Compare commits

..

1 Commits

Author SHA1 Message Date
Shelley Vohr
1b11c304ba fix: dispatch ALT+SPACE keydown to renderer on Windows
Chromium's DesktopWindowTreeHostWin::HandleKeyEvent() intentionally
drops ALT+SPACE keydown events so that the subsequent WM_SYSCHAR
message can open the system menu. This means that when an Electron app
listens for 'system-context-menu' and calls preventDefault(), the
ALT+SPACE keydown never reaches the renderer and 'before-input-event'
never fires.

Override HandleKeyEvent() to intercept ALT+SPACE keydown and dispatch
it via SendEventToSink() so it flows through the normal input pipeline
to the renderer. The subsequent WM_SYSCHAR is still handled by
HandleIMEMessage() to emit 'system-context-menu', preserving existing
behavior for apps that don't prevent default.
2026-03-04 16:09:36 +01:00
576 changed files with 6616 additions and 12487 deletions

1
.github/CODEOWNERS vendored
View File

@@ -19,7 +19,6 @@ DEPS @electron/wg-upgrades
/lib/renderer/security-warnings.ts @electron/wg-security
# Infra WG
/.claude/ @electron/wg-infra
/.github/actions/ @electron/wg-infra
/.github/workflows/*-publish.yml @electron/wg-infra
/.github/workflows/build.yml @electron/wg-infra

View File

@@ -5,8 +5,6 @@ Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/electron/electron/blob/main/CONTRIBUTING.md
NOTE: PRS submitted without this template will be automatically closed.
-->
#### Checklist

View File

@@ -47,16 +47,6 @@ runs:
- name: Add Clang problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
- name: Download previous object checksums
shell: bash
if: ${{ (github.event_name == 'push' || github.event_name == 'pull_request') && inputs.is-asan != 'true' }}
env:
GITHUB_TOKEN: ${{ github.token }}
ARTIFACT_NAME: object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json
SEARCH_BRANCH: ${{ case(github.event_name == 'push', github.ref_name, github.event.pull_request.base.ref) }}
REPO: ${{ github.repository }}
OUTPUT_PATH: src/previous-object-checksums.json
run: node src/electron/.github/actions/build-electron/download-previous-object-checksums.mjs
- name: Build Electron ${{ inputs.step-suffix }}
if: ${{ inputs.target-platform != 'win' }}
shell: bash
@@ -82,17 +72,12 @@ runs:
cp out/Default/.ninja_log out/electron_ninja_log
node electron/script/check-symlinks.js
# Build stats and object checksums
BUILD_STATS_ARGS="out/Default/siso.INFO --out-dir out/Default --output-object-checksums object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json"
if [ -f previous-object-checksums.json ]; then
BUILD_STATS_ARGS="$BUILD_STATS_ARGS --input-object-checksums previous-object-checksums.json"
fi
if ! [ -z "$DD_API_KEY" ]; then
BUILD_STATS_ARGS="$BUILD_STATS_ARGS --upload-stats"
# Upload build stats to Datadog
if ! [ -z $DD_API_KEY ]; then
npx node electron/script/build-stats.mjs out/Default/siso.INFO --upload-stats || true
else
echo "Skipping build-stats.mjs upload because DD_API_KEY is not set"
fi
node electron/script/build-stats.mjs $BUILD_STATS_ARGS || true
- name: Build Electron (Windows) ${{ inputs.step-suffix }}
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
@@ -110,21 +95,16 @@ runs:
Copy-Item out\Default\.ninja_log out\electron_ninja_log
node electron\script\check-symlinks.js
# Build stats and object checksums
$statsArgs = @("out\Default\siso.exe.INFO", "--out-dir", "out\Default", "--output-object-checksums", "object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json")
if (Test-Path previous-object-checksums.json) {
$statsArgs += @("--input-object-checksums", "previous-object-checksums.json")
}
# Upload build stats to Datadog
if ($env:DD_API_KEY) {
$statsArgs += "--upload-stats"
try {
npx node electron\script\build-stats.mjs out\Default\siso.exe.INFO --upload-stats ; $LASTEXITCODE = 0
} catch {
Write-Host "Build stats upload failed, continuing..."
}
} else {
Write-Host "Skipping build-stats.mjs upload because DD_API_KEY is not set"
}
try {
& node electron\script\build-stats.mjs @statsArgs ; $LASTEXITCODE = 0
} catch {
Write-Host "Build stats failed, continuing..."
}
- name: Verify dist.zip ${{ inputs.step-suffix }}
shell: bash
run: |
@@ -148,9 +128,6 @@ runs:
fi
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--reorder-builtins/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--warn-about-builtin-profile-data/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--abort-on-bad-builtin-profile-data/d' out/Default/mksnapshot_args
if [ "${{ inputs.target-platform }}" = "win" ]; then
cd out/Default
@@ -297,25 +274,18 @@ runs:
run: ./src/electron/script/actions/move-artifacts.sh
- name: Upload Generated Artifacts ${{ inputs.step-suffix }}
if: always() && !cancelled()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
- name: Upload Src Artifacts ${{ inputs.step-suffix }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: src_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
- name: Upload Out Gen Artifacts ${{ inputs.step-suffix }}
if: ${{ inputs.upload-out-gen-artifacts == 'true' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: out_gen_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src/out/Default/gen
- name: Upload Object Checksums ${{ inputs.step-suffix }}
if: ${{ always() && !cancelled() && inputs.is-asan != 'true' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: object_checksums_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
path: ./src/object-checksums.${{ inputs.artifact-platform }}_${{ inputs.target-arch }}.json
archive: false

View File

@@ -1,82 +0,0 @@
import { Octokit } from '@octokit/rest';
import { writeFileSync } from 'node:fs';
const token = process.env.GITHUB_TOKEN;
const repo = process.env.REPO;
const artifactName = process.env.ARTIFACT_NAME;
const branch = process.env.SEARCH_BRANCH;
const outputPath = process.env.OUTPUT_PATH;
const required = { GITHUB_TOKEN: token, REPO: repo, ARTIFACT_NAME: artifactName, SEARCH_BRANCH: branch, OUTPUT_PATH: outputPath };
const missing = Object.entries(required).filter(([, v]) => !v).map(([k]) => k);
if (missing.length > 0) {
console.error(`Missing required environment variables: ${missing.join(', ')}`);
process.exit(1);
}
const [owner, repoName] = repo.split('/');
const octokit = new Octokit({ auth: token });
async function main () {
console.log(`Searching for artifact '${artifactName}' on branch '${branch}'...`);
// Resolve the "Build" workflow name to an ID, mirroring how `gh run list --workflow` works
// under the hood (it uses /repos/{owner}/{repo}/actions/workflows/{id}/runs).
const { data: workflows } = await octokit.actions.listRepoWorkflows({ owner, repo: repoName });
const buildWorkflow = workflows.workflows.find((w) => w.name === 'Build');
if (!buildWorkflow) {
console.log('Could not find "Build" workflow, continuing without previous checksums');
return;
}
const { data: runs } = await octokit.actions.listWorkflowRuns({
owner,
repo: repoName,
workflow_id: buildWorkflow.id,
branch,
status: 'completed',
event: 'push',
per_page: 20,
exclude_pull_requests: true
});
for (const run of runs.workflow_runs) {
const { data: artifacts } = await octokit.actions.listWorkflowRunArtifacts({
owner,
repo: repoName,
run_id: run.id,
name: artifactName
});
if (artifacts.artifacts.length > 0) {
const artifact = artifacts.artifacts[0];
console.log(`Found artifact in run ${run.id} (artifact ID: ${artifact.id}), downloading...`);
// Non-archived artifacts are still downloaded from the /zip endpoint
const response = await octokit.actions.downloadArtifact({
owner,
repo: repoName,
artifact_id: artifact.id,
archive_format: 'zip'
});
if (response.headers['content-type'] !== 'application/json') {
console.error(`Unexpected content type for artifact download: ${response.headers['content-type']}`);
console.error('Expected application/json, continuing without previous checksums');
return;
}
writeFileSync(outputPath, JSON.stringify(response.data));
console.log('Downloaded previous object checksums successfully');
return;
}
}
console.log(`No previous object checksums found in last ${runs.workflow_runs.length} runs, continuing without them`);
}
main().catch((err) => {
console.error('Failed to download previous object checksums, continuing without them:', err.message);
process.exit(0);
});

View File

@@ -43,7 +43,7 @@ runs:
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}&getAccountName=true" > sas-token
- name: Save SAS Key
if: ${{ inputs.generate-sas-token == 'true' }}
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: sas-token
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}

View File

@@ -22,50 +22,30 @@ runs:
steps:
- name: Delete wrong ${{ inputs.dependency }}
shell: bash
env:
CIPD_ROOT_PREFIX: ${{ inputs.cipd-root-prefix-path }}
INSTALLATION_DIR: ${{ inputs.installation-dir }}
run : |
rm -rf "${CIPD_ROOT_PREFIX}${INSTALLATION_DIR}"
rm -rf ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }}
- name: Create ensure file for ${{ inputs.dependency }}
if: ${{ inputs.dependency-version == '' }}
shell: bash
env:
PACKAGE: ${{ inputs.package }}
DEPS_FILE: ${{ inputs.deps-file }}
INSTALLATION_DIR: ${{ inputs.installation-dir }}
DEPENDENCY: ${{ inputs.dependency }}
run: |
echo "$PACKAGE" $(e d gclient getdep --deps-file="$DEPS_FILE" -r "${INSTALLATION_DIR}:${PACKAGE}") > "${DEPENDENCY}_ensure_file"
cat "${DEPENDENCY}_ensure_file"
echo '${{ inputs.package }}' `e d gclient getdep --deps-file=${{ inputs.deps-file }} -r '${{ inputs.installation-dir }}:${{ inputs.package }}'` > ${{ inputs.dependency }}_ensure_file
cat ${{ inputs.dependency }}_ensure_file
- name: Create ensure file for ${{ inputs.dependency }} from dependency-version
if: ${{ inputs.dependency-version != '' }}
shell: bash
env:
PACKAGE: ${{ inputs.package }}
DEPENDENCY_VERSION: ${{ inputs.dependency-version }}
DEPENDENCY: ${{ inputs.dependency }}
run: |
echo "$PACKAGE $DEPENDENCY_VERSION" > "${DEPENDENCY}_ensure_file"
cat "${DEPENDENCY}_ensure_file"
echo '${{ inputs.package }} ${{ inputs.dependency-version }}' > ${{ inputs.dependency }}_ensure_file
cat ${{ inputs.dependency }}_ensure_file
- name: CIPD installation of ${{ inputs.dependency }} (macOS)
if: ${{ inputs.target-platform != 'win' }}
shell: bash
env:
CIPD_ROOT_PREFIX: ${{ inputs.cipd-root-prefix-path }}
INSTALLATION_DIR: ${{ inputs.installation-dir }}
DEPENDENCY: ${{ inputs.dependency }}
run: |
echo "ensuring $DEPENDENCY"
e d cipd ensure --root "${CIPD_ROOT_PREFIX}${INSTALLATION_DIR}" -ensure-file "${DEPENDENCY}_ensure_file"
echo "ensuring ${{ inputs.dependency }}"
e d cipd ensure --root ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }} -ensure-file ${{ inputs.dependency }}_ensure_file
- name: CIPD installation of ${{ inputs.dependency }} (Windows)
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
env:
CIPD_ROOT_PREFIX: ${{ inputs.cipd-root-prefix-path }}
INSTALLATION_DIR: ${{ inputs.installation-dir }}
DEPENDENCY: ${{ inputs.dependency }}
run: |
echo "ensuring $env:DEPENDENCY on Windows"
e d cipd ensure --root "$env:CIPD_ROOT_PREFIX$env:INSTALLATION_DIR" -ensure-file "$($env:DEPENDENCY)_ensure_file"
echo "ensuring ${{ inputs.dependency }} on Windows"
e d cipd ensure --root ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }} -ensure-file ${{ inputs.dependency }}_ensure_file

View File

@@ -7,7 +7,7 @@ runs:
shell: bash
id: yarn-cache-dir-path
run: echo "dir=$(node src/electron/script/yarn.js config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}

View File

@@ -8,14 +8,14 @@ runs:
steps:
- name: Obtain SAS Key
continue-on-error: true
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: sas-token
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-1
enableCrossOsArchive: true
- name: Obtain SAS Key
continue-on-error: true
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: sas-token
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
@@ -24,7 +24,7 @@ runs:
# The cache will always exist here as a result of the checkout job
# Either it was uploaded to Azure in the checkout job for this commit
# or it was uploaded in the checkout job for a previous commit.
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
with:
timeout_minutes: 30
max_attempts: 3
@@ -101,7 +101,7 @@ runs:
- name: Move Src Cache (Windows)
if: ${{ inputs.target-platform == 'win' }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
with:
timeout_minutes: 30
max_attempts: 3

View File

@@ -7,7 +7,7 @@ runs:
if: ${{ runner.os != 'Windows' }}
shell: bash
run: |
if [[ -z "$CHROMIUM_GIT_COOKIE" ]]; then
if [[ -z "${{ env.CHROMIUM_GIT_COOKIE }}" ]]; then
echo "CHROMIUM_GIT_COOKIE is not set - cannot authenticate."
exit 0
fi
@@ -18,7 +18,9 @@ runs:
git config --global http.cookiefile ~/.gitcookies
echo "$CHROMIUM_GIT_COOKIE" | tr , \\t >>~/.gitcookies
tr , \\t <<\__END__ >>~/.gitcookies
${{ env.CHROMIUM_GIT_COOKIE }}
__END__
eval 'set -o history' 2>/dev/null || unsetopt HIST_IGNORE_SPACE 2>/dev/null
RESPONSE=$(curl -s -b ~/.gitcookies https://chromium-review.googlesource.com/a/accounts/self)
@@ -40,7 +42,7 @@ runs:
)
git config --global http.cookiefile "%USERPROFILE%\.gitcookies"
powershell -noprofile -nologo -command Write-Output $env:CHROMIUM_GIT_COOKIE_WINDOWS_STRING >>"%USERPROFILE%\.gitcookies"
powershell -noprofile -nologo -command Write-Output "${{ env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}" >>"%USERPROFILE%\.gitcookies"
curl -s -b "%USERPROFILE%\.gitcookies" https://chromium-review.googlesource.com/a/accounts/self > response.txt

View File

@@ -26,7 +26,7 @@ jobs:
# Use dorny/paths-filter instead of the path filter under the on: pull_request: block
# so that the output can be used to conditionally run the apply-patches job, which lets
# the job be marked as a required status check (conditional skip counts as a success).
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
@@ -71,11 +71,3 @@ jobs:
uses: ./src/electron/.github/actions/checkout
with:
target-platform: linux
- name: Upload Patch Conflict Fix
if: ${{ failure() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: update-patches
path: patches/update-patches.patch
if-no-files-found: ignore
archive: false

View File

@@ -17,25 +17,21 @@ jobs:
with:
fetch-depth: 0
- name: Setup Node.js/npm
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
with:
node-version: 24.12.x
- name: Setting Up Dig Site
env:
CLONE_URL: ${{ github.event.pull_request.head.repo.clone_url }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
echo "remote: $CLONE_URL"
echo "sha $HEAD_SHA"
echo "base ref $BASE_REF"
git clone https://github.com/electron/electron.git electron
echo "remote: ${{ github.event.pull_request.head.repo.clone_url }}"
echo "sha ${{ github.event.pull_request.head.sha }}"
echo "base ref ${{ github.event.pull_request.base.ref }}"
git clone https://github.com/electron/electron.git electron
cd electron
mkdir -p artifacts
git remote add fork "$CLONE_URL" && git fetch fork
git checkout "$HEAD_SHA"
git merge-base "origin/$BASE_REF" HEAD > .dig-old
echo "$HEAD_SHA" > .dig-new
git remote add fork ${{ github.event.pull_request.head.repo.clone_url }} && git fetch fork
git checkout ${{ github.event.pull_request.head.sha }}
git merge-base origin/${{ github.event.pull_request.base.ref }} HEAD > .dig-old
echo ${{ github.event.pull_request.head.sha }} > .dig-new
cp .dig-old artifacts
- name: Generating Types for SHA in .dig-new

View File

@@ -17,7 +17,7 @@ jobs:
contents: read
steps:
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 22.17.x
- name: Sparse checkout repository
@@ -86,7 +86,6 @@ jobs:
!message.startsWith("Response status code does not indicate success") &&
!message.startsWith("The hosted runner lost communication with the server") &&
!message.startsWith("Dependabot encountered an error performing the update") &&
!message.startsWith("The action 'Run Electron Tests' has timed out") &&
!/Unable to make request/.test(message) &&
!/The requested URL returned error/.test(message),
)
@@ -155,7 +154,7 @@ jobs:
await core.summary.write();
- name: Send Slack message if errors
if: ${{ always() && steps.audit-errors.outputs.errorsFound && github.ref == 'refs/heads/main' }}
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
payload: |
link: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

View File

@@ -31,46 +31,16 @@ jobs:
else
echo "Not a release branch: $BRANCH_NAME"
fi
- name: Determine Next Unsupported Major Version
id: determine-next-unsupported-major
if: ${{ steps.check-major-version.outputs.MAJOR }}
env:
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
run: |
# Fetch the release schedule
SCHEDULE=$(curl -s https://releases.electronjs.org/schedule.json)
# Get the stableDate for the current major version
STABLE_DATE=$(echo "$SCHEDULE" | jq -r --arg major "${MAJOR}.0.0" '.[] | select(.version == $major) | .stableDate')
if [[ -z "$STABLE_DATE" || "$STABLE_DATE" == "null" ]]; then
echo "Could not find stableDate for version $MAJOR"
exit 1
fi
# Find the oldest version where eolDate >= stableDate of the new major
# This gives us the oldest supported version when the new major goes stable
NEXT_UNSUPPORTED_MAJOR=$(echo "$SCHEDULE" | jq -r --arg stableDate "$STABLE_DATE" '
[.[] | select(.eolDate != null and .eolDate >= $stableDate)] | sort_by(.version | split(".")[0] | tonumber) | first | .version | split(".")[0]
')
if [[ -z "$NEXT_UNSUPPORTED_MAJOR" || "$NEXT_UNSUPPORTED_MAJOR" == "null" ]]; then
echo "Could not determine oldest supported version"
exit 1
fi
echo "SCHEDULE=$SCHEDULE" >> "$GITHUB_OUTPUT"
echo "NEXT_UNSUPPORTED_MAJOR=$NEXT_UNSUPPORTED_MAJOR" >> "$GITHUB_OUTPUT"
- name: New Release Branch Tasks
if: ${{ steps.check-major-version.outputs.MAJOR }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: electron/electron
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
NEXT_UNSUPPORTED_MAJOR: ${{ steps.determine-next-unsupported-major.outputs.NEXT_UNSUPPORTED_MAJOR }}
NUM_SUPPORTED_VERSIONS: 3
run: |
PREVIOUS_MAJOR=$((MAJOR - 1))
UNSUPPORTED_MAJOR=$((NEXT_UNSUPPORTED_MAJOR - 1))
UNSUPPORTED_MAJOR=$((MAJOR - NUM_SUPPORTED_VERSIONS - 1))
# Create new labels
gh label create $MAJOR-x-y --color 8d9ee8 || true
@@ -107,36 +77,12 @@ jobs:
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
id: generate-project-metadata
env:
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
NEXT_UNSUPPORTED_MAJOR: ${{ steps.determine-next-unsupported-major.outputs.NEXT_UNSUPPORTED_MAJOR }}
SCHEDULE: ${{ steps.determine-next-unsupported-major.outputs.SCHEDULE }}
with:
script: |
const schedule = JSON.parse(process.env.SCHEDULE)
const major = parseInt(process.env.MAJOR)
const major = ${{ steps.check-major-version.outputs.MAJOR }}
const nextMajor = major + 1
const prevMajor = major - 1
const { betaDate, stableDate } = schedule.find(v => v.version === `${major}.0.0`)
const betaPrepWeek = new Date(betaDate)
betaPrepWeek.setDate(betaPrepWeek.getDate() - 8)
const betaPrepWeekEnd = new Date(betaPrepWeek)
betaPrepWeekEnd.setDate(betaPrepWeekEnd.getDate() + 4)
const stablePrepWeek = new Date(stableDate)
stablePrepWeek.setDate(stablePrepWeek.getDate() - 8)
const stablePrepWeekEnd = new Date(stablePrepWeek)
stablePrepWeekEnd.setDate(stablePrepWeekEnd.getDate() + 4)
const stableWeek = new Date(stableDate)
stableWeek.setDate(stableWeek.getDate() - 1)
const nextAlphaDate = new Date(stableDate)
nextAlphaDate.setDate(nextAlphaDate.getDate() + 2)
core.setOutput("major", major)
core.setOutput("next-major", nextMajor)
core.setOutput("prev-major", prevMajor)
@@ -145,19 +91,10 @@ jobs:
major,
"next-major": nextMajor,
"prev-major": prevMajor,
"ending-support-major": parseInt(process.env.NEXT_UNSUPPORTED_MAJOR),
"beta-date": betaDate,
"beta-prep-week": betaPrepWeek.toISOString().split('T')[0],
"beta-prep-week-end": betaPrepWeekEnd.toISOString().split('T')[0],
"stable-week": stableWeek.toISOString().split('T')[0],
"stable-prep-week": stablePrepWeek.toISOString().split('T')[0],
"stable-prep-week-end": stablePrepWeekEnd.toISOString().split('T')[0],
"stable-date": stableDate,
"next-alpha-date": nextAlphaDate.toISOString().split('T')[0],
}))
- name: Create Release Project Board
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: dsanders11/project-actions/copy-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/copy-project@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
id: create-release-board
with:
drafts: true
@@ -177,7 +114,7 @@ jobs:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Find Previous Release Project Board
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: dsanders11/project-actions/find-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/find-project@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
id: find-prev-release-board
with:
fail-if-project-not-found: false
@@ -185,7 +122,7 @@ jobs:
token: ${{ steps.generate-token.outputs.token }}
- name: Close Previous Release Project Board
if: ${{ steps.find-prev-release-board.outputs.number }}
uses: dsanders11/project-actions/close-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/close-project@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
project-number: ${{ steps.find-prev-release-board.outputs.number }}
token: ${{ steps.generate-token.outputs.token }}

View File

@@ -61,7 +61,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
@@ -365,18 +365,6 @@ jobs:
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
test-linux-arm64-64k:
uses: ./.github/workflows/pipeline-segment-electron-test-64k.yml
permissions:
contents: read
issues: read
pull-requests: read
needs: [checkout-linux, linux-arm64]
with:
test-runs-on: ubuntu-22.04-arm
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
secrets: inherit
windows-x64:
permissions:
@@ -446,30 +434,3 @@ jobs:
- name: GitHub Actions Jobs Done
run: |
echo "All GitHub Actions Jobs are done"
check-signed-commits:
name: Check signed commits in green PR
needs: gha-done
if: ${{ contains(github.event.pull_request.labels.*.name, 'needs-signed-commits')}}
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: write
steps:
- name: Check signed commits in PR
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1
with:
comment: |
⚠️ This PR contains unsigned commits. This repository enforces [commit signatures](https://docs.github.com/en/authentication/managing-commit-signature-verification)
for all incoming PRs. To get your PR merged, please sign those commits
(`git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}`) and force push them to this branch
(`git push --force-with-lease`)
For more information on signing commits, see GitHub's documentation on [Telling Git about your signing key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key).
- name: Remove needs-signed-commits label
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh pr edit $PR_URL --remove-label needs-signed-commits

View File

@@ -7,7 +7,6 @@ name: Clean Source Cache
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
permissions: {}
@@ -17,8 +16,6 @@ jobs:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
env:
DD_API_KEY: ${{ secrets.DD_API_KEY }}
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root
@@ -26,130 +23,12 @@ jobs:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /mnt/win-cache:/mnt/win-cache
steps:
- name: Get Disk Space Before Cleanup
id: disk-before
shell: bash
run: |
echo "Disk space before cleanup:"
df -h /mnt/cross-instance-cache
df -h /mnt/win-cache
CROSS_FREE_BEFORE=$(df -k /mnt/cross-instance-cache | tail -1 | awk '{print $4}')
CROSS_TOTAL=$(df -k /mnt/cross-instance-cache | tail -1 | awk '{print $2}')
WIN_FREE_BEFORE=$(df -k /mnt/win-cache | tail -1 | awk '{print $4}')
WIN_TOTAL=$(df -k /mnt/win-cache | tail -1 | awk '{print $2}')
echo "cross_free_kb=$CROSS_FREE_BEFORE" >> $GITHUB_OUTPUT
echo "cross_total_kb=$CROSS_TOTAL" >> $GITHUB_OUTPUT
echo "win_free_kb=$WIN_FREE_BEFORE" >> $GITHUB_OUTPUT
echo "win_total_kb=$WIN_TOTAL" >> $GITHUB_OUTPUT
- name: Cleanup Source Cache
shell: bash
run: |
df -h /mnt/cross-instance-cache
find /mnt/cross-instance-cache -type f -mtime +15 -delete
find /mnt/win-cache -type f -mtime +15 -delete
- name: Get Disk Space After Cleanup
id: disk-after
shell: bash
run: |
echo "Disk space after cleanup:"
df -h /mnt/cross-instance-cache
df -h /mnt/win-cache
CROSS_FREE_AFTER=$(df -k /mnt/cross-instance-cache | tail -1 | awk '{print $4}')
WIN_FREE_AFTER=$(df -k /mnt/win-cache | tail -1 | awk '{print $4}')
echo "cross_free_kb=$CROSS_FREE_AFTER" >> $GITHUB_OUTPUT
echo "win_free_kb=$WIN_FREE_AFTER" >> $GITHUB_OUTPUT
- name: Log Disk Space to Datadog
if: ${{ env.DD_API_KEY != '' }}
shell: bash
env:
CROSS_FREE_BEFORE: ${{ steps.disk-before.outputs.cross_free_kb }}
CROSS_FREE_AFTER: ${{ steps.disk-after.outputs.cross_free_kb }}
CROSS_TOTAL: ${{ steps.disk-before.outputs.cross_total_kb }}
WIN_FREE_BEFORE: ${{ steps.disk-before.outputs.win_free_kb }}
WIN_FREE_AFTER: ${{ steps.disk-after.outputs.win_free_kb }}
WIN_TOTAL: ${{ steps.disk-before.outputs.win_total_kb }}
run: |
TIMESTAMP=$(date +%s)
CROSS_FREE_BEFORE_GB=$(awk "BEGIN {printf \"%.2f\", $CROSS_FREE_BEFORE / 1024 / 1024}")
CROSS_FREE_AFTER_GB=$(awk "BEGIN {printf \"%.2f\", $CROSS_FREE_AFTER / 1024 / 1024}")
CROSS_FREED_GB=$(awk "BEGIN {printf \"%.2f\", ($CROSS_FREE_AFTER - $CROSS_FREE_BEFORE) / 1024 / 1024}")
CROSS_TOTAL_GB=$(awk "BEGIN {printf \"%.2f\", $CROSS_TOTAL / 1024 / 1024}")
WIN_FREE_BEFORE_GB=$(awk "BEGIN {printf \"%.2f\", $WIN_FREE_BEFORE / 1024 / 1024}")
WIN_FREE_AFTER_GB=$(awk "BEGIN {printf \"%.2f\", $WIN_FREE_AFTER / 1024 / 1024}")
WIN_FREED_GB=$(awk "BEGIN {printf \"%.2f\", ($WIN_FREE_AFTER - $WIN_FREE_BEFORE) / 1024 / 1024}")
WIN_TOTAL_GB=$(awk "BEGIN {printf \"%.2f\", $WIN_TOTAL / 1024 / 1024}")
echo "cross-instance-cache: free before=${CROSS_FREE_BEFORE_GB}GB, after=${CROSS_FREE_AFTER_GB}GB, freed=${CROSS_FREED_GB}GB, total=${CROSS_TOTAL_GB}GB"
echo "win-cache: free before=${WIN_FREE_BEFORE_GB}GB, after=${WIN_FREE_AFTER_GB}GB, freed=${WIN_FREED_GB}GB, total=${WIN_TOTAL_GB}GB"
curl -s -X POST "https://api.datadoghq.com/api/v2/series" \
-H "Content-Type: application/json" \
-H "DD-API-KEY: ${DD_API_KEY}" \
-d @- << EOF
{
"series": [
{
"metric": "electron.src_cache.disk.free_space_before_cleanup_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${CROSS_FREE_BEFORE_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:cross-instance-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.free_space_after_cleanup_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${CROSS_FREE_AFTER_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:cross-instance-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.space_freed_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${CROSS_FREED_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:cross-instance-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.total_space_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${CROSS_TOTAL_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:cross-instance-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.free_space_before_cleanup_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${WIN_FREE_BEFORE_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:win-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.free_space_after_cleanup_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${WIN_FREE_AFTER_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:win-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.space_freed_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${WIN_FREED_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:win-cache", "platform:linux"]
},
{
"metric": "electron.src_cache.disk.total_space_gb",
"points": [{"timestamp": ${TIMESTAMP}, "value": ${WIN_TOTAL_GB}}],
"type": 3,
"unit": "gigabyte",
"tags": ["volume:win-cache", "platform:linux"]
}
]
}
EOF
echo "Disk space metrics logged to Datadog"
find /mnt/win-cache -type f -mtime +15 -delete
df -h /mnt/win-cache

View File

@@ -33,7 +33,7 @@ jobs:
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
gh issue edit $ISSUE_URL --remove-label 'blocked/need-repro','blocked/need-info ❌'
pr-reviewer-requested:
name: Maintainer requested reviewer on PR
if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '/request-review') && github.event.comment.user.type != 'Bot' }}

View File

@@ -21,7 +21,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90
@@ -42,7 +42,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90
@@ -61,10 +61,9 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: electron/electron
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
set -eo pipefail
COMMENT_COUNT=$(gh issue view "$ISSUE_NUMBER" --comments --json comments | jq '[ .comments[] | select(.author.login == "electron-issue-triage" or .authorAssociation == "OWNER" or .authorAssociation == "MEMBER") | select(.body | startswith("<!-- blocked/need-repro -->")) ] | length')
COMMENT_COUNT=$(gh issue view ${{ github.event.issue.number }} --comments --json comments | jq '[ .comments[] | select(.author.login == "electron-issue-triage" or .authorAssociation == "OWNER" or .authorAssociation == "MEMBER") | select(.body | startswith("<!-- blocked/need-repro -->")) ] | length')
if [[ $COMMENT_COUNT -eq 0 ]]; then
echo "SHOULD_COMMENT=1" >> "$GITHUB_OUTPUT"
fi
@@ -76,7 +75,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- name: Create comment
if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }}
uses: actions-cool/issues-helper@200c78641dbf33838311e5a1e0c31bbdb92d7cf0 # v3.8.0
uses: actions-cool/issues-helper@71b62d7da76e59ff7b193904feb6e77d4dbb2777 # v3.7.6
with:
actions: 'create-comment'
token: ${{ steps.generate-token.outputs.token }}

View File

@@ -20,7 +20,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Add to Issue Triage
uses: dsanders11/project-actions/add-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/add-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
field: Reporter
field-value: ${{ github.event.issue.user.login }}
@@ -146,7 +146,7 @@ jobs:
}
- name: Create unsupported major comment
if: ${{ steps.add-labels.outputs.unsupportedMajor }}
uses: actions-cool/issues-helper@200c78641dbf33838311e5a1e0c31bbdb92d7cf0 # v3.8.0
uses: actions-cool/issues-helper@71b62d7da76e59ff7b193904feb6e77d4dbb2777 # v3.7.6
with:
actions: 'create-comment'
token: ${{ steps.generate-token.outputs.token }}

View File

@@ -20,7 +20,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Remove from issue triage
uses: dsanders11/project-actions/delete-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/delete-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90

View File

@@ -16,11 +16,9 @@ jobs:
steps:
- name: Check for any blocked labels
id: check-for-blocked-labels
env:
LABELS_JSON: ${{ toJSON(github.event.issue.labels.*.name) }}
run: |
set -eo pipefail
BLOCKED_LABEL_COUNT=$(echo "$LABELS_JSON" | jq '[ .[] | select(startswith("blocked/")) ] | length')
BLOCKED_LABEL_COUNT=$(echo '${{ toJSON(github.event.issue.labels.*.name) }}' | jq '[ .[] | select(startswith("blocked/")) ] | length')
if [[ $BLOCKED_LABEL_COUNT -eq 0 ]]; then
echo "NOT_BLOCKED=1" >> "$GITHUB_OUTPUT"
fi
@@ -33,7 +31,7 @@ jobs:
org: electron
- name: Set status
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90

View File

@@ -10,10 +10,6 @@ on:
- '.yarn/**'
- '.yarnrc.yml'
# SECURITY: This workflow uses pull_request_target and has access to secrets.
# Do NOT checkout or run code from the PR head. All code execution must use
# the base branch only. Adding a ref to PR head would expose secrets to
# untrusted code.
permissions: {}
jobs:
@@ -49,23 +45,5 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
run: |
cat <<'REVIEW_EOF' | sed "s/%AUTHOR%/$PR_AUTHOR/g" | gh pr review $PR_URL -r --body-file=-
<!-- disallowed-non-maintainer-change -->
Hello @%AUTHOR%! It looks like this pull request touches one of our dependency or CI files, and per [our contribution policy](https://github.com/electron/electron/blob/main/CONTRIBUTING.md#dependencies-upgrades-policy) we do not accept these types of changes in PRs.
To move this PR forward, please:
1. Revert the dependency/CI file changes from your branch. (e.g. `yarn.lock`, `.yarn/`, `.yarnrc.yml`, `.github/workflows/`, `.github/actions/`)
2. Ensure your branch [allows maintainer commits](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so a maintainer can push the necessary dependency changes on your behalf.
3. Leave a comment letting reviewers know the dependency change is still needed.
<details>
<summary>For maintainers</summary>
To land this PR, push a verified commit to the contributor's branch with the required dependency/CI changes, then dismiss this review.
</details>
REVIEW_EOF
printf "<!-- disallowed-non-maintainer-change -->\n\nHello @${{ github.event.pull_request.user.login }}! It looks like this pull request touches one of our dependency or CI files, and per [our contribution policy](https://github.com/electron/electron/blob/main/CONTRIBUTING.md#dependencies-upgrades-policy) we do not accept these types of changes in PRs." | gh pr review $PR_URL -r --body-file=-

View File

@@ -46,10 +46,6 @@ jobs:
shell: bash
run: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
if [[ ! "$chromium_revision" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "::error::Invalid chromium_revision: $chromium_revision"
exit 1
fi
gn_version="$(curl -sL -b ~/.gitcookies "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . <<-CIPD
@@ -64,10 +60,6 @@ jobs:
shell: bash
run: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
if [[ ! "$chromium_revision" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "::error::Invalid chromium_revision: $chromium_revision"
exit 1
fi
mkdir -p src/buildtools
curl -sL -b ~/.gitcookies "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS

View File

@@ -124,7 +124,7 @@ jobs:
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
with:
node-version: 22.21.x
cache: yarn

View File

@@ -126,7 +126,7 @@ jobs:
cd src/electron
git pack-refs
- name: Download Out Gen Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: out_gen_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src/out/${{ env.ELECTRON_OUT_DIR }}/gen

View File

@@ -132,7 +132,7 @@ jobs:
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
with:
node-version: 22.21.x
cache: yarn

View File

@@ -1,67 +0,0 @@
name: Pipeline Segment - Electron Test on Linux ARM64 64k
on:
workflow_call:
inputs:
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
test-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
concurrency:
group: electron-test-linux-64k-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
permissions: {}
env:
ELECTRON_OUT_DIR: Default
jobs:
test-linux-arm64-64k:
env:
BUILD_TYPE: linux
TARGET_ARCH: arm64
defaults:
run:
shell: bash
runs-on: ${{ inputs.test-runs-on }}
permissions:
contents: read
issues: read
pull-requests: read
steps:
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Download Generated Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
with:
name: generated_artifacts_linux_arm64
path: ./generated_artifacts_linux_arm64
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist
run: |
cd src/out/Default
unzip -:o dist.zip
- name: Run Electron Tests in QEMU 64k Container
shell: bash
env:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
DISPLAY: ':99.0'
run: |
container=$(echo '${{ inputs.test-container }}' | jq -r '.image')
src/electron/script/run-qemu-64k.sh --container $container --testfiles "`pwd`/src"

View File

@@ -48,8 +48,6 @@ env:
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
SENTRYCLI_SKIP_DOWNLOAD: 1
jobs:
test:
@@ -79,7 +77,7 @@ jobs:
cp $(which node) /mnt/runner-externals/node24/bin/
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'win' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
with:
node-version: 22.21.x
- name: Add TCC permissions on macOS
@@ -175,12 +173,12 @@ jobs:
echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV
echo "IS_ASAN=true" >> $GITHUB_ENV
- name: Download Generated Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Download Src Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: src_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
@@ -198,25 +196,15 @@ jobs:
run: |
cd src/out/Default
unzip -:o dist.zip
- name: Import & Trust Self-Signed Codesigning Cert on MacOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
cd src/electron
./script/codesign/generate-identity.sh
# Sign with our self-signed cert so that macOS system integrations
# (UNNotifications, dock bounce, etc.) work in tests on both architectures.
# Autoupdater tests sign their own fixture copies via signApp().
- name: Sign Electron.app for macOS tests
if: ${{ inputs.target-platform == 'macos' }}
run: |
identity=$(src/electron/script/codesign/get-trusted-identity.sh)
if [ -n "$identity" ]; then
codesign -s "$identity" --deep --force src/out/Default/Electron.app
fi
#- name: Import & Trust Self-Signed Codesigning Cert on MacOS
# if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
# run: |
# sudo security authorizationdb write com.apple.trust-settings.admin allow
# cd src/electron
# ./script/codesign/generate-identity.sh
- name: Run Electron Tests
shell: bash
timeout-minutes: 60
env:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
@@ -286,19 +274,6 @@ jobs:
fi
fi
- name: Take screenshot on timeout or cancellation
if: ${{ inputs.target-platform != 'linux' && (cancelled() || failure()) }}
shell: bash
run: |
screenshot_dir="src/electron/spec/artifacts"
mkdir -p "$screenshot_dir"
screenshot_file="$screenshot_dir/screenshot-timeout-$(date +%Y%m%d%H%M%S).png"
if [ "${{ inputs.target-platform }}" = "macos" ]; then
screencapture -x "$screenshot_file" || true
elif [ "${{ inputs.target-platform }}" = "win" ]; then
powershell -command "Add-Type -AssemblyName System.Windows.Forms; \$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; \$bitmap = New-Object System.Drawing.Bitmap(\$screen.Width, \$screen.Height); \$graphics = [System.Drawing.Graphics]::FromImage(\$bitmap); \$graphics.CopyFromScreen(\$screen.Location, [System.Drawing.Point]::Empty, \$screen.Size); \$bitmap.Save('$screenshot_file')" || true
fi
- name: Upload Test results to Datadog
env:
DD_ENV: ci
@@ -314,8 +289,8 @@ jobs:
fi
if: always() && !cancelled()
- name: Upload Test Artifacts
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
if: always() && !cancelled()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
with:
name: ${{ inputs.target-platform == 'linux' && format('test_artifacts_{0}_{1}_{2}', env.ARTIFACT_KEY, inputs.display-server, matrix.shard) || format('test_artifacts_{0}_{1}', env.ARTIFACT_KEY, matrix.shard) }}
path: src/electron/spec/artifacts

View File

@@ -36,8 +36,6 @@ env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
# @sentry/cli is only needed by release upload-symbols.py; skip the ~17MB CDN download on test jobs
SENTRYCLI_SKIP_DOWNLOAD: 1
jobs:
node-tests:
@@ -67,12 +65,12 @@ jobs:
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
- name: Download Generated Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
@@ -123,12 +121,12 @@ jobs:
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
- name: Download Generated Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}

View File

@@ -1,58 +0,0 @@
name: PR Template Check
on:
pull_request_target:
types: [opened, ready_for_review]
# SECURITY: This workflow uses pull_request_target and has access to secrets.
# Do NOT checkout or run code from the PR head. All code execution must use
# the base branch only. Adding a ref to PR head would expose secrets to
# untrusted code.
permissions: {}
jobs:
check-pr-template:
if: ${{ github.event.pull_request.head.repo.fork && !github.event.pull_request.draft && !startsWith(github.head_ref, 'roller/') }}
name: Check PR Template
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
sparse-checkout: .github/PULL_REQUEST_TEMPLATE.md
sparse-checkout-cone-mode: false
- name: Check for required sections
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const fs = require('fs');
const template = fs.readFileSync('.github/PULL_REQUEST_TEMPLATE.md', 'utf8');
const requiredSections = [...template.matchAll(/^(#{1,4} .+)$/gm)].map(
(m) => m[1],
);
if (requiredSections.length === 0) {
console.log('No heading sections found in PR template');
return;
}
const body = context.payload.pull_request.body || '';
const missingSections = requiredSections.filter(
(section) => !body.includes(section),
);
if (missingSections.length > 0) {
const list = missingSections.map((s) => `- \`${s}\``).join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `This PR was automatically closed because the PR template was not properly filled out. The following required sections are missing:\n\n${list}\n\nPlease update your PR description to include all required sections and reopen the PR.`,
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
state: 'closed',
});
}

View File

@@ -1,44 +0,0 @@
name: PR Triage Automation
on:
pull_request_target:
types: [synchronize, review_requested]
issue_comment:
types: [created]
# SECURITY: This workflow uses pull_request_target and has access to secrets.
# Do NOT checkout or run code from the PR head. All code execution must use
# the base branch only. Adding a ref to PR head would expose secrets to
# untrusted code.
permissions: {}
jobs:
set-needs-review:
name: Set status to Needs Review
if: >-
(github.event_name == 'pull_request_target'
&& github.event.pull_request.draft != true
&& !contains(github.event.pull_request.labels.*.name, 'wip ⚒')
&& (github.event.action == 'synchronize' || github.event.action == 'review_requested'))
|| (github.event_name == 'issue_comment'
&& github.event.issue.pull_request
&& !contains(github.event.issue.labels.*.name, 'wip ⚒')
&& github.event.comment.user.login == github.event.issue.user.login)
runs-on: ubuntu-slim
permissions:
contents: read
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
id: generate-token
with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Set status to Needs Review
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 118
field: Status
field-value: 🌀 Needs Review
fail-if-item-not-found: false

View File

@@ -4,10 +4,6 @@ on:
pull_request_target:
types: [labeled]
# SECURITY: This workflow uses pull_request_target and has access to secrets.
# Do NOT checkout or run code from the PR head. All code execution must use
# the base branch only. Adding a ref to PR head would expose secrets to
# untrusted code.
permissions: {}
jobs:
@@ -18,7 +14,7 @@ jobs:
permissions: {}
steps:
- name: Trigger Slack workflow
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
@@ -42,7 +38,7 @@ jobs:
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 94
@@ -60,7 +56,7 @@ jobs:
with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- name: Create comment
uses: actions-cool/issues-helper@200c78641dbf33838311e5a1e0c31bbdb92d7cf0 # v3.8.0
uses: actions-cool/issues-helper@71b62d7da76e59ff7b193904feb6e77d4dbb2777 # v3.7.6
with:
actions: 'create-comment'
token: ${{ steps.generate-token.outputs.token }}
@@ -72,7 +68,7 @@ jobs:
Hello @${{ github.event.pull_request.user.login }}. Due to the high amount of AI spam PRs we receive, if a PR is detected to be majority AI-generated without disclosure and untested, we will automatically close the PR.
We welcome the use of AI tools, as long as the PR meets our quality standards and has clearly been built and tested. If you believe your PR was closed in error, we welcome you to resubmit. However, please read our [CONTRIBUTING.md](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) and [AI Tool Policy](https://github.com/electron/governance/blob/main/policy/ai.md) carefully before reopening. Thanks for your contribution.
We welcome the use of AI tools, as long as the PR meets our quality standards and has clearly been built and tested. If you believe your PR was closed in error, we welcome you to resubmit. However, please read our [CONTRIBUTING.md](http://contributing.md/) carefully before reopening. Thanks for your contribution.
- name: Close the pull request
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}

View File

@@ -1,39 +0,0 @@
name: Pull Request Opened/Synchronized
on:
pull_request_target:
types: [opened, synchronize]
# SECURITY: This workflow uses pull_request_target and has access to secrets.
# Do NOT checkout or run code from the PR head. All code execution must use
# the base branch only. Adding a ref to PR head would expose secrets to
# untrusted code.
permissions: {}
jobs:
check-signed-commits:
name: Check signed commits in PR
if: ${{ !contains(github.event.pull_request.labels.*.name, 'needs-signed-commits')}}
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: write
steps:
- name: Check signed commits in PR
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1
with:
comment: |
⚠️ This PR contains unsigned commits. This repository enforces [commit signatures](https://docs.github.com/en/authentication/managing-commit-signature-verification)
for all incoming PRs. To get your PR merged, please sign those commits
(`git rebase --exec 'git commit -S --amend --no-edit -n' @{upstream}`) and force push them to this branch
(`git push --force-with-lease`)
For more information on signing commits, see GitHub's documentation on [Telling Git about your signing key](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key).
- name: Add needs-signed-commits label
if: ${{ failure() }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh pr edit $PR_URL --add-label needs-signed-commits

View File

@@ -51,6 +51,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3.29.5
with:
sarif_file: results.sarif

View File

@@ -29,7 +29,7 @@ jobs:
PROJECT_NUMBER=$(gh project list --owner electron --format json | jq -r '.projects | map(select(.title | test("^[0-9]+-x-y$"))) | max_by(.number) | .number')
echo "PROJECT_NUMBER=$PROJECT_NUMBER" >> "$GITHUB_OUTPUT"
- name: Update Completed Stable Prep Items
uses: dsanders11/project-actions/completed-by@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/completed-by@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
with:
field: Prep Status
field-value: ✅ Complete

1
.gitignore vendored
View File

@@ -42,7 +42,6 @@ spec/.hash
# Generated native addon files
/spec/fixtures/native-addon/echo/build/
/spec/fixtures/native-addon/dialog-helper/build/
# If someone runs tsc this is where stuff will end up
ts-gen

6
.remarkrc Normal file
View File

@@ -0,0 +1,6 @@
{
"plugins": [
["remark-lint-code-block-style", "fenced"],
["remark-lint-fenced-code-flag"]
]
}

View File

@@ -9,8 +9,4 @@ npmMinimalAgeGate: 10080
npmPreapprovedPackages:
- "@electron/*"
httpProxy: "${HTTP_PROXY:-}"
httpsProxy: "${HTTPS_PROXY:-}"
yarnPath: .yarn/releases/yarn-4.12.0.cjs

View File

@@ -18,12 +18,12 @@ import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//v8/gni/snapshot_toolchain.gni")
import("build/asar.gni")
import("build/electron_paks.gni")
import("build/esbuild/esbuild.gni")
import("build/extract_symbols.gni")
import("build/js2c_toolchain.gni")
import("build/npm.gni")
import("build/templated_file.gni")
import("build/tsc.gni")
import("build/webpack/webpack.gni")
import("buildflags/buildflags.gni")
import("filenames.auto.gni")
import("filenames.gni")
@@ -162,81 +162,75 @@ npm_action("build_electron_definitions") {
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
}
typescript_check("electron_lib_typecheck") {
deps = [ ":build_electron_definitions" ]
tsconfig = "//electron/tsconfig.electron.json"
sources = auto_filenames.typecheck_sources
}
esbuild_build("electron_browser_bundle") {
webpack_build("electron_browser_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.browser_bundle_deps
config_file = "//electron/build/esbuild/configs/browser.js"
config_file = "//electron/build/webpack/webpack.config.browser.js"
out_file = "$target_gen_dir/js2c/browser_init.js"
}
esbuild_build("electron_renderer_bundle") {
webpack_build("electron_renderer_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.renderer_bundle_deps
config_file = "//electron/build/esbuild/configs/renderer.js"
config_file = "//electron/build/webpack/webpack.config.renderer.js"
out_file = "$target_gen_dir/js2c/renderer_init.js"
}
esbuild_build("electron_worker_bundle") {
webpack_build("electron_worker_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.worker_bundle_deps
config_file = "//electron/build/esbuild/configs/worker.js"
config_file = "//electron/build/webpack/webpack.config.worker.js"
out_file = "$target_gen_dir/js2c/worker_init.js"
}
esbuild_build("electron_sandboxed_renderer_bundle") {
webpack_build("electron_sandboxed_renderer_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.sandbox_bundle_deps
config_file = "//electron/build/esbuild/configs/sandboxed_renderer.js"
config_file = "//electron/build/webpack/webpack.config.sandboxed_renderer.js"
out_file = "$target_gen_dir/js2c/sandbox_bundle.js"
}
esbuild_build("electron_isolated_renderer_bundle") {
webpack_build("electron_isolated_renderer_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.isolated_bundle_deps
config_file = "//electron/build/esbuild/configs/isolated_renderer.js"
config_file = "//electron/build/webpack/webpack.config.isolated_renderer.js"
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
}
esbuild_build("electron_node_bundle") {
webpack_build("electron_node_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.node_bundle_deps
config_file = "//electron/build/esbuild/configs/node.js"
config_file = "//electron/build/webpack/webpack.config.node.js"
out_file = "$target_gen_dir/js2c/node_init.js"
}
esbuild_build("electron_utility_bundle") {
webpack_build("electron_utility_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.utility_bundle_deps
config_file = "//electron/build/esbuild/configs/utility.js"
config_file = "//electron/build/webpack/webpack.config.utility.js"
out_file = "$target_gen_dir/js2c/utility_init.js"
}
esbuild_build("electron_preload_realm_bundle") {
webpack_build("electron_preload_realm_bundle") {
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.preload_realm_bundle_deps
config_file = "//electron/build/esbuild/configs/preload_realm.js"
config_file = "//electron/build/webpack/webpack.config.preload_realm.js"
out_file = "$target_gen_dir/js2c/preload_realm_bundle.js"
}
@@ -244,7 +238,6 @@ action("electron_js2c") {
deps = [
":electron_browser_bundle",
":electron_isolated_renderer_bundle",
":electron_lib_typecheck",
":electron_node_bundle",
":electron_preload_realm_bundle",
":electron_renderer_bundle",
@@ -328,33 +321,12 @@ grit("resources") {
"grit/electron_resources.h",
"electron_resources.pak",
]
if (translate_genders) {
outputs += [
"electron_resources_MASCULINE.pak",
"electron_resources_FEMININE.pak",
"electron_resources_NEUTER.pak",
]
}
foreach(locale, all_chrome_locales) {
outputs += [ "electron_strings_$locale.pak" ]
if (translate_genders) {
outputs += [
"electron_strings_${locale}_MASCULINE.pak",
"electron_strings_${locale}_FEMININE.pak",
"electron_strings_${locale}_NEUTER.pak",
]
}
}
# Mojo manifest overlays are generated.
grit_flags = [
"-E",
"target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
]
if (translate_genders) {
grit_flags += [ "--translate-genders" ]
}
deps = [ ":copy_shell_devtools_discovery_page" ]
@@ -478,7 +450,6 @@ source_set("electron_lib") {
"//chrome:strings",
"//chrome/app:command_ids",
"//chrome/app/resources:platform_locale_settings",
"//chrome/common/notifications",
"//components/autofill/core/common:features",
"//components/certificate_transparency",
"//components/compose:buildflags",
@@ -648,7 +619,6 @@ source_set("electron_lib") {
"SecurityInterface.framework",
"ServiceManagement.framework",
"StoreKit.framework",
"UserNotifications.framework",
]
weak_frameworks = [ "QuickLookThumbnailing.framework" ]
@@ -1024,17 +994,7 @@ if (is_mac) {
}
}
# Electron defines its own plugin helper (using CHILD_EMBEDDER_FIRST + 1) to
# allow loading of unsigned or third-party-signed libraries.
_electron_plugin_helper_params = [
"plugin",
".plugin",
" (Plugin)",
]
electron_mac_helpers =
content_mac_helpers + [ _electron_plugin_helper_params ]
foreach(helper_params, electron_mac_helpers) {
foreach(helper_params, content_mac_helpers) {
_helper_target = helper_params[0]
_helper_bundle_id = helper_params[1]
_helper_suffix = helper_params[2]
@@ -1087,7 +1047,7 @@ if (is_mac) {
":stripped_squirrel_framework",
]
foreach(helper_params, electron_mac_helpers) {
foreach(helper_params, content_mac_helpers) {
sources +=
[ "$root_out_dir/${electron_helper_name}${helper_params[2]}.app" ]
public_deps += [ ":electron_helper_app_${helper_params[0]}" ]
@@ -1191,7 +1151,7 @@ if (is_mac) {
deps = [ ":electron_framework" ]
}
foreach(helper_params, electron_mac_helpers) {
foreach(helper_params, content_mac_helpers) {
_helper_target = helper_params[0]
_helper_bundle_id = helper_params[1]
_helper_suffix = helper_params[2]
@@ -1243,7 +1203,7 @@ if (is_mac) {
deps += [ ":crashpad_handler_syms" ]
}
foreach(helper_params, electron_mac_helpers) {
foreach(helper_params, content_mac_helpers) {
_helper_target = helper_params[0]
deps += [ ":electron_helper_syms_${_helper_target}" ]
}

View File

@@ -127,22 +127,6 @@ patches/{target}/*.patch → [e sync --3] → target repo commits
2. Create a git commit
3. Run `e patches <target>` to export
**Fixing patch conflicts on an existing PR:**
If asked to fix a patch conflict on a branch that already has an open PR, check the PR's failed **Apply Patches** CI run for an `update-patches` artifact before running `e sync` locally. CI has already performed the 3-way merge and exported the resolved patch diff — applying it is much faster than a full local sync.
```bash
# Find the failed Apply Patches run for the PR and download the artifact
gh run list --repo electron/electron --branch <pr-branch> --workflow "Apply Patches" --limit 1
gh run download <run-id> --repo electron/electron --name update-patches
# Apply the CI-generated fix, then push
git am update-patches.patch
git push
```
If no artifact exists (e.g. the 3-way merge itself failed), fall back to `e sync --3` and resolve manually.
## Testing
**Test location:** `spec/` directory
@@ -208,7 +192,6 @@ gh label list --repo electron/electron --search target/ --json name,color --jq '
```bash
npm run lint # Run all linters
npm run lint:clang-format # C++ formatting
npm run lint:api-history # Validate API history YAML blocks in docs
```
## Key Files

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'148.0.7763.0',
'147.0.7713.0',
'node_version':
'v24.14.1',
'v24.14.0',
'nan_version':
'675cefebca42410733da8a454c8d9391fcebfbc2',
'squirrel.mac_version':

View File

@@ -2,7 +2,7 @@ is_electron_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
node_module_version = 146
node_module_version = 145
v8_promise_internal_field_count = 1
v8_embedder_string = "-electron.0"
@@ -51,6 +51,9 @@ is_cfi = false
use_qt5 = false
use_qt6 = false
# Disables the builtins PGO for V8
v8_builtins_profiling_log_file = ""
# https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md
# TODO(vertedinde): hunt down dangling pointers on Linux
enable_dangling_raw_ptr_checks = false

View File

@@ -183,7 +183,6 @@ template("electron_paks") {
"${root_gen_dir}/components/strings/components_locale_settings_",
"${root_gen_dir}/components/strings/components_strings_",
"${root_gen_dir}/device/bluetooth/strings/bluetooth_strings_",
"${root_gen_dir}/electron/electron_strings_",
"${root_gen_dir}/extensions/strings/extensions_strings_",
"${root_gen_dir}/services/strings/services_strings_",
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
@@ -200,7 +199,6 @@ template("electron_paks") {
"//components/strings:components_locale_settings",
"//components/strings:components_strings",
"//device/bluetooth/strings",
"//electron:resources",
"//extensions/strings",
"//services/strings",
"//third_party/blink/public/strings",

View File

@@ -9,189 +9,10 @@
<emit emit_type='prepend'></emit>
</output>
<output filename="electron_resources.pak" type="data_package" />
<output filename="electron_strings_af.pak" type="data_package" lang="af" />
<output filename="electron_strings_am.pak" type="data_package" lang="am" />
<output filename="electron_strings_ar.pak" type="data_package" lang="ar" />
<output filename="electron_strings_as.pak" type="data_package" lang="as" />
<output filename="electron_strings_az.pak" type="data_package" lang="az" />
<output filename="electron_strings_be.pak" type="data_package" lang="be" />
<output filename="electron_strings_bg.pak" type="data_package" lang="bg" />
<output filename="electron_strings_bn.pak" type="data_package" lang="bn" />
<output filename="electron_strings_bs.pak" type="data_package" lang="bs" />
<output filename="electron_strings_ca.pak" type="data_package" lang="ca" />
<output filename="electron_strings_cs.pak" type="data_package" lang="cs" />
<output filename="electron_strings_cy.pak" type="data_package" lang="cy" />
<output filename="electron_strings_da.pak" type="data_package" lang="da" />
<output filename="electron_strings_de.pak" type="data_package" lang="de" />
<output filename="electron_strings_el.pak" type="data_package" lang="el" />
<output filename="electron_strings_en-GB.pak" type="data_package" lang="en-GB" />
<output filename="electron_strings_en-US.pak" type="data_package" lang="en" />
<output filename="electron_strings_es-419.pak" type="data_package" lang="es-419" />
<output filename="electron_strings_es.pak" type="data_package" lang="es" />
<output filename="electron_strings_et.pak" type="data_package" lang="et" />
<output filename="electron_strings_eu.pak" type="data_package" lang="eu" />
<output filename="electron_strings_fa.pak" type="data_package" lang="fa" />
<output filename="electron_strings_fi.pak" type="data_package" lang="fi" />
<output filename="electron_strings_fil.pak" type="data_package" lang="fil" />
<output filename="electron_strings_fr-CA.pak" type="data_package" lang="fr-CA" />
<output filename="electron_strings_fr.pak" type="data_package" lang="fr" />
<output filename="electron_strings_gl.pak" type="data_package" lang="gl" />
<output filename="electron_strings_gu.pak" type="data_package" lang="gu" />
<output filename="electron_strings_hi.pak" type="data_package" lang="hi" />
<output filename="electron_strings_hr.pak" type="data_package" lang="hr" />
<output filename="electron_strings_hu.pak" type="data_package" lang="hu" />
<output filename="electron_strings_hy.pak" type="data_package" lang="hy" />
<output filename="electron_strings_id.pak" type="data_package" lang="id" />
<output filename="electron_strings_is.pak" type="data_package" lang="is" />
<output filename="electron_strings_it.pak" type="data_package" lang="it" />
<output filename="electron_strings_he.pak" type="data_package" lang="he" />
<output filename="electron_strings_ja.pak" type="data_package" lang="ja" />
<output filename="electron_strings_ka.pak" type="data_package" lang="ka" />
<output filename="electron_strings_kk.pak" type="data_package" lang="kk" />
<output filename="electron_strings_km.pak" type="data_package" lang="km" />
<output filename="electron_strings_kn.pak" type="data_package" lang="kn" />
<output filename="electron_strings_ko.pak" type="data_package" lang="ko" />
<output filename="electron_strings_ky.pak" type="data_package" lang="ky" />
<output filename="electron_strings_lo.pak" type="data_package" lang="lo" />
<output filename="electron_strings_lt.pak" type="data_package" lang="lt" />
<output filename="electron_strings_lv.pak" type="data_package" lang="lv" />
<output filename="electron_strings_mk.pak" type="data_package" lang="mk" />
<output filename="electron_strings_ml.pak" type="data_package" lang="ml" />
<output filename="electron_strings_mn.pak" type="data_package" lang="mn" />
<output filename="electron_strings_mr.pak" type="data_package" lang="mr" />
<output filename="electron_strings_ms.pak" type="data_package" lang="ms" />
<output filename="electron_strings_my.pak" type="data_package" lang="my" />
<output filename="electron_strings_ne.pak" type="data_package" lang="ne" />
<output filename="electron_strings_nl.pak" type="data_package" lang="nl" />
<!-- The translation console uses 'no' for Norwegian Bokmål. It should
be 'nb'. -->
<output filename="electron_strings_nb.pak" type="data_package" lang="no" />
<output filename="electron_strings_or.pak" type="data_package" lang="or" />
<output filename="electron_strings_pa.pak" type="data_package" lang="pa" />
<output filename="electron_strings_pl.pak" type="data_package" lang="pl" />
<output filename="electron_strings_pt-BR.pak" type="data_package" lang="pt-BR" />
<output filename="electron_strings_pt-PT.pak" type="data_package" lang="pt-PT" />
<output filename="electron_strings_ro.pak" type="data_package" lang="ro" />
<output filename="electron_strings_ru.pak" type="data_package" lang="ru" />
<output filename="electron_strings_si.pak" type="data_package" lang="si" />
<output filename="electron_strings_sk.pak" type="data_package" lang="sk" />
<output filename="electron_strings_sl.pak" type="data_package" lang="sl" />
<output filename="electron_strings_sq.pak" type="data_package" lang="sq" />
<output filename="electron_strings_sr-Latn.pak" type="data_package" lang="sr-Latn" />
<output filename="electron_strings_sr.pak" type="data_package" lang="sr" />
<output filename="electron_strings_sv.pak" type="data_package" lang="sv" />
<output filename="electron_strings_sw.pak" type="data_package" lang="sw" />
<output filename="electron_strings_ta.pak" type="data_package" lang="ta" />
<output filename="electron_strings_te.pak" type="data_package" lang="te" />
<output filename="electron_strings_th.pak" type="data_package" lang="th" />
<output filename="electron_strings_tr.pak" type="data_package" lang="tr" />
<output filename="electron_strings_uk.pak" type="data_package" lang="uk" />
<output filename="electron_strings_ur.pak" type="data_package" lang="ur" />
<output filename="electron_strings_uz.pak" type="data_package" lang="uz" />
<output filename="electron_strings_vi.pak" type="data_package" lang="vi" />
<output filename="electron_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
<output filename="electron_strings_zh-HK.pak" type="data_package" lang="zh-HK" />
<output filename="electron_strings_zh-TW.pak" type="data_package" lang="zh-TW" />
<output filename="electron_strings_zu.pak" type="data_package" lang="zu" />
<!-- CARO TODO: Pseudolocales? -->
<output filename="electron_strings_ar-XB.pak" type="data_package" lang="ar-XB" />
<output filename="electron_strings_en-XA.pak" type="data_package" lang="en-XA" />
</outputs>
<translations>
<file path="translations/electron_strings_af.xtb" lang="af" />
<file path="translations/electron_strings_am.xtb" lang="am" />
<file path="translations/electron_strings_ar.xtb" lang="ar" />
<file path="translations/electron_strings_as.xtb" lang="as" />
<file path="translations/electron_strings_az.xtb" lang="az" />
<file path="translations/electron_strings_be.xtb" lang="be" />
<file path="translations/electron_strings_bg.xtb" lang="bg" />
<file path="translations/electron_strings_bn.xtb" lang="bn" />
<file path="translations/electron_strings_bs.xtb" lang="bs" />
<file path="translations/electron_strings_ca.xtb" lang="ca" />
<file path="translations/electron_strings_cs.xtb" lang="cs" />
<file path="translations/electron_strings_cy.xtb" lang="cy" />
<file path="translations/electron_strings_da.xtb" lang="da" />
<file path="translations/electron_strings_de.xtb" lang="de" />
<file path="translations/electron_strings_el.xtb" lang="el" />
<file path="translations/electron_strings_en-GB.xtb" lang="en-GB" />
<file path="translations/electron_strings_es-419.xtb" lang="es-419" />
<file path="translations/electron_strings_es.xtb" lang="es" />
<file path="translations/electron_strings_et.xtb" lang="et" />
<file path="translations/electron_strings_eu.xtb" lang="eu" />
<file path="translations/electron_strings_fa.xtb" lang="fa" />
<file path="translations/electron_strings_fi.xtb" lang="fi" />
<file path="translations/electron_strings_fil.xtb" lang="fil" />
<file path="translations/electron_strings_fr-CA.xtb" lang="fr-CA" />
<file path="translations/electron_strings_fr.xtb" lang="fr" />
<file path="translations/electron_strings_gl.xtb" lang="gl" />
<file path="translations/electron_strings_gu.xtb" lang="gu" />
<file path="translations/electron_strings_hi.xtb" lang="hi" />
<file path="translations/electron_strings_hr.xtb" lang="hr" />
<file path="translations/electron_strings_hu.xtb" lang="hu" />
<file path="translations/electron_strings_hy.xtb" lang="hy" />
<file path="translations/electron_strings_id.xtb" lang="id" />
<file path="translations/electron_strings_is.xtb" lang="is" />
<file path="translations/electron_strings_it.xtb" lang="it" />
<!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
<file path="translations/electron_strings_iw.xtb" lang="he" />
<file path="translations/electron_strings_ja.xtb" lang="ja" />
<file path="translations/electron_strings_ka.xtb" lang="ka" />
<file path="translations/electron_strings_kk.xtb" lang="kk" />
<file path="translations/electron_strings_km.xtb" lang="km" />
<file path="translations/electron_strings_kn.xtb" lang="kn" />
<file path="translations/electron_strings_ko.xtb" lang="ko" />
<file path="translations/electron_strings_ky.xtb" lang="ky" />
<file path="translations/electron_strings_lo.xtb" lang="lo" />
<file path="translations/electron_strings_lt.xtb" lang="lt" />
<file path="translations/electron_strings_lv.xtb" lang="lv" />
<file path="translations/electron_strings_mk.xtb" lang="mk" />
<file path="translations/electron_strings_ml.xtb" lang="ml" />
<file path="translations/electron_strings_mn.xtb" lang="mn" />
<file path="translations/electron_strings_mr.xtb" lang="mr" />
<file path="translations/electron_strings_ms.xtb" lang="ms" />
<file path="translations/electron_strings_my.xtb" lang="my" />
<file path="translations/electron_strings_ne.xtb" lang="ne" />
<file path="translations/electron_strings_nl.xtb" lang="nl" />
<file path="translations/electron_strings_no.xtb" lang="no" />
<file path="translations/electron_strings_or.xtb" lang="or" />
<file path="translations/electron_strings_pa.xtb" lang="pa" />
<file path="translations/electron_strings_pl.xtb" lang="pl" />
<file path="translations/electron_strings_pt-BR.xtb" lang="pt-BR" />
<file path="translations/electron_strings_pt-PT.xtb" lang="pt-PT" />
<file path="translations/electron_strings_ro.xtb" lang="ro" />
<file path="translations/electron_strings_ru.xtb" lang="ru" />
<file path="translations/electron_strings_si.xtb" lang="si" />
<file path="translations/electron_strings_sk.xtb" lang="sk" />
<file path="translations/electron_strings_sl.xtb" lang="sl" />
<file path="translations/electron_strings_sq.xtb" lang="sq" />
<file path="translations/electron_strings_sr-Latn.xtb" lang="sr-Latn" />
<file path="translations/electron_strings_sr.xtb" lang="sr" />
<file path="translations/electron_strings_sv.xtb" lang="sv" />
<file path="translations/electron_strings_sw.xtb" lang="sw" />
<file path="translations/electron_strings_ta.xtb" lang="ta" />
<file path="translations/electron_strings_te.xtb" lang="te" />
<file path="translations/electron_strings_th.xtb" lang="th" />
<file path="translations/electron_strings_tr.xtb" lang="tr" />
<file path="translations/electron_strings_uk.xtb" lang="uk" />
<file path="translations/electron_strings_ur.xtb" lang="ur" />
<file path="translations/electron_strings_uz.xtb" lang="uz" />
<file path="translations/electron_strings_vi.xtb" lang="vi" />
<file path="translations/electron_strings_zh-CN.xtb" lang="zh-CN" />
<file path="translations/electron_strings_zh-HK.xtb" lang="zh-HK" />
<file path="translations/electron_strings_zh-TW.xtb" lang="zh-TW" />
<file path="translations/electron_strings_zu.xtb" lang="zu" />
</translations>
<release seq="1">
<messages fallback_to_english="true">
<message name="IDS_MAC_NOTIFICATION_INLINE_REPLY_BUTTON" desc="Label for the inline reply button inside a macOS notification.">
Reply
</message>
<message name="IDS_MAC_NOTIFICATION_SHOW_BUTTON" desc="Label for the default action button inside a macOS notification.">
Show
</message>
</messages>
<release seq="1" allow_pseudo="false">
<includes>
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}/shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
</includes>
</release>
</grit>
</grit>

View File

@@ -1,326 +0,0 @@
#!/usr/bin/env node
// Driver script that replaces webpack for building Electron's internal
// JS bundles. Each bundle is a single esbuild invocation parameterized by
// the per-target configuration files under build/esbuild/configs.
//
// Invoked by the GN `esbuild_build` template via `npm run bundle -- …`.
'use strict';
const esbuild = require('esbuild');
const fs = require('node:fs');
const path = require('node:path');
const electronRoot = path.resolve(__dirname, '../..');
function parseArgs (argv) {
const args = {};
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a.startsWith('--')) {
const key = a.slice(2);
const next = argv[i + 1];
if (next === undefined || next.startsWith('--')) {
args[key] = true;
} else {
args[key] = next;
i++;
}
}
}
return args;
}
// Parse $target_gen_dir/buildflags/buildflags.h (a C++ header containing
// `#define BUILDFLAG_INTERNAL_NAME() (0|1)` lines) into a map of flag name
// to boolean. Used to seed the `define` table so that `BUILDFLAG(NAME)` call
// sites can be statically folded to `true`/`false` at build time.
function parseBuildflags (buildflagsPath) {
const flags = {};
if (!buildflagsPath) return flags;
const source = fs.readFileSync(buildflagsPath, 'utf8');
const re = /#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/g;
let match;
while ((match = re.exec(source)) !== null) {
const [, name, value] = match;
flags[name] = value === '1';
}
return flags;
}
// Return the list of esbuild `alias` entries used by every bundle. esbuild's
// alias matches the full module specifier (no `$` suffix trickery like
// webpack), so the bare `electron` alias also matches `electron/main`, etc.,
// because esbuild matches the leftmost segment first.
function buildAliases (electronAPIFile, { aliasTimers }) {
const aliases = {
electron: electronAPIFile,
'electron/main': electronAPIFile,
'electron/renderer': electronAPIFile,
'electron/common': electronAPIFile,
'electron/utility': electronAPIFile
};
// Only browser-platform bundles (sandboxed_renderer, isolated_renderer,
// preload_realm) need the timers shim — Node's `timers` builtin is not
// available there. For node-platform bundles (browser, renderer, worker,
// utility, node) the alias MUST NOT apply: lib/common/init.ts wraps the
// real Node timers and then assigns the wrappers onto globalThis. If
// those bundles saw the shim, the wrappers would recursively call back
// into globalThis.setTimeout and blow the stack.
if (aliasTimers) {
aliases.timers = path.resolve(electronRoot, 'lib', 'common', 'timers-shim.ts');
}
return aliases;
}
// esbuild's `alias` does not support wildcard prefixes like `@electron/internal/*`.
// We instead install a tiny resolve plugin that rewrites any import starting
// with that prefix to an absolute path under `lib/`. The plugin must also
// replicate esbuild's extension/index resolution because returning a path
// from onResolve bypasses the default resolver.
function internalAliasPlugin () {
const candidates = (base) => [
base,
`${base}.ts`,
`${base}.js`,
path.join(base, 'index.ts'),
path.join(base, 'index.js')
];
return {
name: 'electron-internal-alias',
setup (build) {
build.onResolve({ filter: /^@electron\/internal(\/|$)/ }, (args) => {
// Tolerate stray double slashes in import paths (webpack was lenient).
const rel = args.path.replace(/^@electron\/internal\/?/, '').replace(/^\/+/, '');
const base = path.resolve(electronRoot, 'lib', rel);
for (const c of candidates(base)) {
try {
if (fs.statSync(c).isFile()) return { path: c };
} catch { /* keep looking */ }
}
return { errors: [{ text: `Cannot resolve @electron/internal path: ${args.path}` }] };
});
}
};
}
// Rewrites `BUILDFLAG(NAME)` call-sites to `(true)` or `(false)` at load
// time, equivalent to the combination of webpack's DefinePlugin substitution
// (BUILDFLAG -> "" and NAME -> "true"/"false") that the old config used.
// Doing it in a single regex pass keeps the semantics identical and avoids
// fighting with esbuild's AST-level `define` quoting rules.
function buildflagPlugin (buildflags, { allowUnknown = false } = {}) {
return {
name: 'electron-buildflag',
setup (build) {
build.onLoad({ filter: /\.(ts|js)$/ }, async (args) => {
const source = await fs.promises.readFile(args.path, 'utf8');
if (!source.includes('BUILDFLAG(')) {
return { contents: source, loader: args.path.endsWith('.ts') ? 'ts' : 'js' };
}
const rewritten = source.replace(/BUILDFLAG\(([A-Z0-9_]+)\)/g, (_, name) => {
if (!Object.prototype.hasOwnProperty.call(buildflags, name)) {
if (allowUnknown) return '(false)';
throw new Error(`Unknown BUILDFLAG: ${name} (in ${args.path})`);
}
return `(${buildflags[name]})`;
});
return { contents: rewritten, loader: args.path.endsWith('.ts') ? 'ts' : 'js' };
});
}
};
}
// TODO(MarshallOfSound): drop this patch once evanw/esbuild#4441 lands and
// we bump esbuild — that PR adds a `__toCommonJSCached` helper for the
// inline-require path so identity is preserved upstream. Tracked at
// https://github.com/evanw/esbuild/issues/4440.
//
// esbuild's runtime emits `__toCommonJS = (mod) => __copyProps(__defProp({},
// "__esModule", { value: true }), mod)`, which allocates a fresh wrapper
// object every time `require()` resolves to a bundled ESM module. That
// breaks identity expectations our code relies on (e.g. sandboxed preloads
// expecting `require('timers') === require('node:timers')`, and the
// defineProperties getters in lib/common/define-properties.ts expecting
// stable namespaces). A cached WeakMap-backed version of __toCommonJS
// existed in older esbuild releases (see evanw/esbuild#2126) but was
// removed in evanw/esbuild@f4ff26d3 (0.14.27). Substitute a memoized
// variant in post-processing so every call site returns the same wrapper
// for the same underlying namespace, matching webpack's
// `__webpack_require__` cache semantics.
const ESBUILD_TO_COMMONJS_PATTERN =
/var __toCommonJS = \(mod\) => __copyProps\(__defProp\(\{\}, "__esModule", \{ value: true \}\), mod\);/;
const ESBUILD_TO_COMMONJS_REPLACEMENT =
'var __toCommonJS = /* @__PURE__ */ ((cache) => (mod) => {\n' +
' var cached = cache.get(mod);\n' +
' if (cached) return cached;\n' +
' var result = __copyProps(__defProp({}, "__esModule", { value: true }), mod);\n' +
' cache.set(mod, result);\n' +
' return result;\n' +
' })(new WeakMap());';
function patchToCommonJS (source) {
// Once evanw/esbuild#4441 lands, esbuild will emit `__toCommonJSCached`
// for inline require() — when we see that helper in the output, the
// upstream fix is active and this whole patch is a no-op (and should be
// deleted on the next esbuild bump).
if (source.includes('__toCommonJSCached')) {
return source;
}
if (!ESBUILD_TO_COMMONJS_PATTERN.test(source)) {
// Some bundles may not contain any ESM-shaped modules, in which case
// esbuild omits the helper entirely and there is nothing to patch.
if (source.includes('__toCommonJS')) {
throw new Error(
'esbuild bundle contains __toCommonJS but did not match the ' +
'expected pattern; the runtime helper has likely changed upstream. ' +
'Update ESBUILD_TO_COMMONJS_PATTERN in build/esbuild/bundle.js, or ' +
'delete patchToCommonJS entirely if evanw/esbuild#4441 has landed.'
);
}
return source;
}
return source.replace(ESBUILD_TO_COMMONJS_PATTERN, ESBUILD_TO_COMMONJS_REPLACEMENT);
}
// Wrap bundle source text in the same header/footer pairs webpack's
// wrapper-webpack-plugin used. The try/catch wrapper is load-bearing:
// shell/common/node_util.cc's CompileAndCall relies on it to prevent
// exceptions from tearing down bootstrap.
function applyWrappers (source, opts, outputFilename) {
let wrapped = patchToCommonJS(source);
if (opts.wrapInitWithProfilingTimeout) {
const header = 'function ___electron_webpack_init__() {';
const footer = '\n};\nif ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {\n setTimeout(___electron_webpack_init__, 0);\n} else {\n ___electron_webpack_init__();\n}';
wrapped = header + wrapped + footer;
}
if (opts.wrapInitWithTryCatch) {
const header = 'try {';
const footer = `\n} catch (err) {\n console.error('Electron ${outputFilename} script failed to run');\n console.error(err);\n}`;
wrapped = header + wrapped + footer;
}
return wrapped;
}
async function buildBundle (opts, cliArgs) {
const {
target,
alwaysHasNode,
loadElectronFromAlternateTarget,
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch
} = opts;
const outputFilename = cliArgs['output-filename'] || `${target}.bundle.js`;
const outputPath = cliArgs['output-path'] || path.resolve(electronRoot, 'out');
const mode = cliArgs.mode || 'development';
const minify = mode === 'production';
const printGraph = !!cliArgs['print-graph'];
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
if (!fs.existsSync(entry)) {
entry = path.resolve(electronRoot, 'lib', target, 'init.js');
}
const electronAPIFile = path.resolve(
electronRoot,
'lib',
loadElectronFromAlternateTarget || target,
'api',
'exports',
'electron.ts'
);
const buildflags = parseBuildflags(cliArgs.buildflags);
// Shims that stand in for webpack ProvidePlugin. Each target gets the
// minimum set of globals it needs; the capture files mirror the originals
// under lib/common so the behavior (grab globals before user code can
// delete them) is preserved exactly.
const inject = [];
if (opts.targetDeletesNodeGlobals) {
inject.push(path.resolve(__dirname, 'shims', 'node-globals-shim.js'));
}
if (!alwaysHasNode) {
inject.push(path.resolve(__dirname, 'shims', 'browser-globals-shim.js'));
}
inject.push(path.resolve(__dirname, 'shims', 'promise-shim.js'));
const result = await esbuild.build({
entryPoints: [entry],
bundle: true,
format: 'iife',
platform: alwaysHasNode ? 'node' : 'browser',
target: 'es2022',
minify,
// Preserve class/function names in both development and production so
// gin_helper-surfaced constructor names and stack traces stay readable.
// (Under webpack this only mattered when terser ran in is_official_build;
// esbuild applies the same rename pressure in dev too, so keep it on
// unconditionally for consistency.)
keepNames: true,
sourcemap: false,
logLevel: 'warning',
metafile: true,
write: false,
resolveExtensions: ['.ts', '.js'],
alias: buildAliases(electronAPIFile, { aliasTimers: !alwaysHasNode }),
inject,
define: {
__non_webpack_require__: 'require'
},
// Node internal modules we pull through __non_webpack_require__ at runtime.
// These must not be bundled — esbuild should leave the literal require()
// call alone so the outer Node scope resolves them.
external: [
'internal/modules/helpers',
'internal/modules/run_main',
'internal/fs/utils',
'internal/util',
'internal/validators',
'internal/url'
],
plugins: [
internalAliasPlugin(),
buildflagPlugin(buildflags, { allowUnknown: printGraph })
]
});
if (printGraph) {
const inputs = Object.keys(result.metafile.inputs)
.filter((p) => !p.includes('node_modules') && !p.startsWith('..'))
.map((p) => path.relative(electronRoot, path.resolve(electronRoot, p)));
process.stdout.write(JSON.stringify(inputs) + '\n');
return;
}
if (result.outputFiles.length !== 1) {
throw new Error(`Expected exactly one output file, got ${result.outputFiles.length}`);
}
const wrapped = applyWrappers(
result.outputFiles[0].text,
{ wrapInitWithProfilingTimeout, wrapInitWithTryCatch },
outputFilename
);
await fs.promises.mkdir(outputPath, { recursive: true });
await fs.promises.writeFile(path.join(outputPath, outputFilename), wrapped);
}
async function main () {
const cliArgs = parseArgs(process.argv.slice(2));
if (!cliArgs.config) {
console.error('Usage: bundle.js --config <path> [--output-filename X] [--output-path Y] [--mode development|production] [--buildflags path/to/buildflags.h] [--print-graph]');
process.exit(1);
}
const configPath = path.resolve(cliArgs.config);
const opts = require(configPath);
await buildBundle(opts, cliArgs);
}
main().catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -1,4 +0,0 @@
module.exports = {
target: 'browser',
alwaysHasNode: true
};

View File

@@ -1,4 +0,0 @@
module.exports = {
target: 'node',
alwaysHasNode: true
};

View File

@@ -1,4 +0,0 @@
module.exports = {
target: 'utility',
alwaysHasNode: true
};

View File

@@ -1,18 +0,0 @@
// Injected into browser-platform bundles (sandboxed_renderer, isolated_renderer,
// preload_realm) where Node globals are not implicitly available. Supplies
// `Buffer`, `process`, and `global` — replacing webpack's ProvidePlugin
// polyfill injection plus webpack 5's built-in `global -> globalThis` rewrite
// that `target: 'web'` performed automatically.
//
// The `buffer` and `process/browser` imports below intentionally use the
// npm polyfill packages, not Node's built-in `node:buffer` / `node:process`
// modules, because these shims ship into browser-platform bundles that do
// not have Node globals available at runtime.
/* eslint-disable import/order, import/enforce-node-protocol-usage */
import { Buffer as _Buffer } from 'buffer';
import _process from 'process/browser';
const _global = globalThis;
export { _Buffer as Buffer, _process as process, _global as global };

View File

@@ -1,14 +0,0 @@
// Injected into renderer/worker bundles to replace webpack's ProvidePlugin
// that captured `Buffer`, `global`, and `process` before user code could
// delete them from the global scope. The Module.wrapper override in
// lib/renderer/init.ts re-injects these into user preload scripts later.
// Rip globals off of globalThis/self/window so they are captured in this
// module's closure and retained even if the caller later deletes them.
const _global = typeof globalThis !== 'undefined'
? globalThis.global
: (self || window).global;
const _process = _global.process;
const _Buffer = _global.Buffer;
export { _global as global, _process as process, _Buffer as Buffer };

View File

@@ -1,7 +0,0 @@
// Captures the original `Promise` constructor so that userland mutations of
// `global.Promise.resolve` do not affect Electron's internal code. Mirrors
// webpack's ProvidePlugin reference to lib/common/webpack-globals-provider.
const _Promise = globalThis.Promise;
export { _Promise as Promise };

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="af">
<translation id="2727175239389218057">Antwoord</translation>
<translation id="5300589172476337783">Wys</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="am">
<translation id="2727175239389218057">ምላሽ ስጥ</translation>
<translation id="5300589172476337783">አሳይ</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
<translation id="2727175239389218057">الرّد</translation>
<translation id="5300589172476337783">عرض</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="as">
<translation id="2727175239389218057">প্ৰত্যুত্তৰ দিয়ক</translation>
<translation id="5300589172476337783">দেখুৱাওক</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="az">
<translation id="2727175239389218057">Cavablayın</translation>
<translation id="5300589172476337783">Göstərin</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="be">
<translation id="2727175239389218057">Адказаць</translation>
<translation id="5300589172476337783">Паказаць</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bg">
<translation id="2727175239389218057">Отговор</translation>
<translation id="5300589172476337783">Показване</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
<translation id="2727175239389218057">উত্তর দিন</translation>
<translation id="5300589172476337783">দেখান</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bs">
<translation id="2727175239389218057">Odgovori</translation>
<translation id="5300589172476337783">Prikaži</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ca">
<translation id="2727175239389218057">Respon</translation>
<translation id="5300589172476337783">Mostra</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
<translation id="2727175239389218057">Odpovědět</translation>
<translation id="5300589172476337783">Zobrazit</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="cy">
<translation id="2727175239389218057">Ateb</translation>
<translation id="5300589172476337783">Arddangos</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="da">
<translation id="2727175239389218057">Svar</translation>
<translation id="5300589172476337783">Vis</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="de">
<translation id="2727175239389218057">Antworten</translation>
<translation id="5300589172476337783">Anzeigen</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="el">
<translation id="2727175239389218057">Απάντηση</translation>
<translation id="5300589172476337783">Εμφάνιση</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="en-GB">
<translation id="2727175239389218057">Reply</translation>
<translation id="5300589172476337783">Show</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es-419">
<translation id="2727175239389218057">Responder</translation>
<translation id="5300589172476337783">Mostrar</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es">
<translation id="2727175239389218057">Responder</translation>
<translation id="5300589172476337783">Mostrar</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="et">
<translation id="2727175239389218057">Vasta</translation>
<translation id="5300589172476337783">Kuva</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="eu">
<translation id="2727175239389218057">Erantzun</translation>
<translation id="5300589172476337783">Erakutsi</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
<translation id="2727175239389218057">پاسخ دادن</translation>
<translation id="5300589172476337783">نمایش</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fi">
<translation id="2727175239389218057">Vastaa</translation>
<translation id="5300589172476337783">Näytä</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fil">
<translation id="2727175239389218057">Sumagot</translation>
<translation id="5300589172476337783">Ipakita</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fr-CA">
<translation id="2727175239389218057">Répondre</translation>
<translation id="5300589172476337783">Afficher</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fr">
<translation id="2727175239389218057">Répondre</translation>
<translation id="5300589172476337783">Afficher</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="gl">
<translation id="2727175239389218057">Responder</translation>
<translation id="5300589172476337783">Mostrar</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="gu">
<translation id="2727175239389218057">જવાબ આપો</translation>
<translation id="5300589172476337783">બતાવો</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
<translation id="2727175239389218057">जवाब दें</translation>
<translation id="5300589172476337783">दिखाएं</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hr">
<translation id="2727175239389218057">Odgovori</translation>
<translation id="5300589172476337783">Prikaži</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hu">
<translation id="2727175239389218057">Válasz</translation>
<translation id="5300589172476337783">Megjelenítés</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hy">
<translation id="2727175239389218057">Պատասխանել</translation>
<translation id="5300589172476337783">Ցույց տալ</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="id">
<translation id="2727175239389218057">Balas</translation>
<translation id="5300589172476337783">Tampilkan</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="is">
<translation id="2727175239389218057">Svara</translation>
<translation id="5300589172476337783">Sýna</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="it">
<translation id="2727175239389218057">Rispondi</translation>
<translation id="5300589172476337783">Mostra</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="iw">
<translation id="2727175239389218057">מענה</translation>
<translation id="5300589172476337783">הצגה</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
<translation id="2727175239389218057">返信</translation>
<translation id="5300589172476337783">表示</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ka">
<translation id="2727175239389218057">პასუხი</translation>
<translation id="5300589172476337783">ჩვენება</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="kk">
<translation id="2727175239389218057">Жауап беру</translation>
<translation id="5300589172476337783">Көрсету</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="km">
<translation id="2727175239389218057">ឆ្លើយតប</translation>
<translation id="5300589172476337783">បង្ហាញ</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="kn">
<translation id="2727175239389218057">ಪ್ರತ್ಯುತ್ತರಿಸಿ</translation>
<translation id="5300589172476337783">ತೋರಿಸಿ</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ko">
<translation id="2727175239389218057">답장</translation>
<translation id="5300589172476337783">표시</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ky">
<translation id="2727175239389218057">Жооп берүү</translation>
<translation id="5300589172476337783">Көрсөтүү</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lo">
<translation id="2727175239389218057">ຕອບກັບ</translation>
<translation id="5300589172476337783">ສະ​ແດງ​</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lt">
<translation id="2727175239389218057">Atsakyti</translation>
<translation id="5300589172476337783">Rodyti</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
<translation id="2727175239389218057">Atbildēt</translation>
<translation id="5300589172476337783">Rādīt</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mk">
<translation id="2727175239389218057">Одговори</translation>
<translation id="5300589172476337783">Прикажи</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ml">
<translation id="2727175239389218057">മറുപടി നൽകുക</translation>
<translation id="5300589172476337783">കാണിക്കുക</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mn">
<translation id="2727175239389218057">Хариулах</translation>
<translation id="5300589172476337783">Харуулах</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mr">
<translation id="2727175239389218057">उत्तर द्या</translation>
<translation id="5300589172476337783">दर्शवा</translation>
</translationbundle>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ms">
<translation id="2727175239389218057">Balas</translation>
<translation id="5300589172476337783">Paparkan</translation>
</translationbundle>

Some files were not shown because too many files have changed in this diff Show More