mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
Compare commits
171 Commits
nikwen/way
...
v42.0.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abd47d40cb | ||
|
|
36a610a9d0 | ||
|
|
30d5e51a0e | ||
|
|
7790ade15a | ||
|
|
bffc44fae9 | ||
|
|
6da0023312 | ||
|
|
88cc5da6cf | ||
|
|
d91a5e78e5 | ||
|
|
b38c88664e | ||
|
|
687bd0a1f0 | ||
|
|
9d194e28ab | ||
|
|
b6de8acc8a | ||
|
|
b51e62e560 | ||
|
|
f1958d838c | ||
|
|
8b2dba3726 | ||
|
|
4ac50292d5 | ||
|
|
81e76165ae | ||
|
|
acf615229d | ||
|
|
d5cea60ac7 | ||
|
|
60ec7cd0fb | ||
|
|
3d7d676bee | ||
|
|
c5b0ee8a9b | ||
|
|
3ea2c9c760 | ||
|
|
067fe3d1f1 | ||
|
|
75a7ebc7c0 | ||
|
|
64055f27e7 | ||
|
|
09156151c4 | ||
|
|
b07503d468 | ||
|
|
ef664710a0 | ||
|
|
61954b457b | ||
|
|
b9c4e815ef | ||
|
|
48cc1126bd | ||
|
|
d146c4f019 | ||
|
|
5f3c30b8e5 | ||
|
|
1a67d03b0b | ||
|
|
043377523a | ||
|
|
d1c3b41f24 | ||
|
|
3bde2f38a8 | ||
|
|
c39e3d5687 | ||
|
|
316351f673 | ||
|
|
ad5b435f43 | ||
|
|
9c1e9e0237 | ||
|
|
844bbf8484 | ||
|
|
a9f2f95d64 | ||
|
|
30cf3882de | ||
|
|
ec57a84297 | ||
|
|
a078ed77c5 | ||
|
|
10fb5b39c5 | ||
|
|
4bd7aa8d98 | ||
|
|
70a321634c | ||
|
|
aa7a81deb9 | ||
|
|
9ecc0670fe | ||
|
|
4affacb4e1 | ||
|
|
63d2c9c9d1 | ||
|
|
3c8256cdcc | ||
|
|
6e035d36e1 | ||
|
|
45bc6435ce | ||
|
|
b0b7a70f69 | ||
|
|
64554bcc13 | ||
|
|
5c1bb7126d | ||
|
|
3087643c9c | ||
|
|
8e5e775e84 | ||
|
|
2a1790e0ef | ||
|
|
be93d72e82 | ||
|
|
4cc29c25e5 | ||
|
|
acdabe464e | ||
|
|
d74660fb3a | ||
|
|
b8daf0b57d | ||
|
|
95af3a7e78 | ||
|
|
1b5f3ea40e | ||
|
|
eb19030912 | ||
|
|
bc02cdf5b3 | ||
|
|
f9de33b79f | ||
|
|
670b87c7ee | ||
|
|
c4addb7f13 | ||
|
|
a0f9ff4cc0 | ||
|
|
b31c3efb29 | ||
|
|
4604c78c88 | ||
|
|
7bd5de006e | ||
|
|
b861998db0 | ||
|
|
786bf64a09 | ||
|
|
32fd562a6f | ||
|
|
8bca9a0a7c | ||
|
|
e258e0735d | ||
|
|
7e84164ed9 | ||
|
|
1e43451d08 | ||
|
|
a0f042f8d3 | ||
|
|
b5fdb985f5 | ||
|
|
487c29b3e2 | ||
|
|
b5f2375eb6 | ||
|
|
0d74dce4ee | ||
|
|
7e09a452a8 | ||
|
|
fd717ad03e | ||
|
|
3cb947d1b9 | ||
|
|
1f167f66f2 | ||
|
|
6fc19a017f | ||
|
|
cba85c0983 | ||
|
|
2067d3a414 | ||
|
|
d298f4be88 | ||
|
|
be53e0a470 | ||
|
|
5b6b1c1641 | ||
|
|
1f51bf66fb | ||
|
|
1686aa37f2 | ||
|
|
ef8c983ccb | ||
|
|
28f46a967e | ||
|
|
04614eed17 | ||
|
|
964cf07e19 | ||
|
|
cd495e20a7 | ||
|
|
d73eaf83f5 | ||
|
|
65f97115f1 | ||
|
|
3aa89f7ff1 | ||
|
|
efb7477305 | ||
|
|
4323fa4b06 | ||
|
|
5c61e826c8 | ||
|
|
bba4374952 | ||
|
|
eb80b7c889 | ||
|
|
199588ff02 | ||
|
|
510576fcd7 | ||
|
|
0c09677949 | ||
|
|
7356c75ca3 | ||
|
|
e1e3ecee75 | ||
|
|
d1b34d76a8 | ||
|
|
d456259da4 | ||
|
|
e21a1b8cd1 | ||
|
|
7f8e35c8c8 | ||
|
|
2da7d8dadb | ||
|
|
d2e0d19985 | ||
|
|
d074963b30 | ||
|
|
ef7f35e15c | ||
|
|
5559ffa184 | ||
|
|
4ede07538d | ||
|
|
b310e26059 | ||
|
|
ad4dc5045f | ||
|
|
a45f5dbcba | ||
|
|
ba46942463 | ||
|
|
602119ea25 | ||
|
|
8f0f8401f2 | ||
|
|
f90dd8d6bd | ||
|
|
6dfb19210b | ||
|
|
119127b23a | ||
|
|
a806e3890f | ||
|
|
e48835e4e0 | ||
|
|
7dfd55b8ea | ||
|
|
e02471eba0 | ||
|
|
83615377dc | ||
|
|
f8eb1b2a31 | ||
|
|
d23fbd5c71 | ||
|
|
e7d473337f | ||
|
|
1766e229eb | ||
|
|
0d0a58cbd4 | ||
|
|
99a6230d6b | ||
|
|
49a9efa764 | ||
|
|
1b080d4097 | ||
|
|
191f673246 | ||
|
|
636e0e26f3 | ||
|
|
a7744df592 | ||
|
|
b0d5b63477 | ||
|
|
0f54cb1d8b | ||
|
|
4ed6809aaa | ||
|
|
44ebbc11ed | ||
|
|
d1b5d7c9ed | ||
|
|
d5ac7d3f33 | ||
|
|
17ddcbf01f | ||
|
|
3b3e1e8ef6 | ||
|
|
045516d598 | ||
|
|
1fffaeb481 | ||
|
|
88e666f210 | ||
|
|
90f7796adb | ||
|
|
e6925bef1f | ||
|
|
6a5e9fe677 | ||
|
|
270c9e7ce9 |
@@ -1,106 +0,0 @@
|
||||
---
|
||||
name: chrome-release-cls
|
||||
description: Given a Chrome Releases blog post URL (chromereleases.googleblog.com), extract every CVE/bug and find the underlying Gerrit CL that fixed it by searching the local Chromium checkout and sub-repos. Use when asked to map Chrome security release notes to fixing CLs, or to find which commits correspond to CVEs in a Chrome stable update.
|
||||
---
|
||||
|
||||
# Chrome Release → Fixing CL Mapper
|
||||
|
||||
Maps every security fix in a Chrome Releases blog post to the Gerrit CL(s) that fixed it.
|
||||
|
||||
## Input
|
||||
|
||||
`$ARGUMENTS` — a `https://chromereleases.googleblog.com/...` URL. If empty, ask the user for one.
|
||||
|
||||
## Procedure
|
||||
|
||||
### 1. Extract CVE → bug ID pairs from the blog post
|
||||
|
||||
The blog HTML buries bug IDs inside `<a>` tags, so strip tags first. Run:
|
||||
|
||||
```bash
|
||||
curl -sL "$URL" | python3 -c '
|
||||
import sys, re, html
|
||||
t = re.sub(r"<[^>]+>", " ", sys.stdin.read())
|
||||
t = re.sub(r"\s+", " ", html.unescape(t))
|
||||
seen = set()
|
||||
for m in re.finditer(r"\[\s*(\d{6,})\s*\]\s*(Critical|High|Medium|Low)\s*(CVE-\d{4}-\d+):\s*([^.]+?)\.", t):
|
||||
if m.group(3) in seen: continue
|
||||
seen.add(m.group(3))
|
||||
print(f"{m.group(3)}|{m.group(1)}|{m.group(2)}|{m.group(4).strip()}")
|
||||
' > /tmp/cve_bugs.txt
|
||||
cat /tmp/cve_bugs.txt
|
||||
```
|
||||
|
||||
If this yields nothing, the page may have changed format — fall back to `grep -oE 'CVE-[0-9]{4}-[0-9]+'` and `grep -oE 'crbug\.com/[0-9]+'` and pair them by order.
|
||||
|
||||
### 2. Find the fixing CL for each bug
|
||||
|
||||
Search git history in the Chromium checkout and relevant sub-repos for commits whose `Bug:` or `Fixed:` footer references the bug ID, then extract the `Reviewed-on:` Gerrit URL.
|
||||
|
||||
Repo selection by component keyword:
|
||||
- ANGLE → `third_party/angle`
|
||||
- Skia, Graphite → `third_party/skia`
|
||||
- PDFium → `third_party/pdfium`
|
||||
- Dawn → `third_party/dawn`
|
||||
- V8, Turbofan, Maglev, Turboshaft → `v8`
|
||||
- everything else → `.` (chromium/src)
|
||||
|
||||
Always also fall back to `.` if the hinted repo has no match.
|
||||
|
||||
```bash
|
||||
cd /root/src/electron/src # chromium root (parent of electron/)
|
||||
|
||||
lookup() {
|
||||
local bug="$1" repos="$2"
|
||||
for repo in $repos . v8 third_party/skia third_party/angle third_party/pdfium third_party/dawn; do
|
||||
local hits
|
||||
hits=$(git -C "$repo" log --all --since='6 months ago' -E \
|
||||
--grep="(Bug|Fixed):.*\\b${bug}\\b" --format='%H' 2>/dev/null | sort -u)
|
||||
[[ -z "$hits" ]] && continue
|
||||
while read -r h; do
|
||||
git -C "$repo" log -1 --format='%B' "$h" | grep '^Reviewed-on:' | sed 's/^/ /'
|
||||
echo " ↳ $(git -C "$repo" log -1 --format='%s' "$h")"
|
||||
done <<<"$hits"
|
||||
return 0
|
||||
done
|
||||
echo " (not found locally)"
|
||||
}
|
||||
```
|
||||
|
||||
Drive it from `/tmp/cve_bugs.txt`. Prefer the **non-`[M1xx]`-prefixed** commit subject as the canonical main CL; the `[M1xx]` ones are branch cherry-picks.
|
||||
|
||||
### 3. Handle misses
|
||||
|
||||
For any bug with no local hit:
|
||||
- `git -C <repo> fetch origin` then re-search `--remotes` (fix may be newer than the checkout).
|
||||
- Query Gerrit directly: `curl -s "https://chromium-review.googlesource.com/changes/?q=bug:${BUG}&n=10" | tail -n +2 | python3 -m json.tool` (also try `skia-review`, `pdfium-review`, `dawn-review`, `aomedia-review`).
|
||||
- **`b/` bug format (Skia, Graphite, Dawn):** These repos reference bugs as `b/<id>` in commit messages rather than `Bug: <id>` footers. The Gerrit `bug:` query will return nothing. Use `message:<id>` search instead:
|
||||
```bash
|
||||
curl -s "https://skia-review.googlesource.com/changes/?q=message:${BUG}&n=5" | tail -n +2
|
||||
```
|
||||
Apply the same pattern for `dawn-review.googlesource.com` when the component is Dawn.
|
||||
- **Tracing main CLs from merges:** When only `[M1xx]` merge CLs are found, query the CL detail for `cherry_pick_of_change` to find the original main CL number:
|
||||
```bash
|
||||
curl -s "https://chromium-review.googlesource.com/changes/${CL_NUM}?o=CURRENT_REVISION" | tail -n +2 | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
print(d.get('cherry_pick_of_change', 'none'))
|
||||
"
|
||||
```
|
||||
- If still nothing and the bug was reported very recently (especially by "Google Threat Intelligence" or marked in-the-wild), the CL is likely still access-restricted — report it as such rather than guessing.
|
||||
|
||||
### 4. Special cases
|
||||
|
||||
- **Roll CLs — skip and find the upstream fix:** For components whose fixes land in upstream repos (PDFium, Dawn, Skia, Graphite, libaom, libvpx, ffmpeg), the chromium-review hit will be a `Roll src/third_party/...` commit. Do not report the roll CL as the fix. Instead, query the component's own Gerrit instance directly for the actual fixing CL:
|
||||
- PDFium → `pdfium-review.googlesource.com` (use `bug:` or `message:` query)
|
||||
- Dawn → `dawn-review.googlesource.com` (use `message:` query — uses `b/` format)
|
||||
- Skia / Graphite → `skia-review.googlesource.com` (use `message:` query — uses `b/` format)
|
||||
- libaom → `aomedia-review.googlesource.com`
|
||||
|
||||
Only if the upstream Gerrit instance returns no results should you fall back to reporting the roll CL — in that case, include the roll CL and note that the actual fix is upstream but the specific CL could not be identified.
|
||||
- Multiple `Reviewed-on:` lines in one commit body: cherry-picks keep the original line plus a new one. The **first** `Reviewed-on:` is the original CL.
|
||||
- A bug may have multiple distinct fix CLs (fix + follow-up hardening) — list all of them.
|
||||
|
||||
### 5. Output
|
||||
|
||||
Produce a markdown table per severity level: `CVE | Bug | Component | Fix CL (main)`. Link bugs as `https://crbug.com/<id>`. Save raw output (including all branch merges) to `/tmp/cve_cls.txt` and mention the path.
|
||||
@@ -1,123 +0,0 @@
|
||||
---
|
||||
name: chrome-release-verify
|
||||
description: End-to-end Chrome security backport for an Electron release branch. Given a Chrome Releases blog URL and a branch (e.g. 41-x-y), determines which CVE fixes are missing from the *actual synced source*, writes the cherry-pick patches locally, validates them with `e sync --3` + `lint --patches`, then pushes a single PR. Use when asked to backport a Chrome security release to N-x-y, "is CVE-X already in N-x-y?", or to produce/validate the cherry-pick set for a release branch.
|
||||
---
|
||||
|
||||
# Chrome Release → Validated Backport PR
|
||||
|
||||
Input: `$ARGUMENTS` = `<release-branch> <chrome-releases-blog-url>` (e.g. `41-x-y https://chromereleases.googleblog.com/2026/04/stable-channel-update-for-desktop_15.html`). Ask if either is missing.
|
||||
|
||||
The flow is **local-first**: nothing is pushed until every patch applies via `e sync --3` and passes `lint --patches`.
|
||||
|
||||
## 1. Map CVE → bug → fix CL
|
||||
|
||||
Run `/chrome-release-cls <blog-url>` (or its inline procedure) to produce `/tmp/cve_bugs.txt` (`CVE|bug|severity|desc`) and a per-bug canonical fix CL. For each CL also note `repo` (path under `src/`: `.`, `v8`, `third_party/{skia,angle,pdfium,dawn}`, `third_party/libaom/source/libaom`) and `gerrit-host`.
|
||||
|
||||
**Prefer the target-milestone merge CL** if one exists (e.g. on `41-x-y` ≈ M146, prefer the `[M146]` cherry-pick over the main CL) — it's already rebased and far less likely to conflict. Find it via `git log --all --grep` on the Change-Id, or Gerrit `?q=bug:<n>`. If Chrome did *not* merge a fix to the target milestone, that's a strong signal the vulnerable code doesn't exist there — flag it for skip rather than forcing a port.
|
||||
|
||||
## 2. Prepare a synced worktree
|
||||
|
||||
Reuse `bp-<NN>` from `e show configs` if present, else `e worktree add bp-<NN> ~/src/electron-bp-<NN> --source <current> --no-sync`.
|
||||
|
||||
```bash
|
||||
cd <root>/src/electron
|
||||
git fetch origin <branch>
|
||||
git checkout -B security-backport/<branch>/<short-date> origin/<branch>
|
||||
e use bp-<NN>
|
||||
e sync 2>&1 | tee /tmp/bp_sync.log
|
||||
```
|
||||
|
||||
If sync fails with `NotADirectoryError: '<root>/src/.git/objects/info/alternates'`, remove `GIT_CACHE_PATH` from the bp config's `env` and retry.
|
||||
|
||||
## 3. Verify IN-TREE vs NEEDS-BACKPORT
|
||||
|
||||
For each bug, three checks against the **synced** repo:
|
||||
|
||||
1. `git -C "$repo" log HEAD --since='1 year ago' -E --grep="\b${bug}\b" --format='%h %s'`
|
||||
2. Fetch Change-Id from Gerrit, then `git log HEAD --grep="^Change-Id: ${cid}$"`
|
||||
3. `grep -rlE "(\b${bug}\b|${cid})" <root>/src/electron/patches/`
|
||||
|
||||
Any hit ⇒ IN-TREE. All empty ⇒ NEEDS-BACKPORT.
|
||||
|
||||
For each NEEDS-BACKPORT CL, also fetch its file list (`/changes/<proj>~<cl>/revisions/current/files`) and **skip** if every file is under `chrome/browser/`, `chrome/android/`, `ios/`, or `components/**/android/` — Electron doesn't compile those.
|
||||
|
||||
Report the table now (`CVE | Sev | Bug | Component | Verdict | CL`) and the proposed backport set; get user sign-off before continuing.
|
||||
|
||||
## 4. Write patches locally (no push yet)
|
||||
|
||||
For each backport CL, fetch the raw patch and write it into `patches/<dir>/`:
|
||||
|
||||
```bash
|
||||
curl -s "https://${host}.googlesource.com/changes/${proj//\//%2F}~${cl}/revisions/current/patch" \
|
||||
| base64 -d > "patches/${dir}/cherry-pick-${short}.patch"
|
||||
echo "cherry-pick-${short}.patch" >> "patches/${dir}/.patches"
|
||||
```
|
||||
|
||||
For repos with no Gerrit host `e cherry-pick` supports (e.g. **libaom** on aomedia), instead `git cherry-pick` the upstream commits onto the synced sub-repo HEAD and `git format-patch` the result.
|
||||
|
||||
For any newly-created `patches/<dir>/`, append to `patches/config.json` **preserving the compact one-line-per-entry style**:
|
||||
|
||||
```json
|
||||
{ "patch_dir": "src/electron/patches/<dir>", "repo": "src/third_party/<dir-or-nested-path>" }
|
||||
```
|
||||
|
||||
## 5. Validate with `e sync --3`
|
||||
|
||||
```bash
|
||||
e sync --3 2>&1 | tee /tmp/bp_sync3.log
|
||||
```
|
||||
|
||||
On `Patch failed at NNNN <subject>`:
|
||||
|
||||
- `cd` into the failing repo, inspect `git diff` for conflict markers.
|
||||
- **Test-only files** (e.g. `web_tests/VirtualTestSuites`, `*_unittest.cc` context drift): take ours (`git checkout --ours -- <file>`) if the security-relevant hunks merged cleanly.
|
||||
- **Substantive code conflicts**: check whether a target-milestone merge CL exists and swap to it. If none exists upstream and the surrounding code is structurally different, **drop the patch** (delete the file, remove from `.patches` and `config.json`) and note it for a separate manual-port PR — do not improvise security-fix semantics.
|
||||
- After resolving: `git add <files> && git -c commit.gpgsign=false am --continue`, then `e patches <repo>` to export the resolved patch, then re-run `e sync --3`. Repeat until clean.
|
||||
|
||||
## 6. Export → lint → re-apply loop
|
||||
|
||||
```bash
|
||||
e patches all
|
||||
node script/lint.js --patches # must exit 0
|
||||
```
|
||||
|
||||
If lint reports findings (typically trailing whitespace on `+` content lines), fixing them **changes the bytes the patch writes**, which invalidates the `index <old>..<new>` blob hashes that `e patches` baked in. Hand-editing a `.patch` and pushing it as-is will pass lint locally but fail CI's Apply Patches re-export check with a one-line `index` hash diff.
|
||||
|
||||
So whenever lint (or you) modifies any `.patch` file after export, round-trip once more:
|
||||
|
||||
```bash
|
||||
# fix the lint findings in patches/**/*.patch, then:
|
||||
e sync # re-apply the edited patches (no --3 needed; they applied cleanly last time)
|
||||
e patches all # re-export so index blob hashes match the edited content
|
||||
node script/lint.js --patches # must now exit 0
|
||||
git diff --quiet -- patches/ || { echo "patches changed again — repeat the loop"; }
|
||||
```
|
||||
|
||||
Repeat until `lint --patches` exits 0 **and** `git diff -- patches/` is empty after the final `e patches all`. Only then is the patch set CI-stable.
|
||||
|
||||
## 7. Commit, push, PR
|
||||
|
||||
```bash
|
||||
git add patches/
|
||||
git commit -m "chore: cherry-pick <N> changes from <dirs>"
|
||||
git push origin HEAD
|
||||
gh pr create --repo electron/electron --base <branch> --head <this-branch> \
|
||||
--title "chore: cherry-pick <N> changes from <dirs>" \
|
||||
--label "<branch>" --label backport-check-skip --label semver/patch --label "security 🔒" \
|
||||
--body-file /tmp/pr_body.md
|
||||
```
|
||||
|
||||
PR body format:
|
||||
|
||||
```markdown
|
||||
Backports the following changes:
|
||||
|
||||
* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject> ([<bug>](https://crbug.com/<bug>), CVE-YYYY-NNNN)
|
||||
* ...
|
||||
|
||||
Notes: Security: backported fixes for CVE-YYYY-NNNN, CVE-YYYY-NNNN, ....
|
||||
```
|
||||
|
||||
Short commit links to the **Gerrit CL**; bug links to `crbug.com`; CVE comes from the blog mapping (the patch's own `Bug:` footer may differ); `Notes:` is the last line. Mention any dropped patches (with reason) above the `Notes:` line.
|
||||
|
||||
Restore `e use <previous>` when done.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: electron-node-upgrade
|
||||
description: Guide for performing Node.js version upgrades in the Electron project. Use when working on the roller/node/main branch to fix patch conflicts during `e sync --3`. Covers the patch application workflow, conflict resolution, analyzing upstream Node.js changes, building, running the Node.js test suite, and proper commit formatting for patch fixes.
|
||||
description: Guide for performing Node.js version upgrades in the Electron project. Use when working on the roller/node/main branch to fix patch conflicts during `e sync --3`. Covers the patch application workflow, conflict resolution, analyzing upstream Node.js changes, and proper commit formatting for patch fixes.
|
||||
---
|
||||
|
||||
# Electron Node.js Upgrade: Phase One
|
||||
@@ -174,127 +174,10 @@ When the error is in Electron's own source code:
|
||||
1. Edit files directly in the electron repo
|
||||
2. Commit directly (no patch export needed)
|
||||
|
||||
# Electron Node.js Upgrade: Phase Three
|
||||
|
||||
## Summary
|
||||
|
||||
Run the Node.js test suite via `script/node-spec-runner.js`, fix failing tests, and commit fixes until all tests pass. Certain tests are permanently disabled (listed in `script/node-disabled-tests.json`) and should not be run.
|
||||
|
||||
Run Phase Three immediately after Phase Two is complete.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
Phase Three is complete when:
|
||||
- `node script/node-spec-runner.js --default` exits with zero failures
|
||||
- All changes are committed per the commit guidelines
|
||||
|
||||
Do not stop until these criteria are met.
|
||||
|
||||
## Context
|
||||
|
||||
Electron runs a subset of Node.js's upstream test suite using a custom runner (`script/node-spec-runner.js`). Tests are executed with the built Electron binary via `ELECTRON_RUN_AS_NODE=true`. Many tests need adaptation because Electron uses BoringSSL (not OpenSSL) and Chromium's V8 (which may differ from Node.js's bundled V8).
|
||||
|
||||
**Key files:**
|
||||
- `script/node-spec-runner.js` — Test runner script
|
||||
- `script/node-disabled-tests.json` — Permanently disabled tests (do not try to fix these)
|
||||
- `../third_party/electron_node/test/` — Node.js test files (where patches apply)
|
||||
- `patches/node/fix_crypto_tests_to_run_with_bssl.patch` — BoringSSL crypto test adaptations
|
||||
- `patches/node/test_formally_mark_some_tests_as_flaky.patch` — Flaky test list
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Run `node script/node-spec-runner.js --default` from the electron repo
|
||||
2. If all tests pass → Phase Three is complete
|
||||
3. If tests fail:
|
||||
- Identify the failing test file(s) from the output
|
||||
- Analyze each failure (see "Common Failure Patterns" below)
|
||||
- Fix the test in `../third_party/electron_node/test/...`
|
||||
- Re-run the specific failing test to verify: `node script/node-spec-runner.js {test-path}`
|
||||
- The test path is relative to the node `test/` directory, e.g. `test/parallel/test-crypto-key-objects-raw.js`
|
||||
- Do NOT use `--default` when running specific tests — it adds the full suite flags
|
||||
- Do NOT run tests directly with `ELECTRON_RUN_AS_NODE` — the runner handles environment setup (e.g. temporarily switching `package.json` from ESM to CommonJS)
|
||||
- Commit the fix using the fixup workflow and commit guidelines
|
||||
- Return to step 1
|
||||
|
||||
## Commands Reference
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `node script/node-spec-runner.js --default` | Run full Node.js test suite |
|
||||
| `node script/node-spec-runner.js test/parallel/test-foo.js` | Run a single test |
|
||||
| `NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs` | Regenerate snapshot for a snapshot-based test |
|
||||
|
||||
## Common Failure Patterns
|
||||
|
||||
### BoringSSL incompatibilities
|
||||
|
||||
Electron uses BoringSSL (via Chromium) instead of OpenSSL. Many crypto features are missing or behave differently:
|
||||
|
||||
| Unsupported in BoringSSL | Guard pattern |
|
||||
|--------------------------|---------------|
|
||||
| ChaCha20-Poly1305 | `if (!process.features.openssl_is_boringssl)` |
|
||||
| AES-CCM (aes-128-ccm, aes-256-ccm) | `if (ciphers.includes('aes-128-ccm'))` |
|
||||
| AES-KW (key wrapping) | `if (!process.features.openssl_is_boringssl)` |
|
||||
| DSA keys | `if (!process.features.openssl_is_boringssl)` |
|
||||
| Ed448 / X448 curves | `if (!process.features.openssl_is_boringssl)` |
|
||||
| DH key PEM loading | `if (!process.features.openssl_is_boringssl)` |
|
||||
| PQC algorithms (ML-KEM, ML-DSA, SLH-DSA) | `if (hasOpenSSL(3, 5))` (already guards these) |
|
||||
|
||||
When guarding tests, prefer checking cipher availability (`ciphers.includes(algo)`) over blanket BoringSSL checks where possible, as it's more precise and self-documenting.
|
||||
|
||||
New upstream tests that exercise these features will need guards added to the `fix_crypto_tests_to_run_with_bssl` patch.
|
||||
|
||||
### Snapshot test mismatches
|
||||
|
||||
Some tests compare output against committed `.snapshot` files using `assert.strictEqual` — these are NOT wildcard comparisons. When Chromium's V8 produces different output (e.g. different stack traces due to V8 enhancements), the snapshot must be regenerated:
|
||||
|
||||
```bash
|
||||
NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs
|
||||
```
|
||||
|
||||
Then inspect the diff to verify the changes are expected, and commit the updated snapshot into the appropriate patch.
|
||||
|
||||
### V8 behavioral differences
|
||||
|
||||
Chromium's V8 may be ahead of Node.js's bundled V8. This can cause:
|
||||
- Different stack trace formats (e.g. thenable async stack frames)
|
||||
- Different error messages
|
||||
- Features available in Chromium V8 that aren't in stock Node.js V8 (or vice versa)
|
||||
|
||||
## Two Types of Test Fixes
|
||||
|
||||
### A. Patch Fixes (most common for test failures)
|
||||
|
||||
Most test fixes go into existing patches in `patches/node/`. Use the fixup workflow:
|
||||
|
||||
1. Edit the test file in `../third_party/electron_node/test/...`
|
||||
2. Find the relevant patch commit: `git log --oneline | grep -i "keyword"`
|
||||
- Crypto/BoringSSL tests → `fix crypto tests to run with bssl`
|
||||
- Snapshot tests → the specific snapshot patch (e.g. `test: accomodate V8 thenable`)
|
||||
- Flaky tests → `test: formally mark some tests as flaky`
|
||||
3. Create a fixup commit:
|
||||
```bash
|
||||
cd ../third_party/electron_node
|
||||
git add test/path/to/test.js
|
||||
git commit --fixup=<patch-commit-hash>
|
||||
GIT_SEQUENCE_EDITOR=: git rebase --autosquash --autostash -i <commit>^
|
||||
```
|
||||
4. Export: `e patches node`
|
||||
5. **Read `references/phase-three-commit-guidelines.md` NOW**, then commit the updated patch file.
|
||||
|
||||
### B. New Patches (rare)
|
||||
|
||||
Only create a new patch when the fix doesn't belong in any existing patch. The new patch commit in `../third_party/electron_node` must include a description explaining why the patch exists and when it can be removed — the lint check enforces this.
|
||||
|
||||
## Adding to Disabled Tests
|
||||
|
||||
Only add a test to `script/node-disabled-tests.json` as a **last resort** — when the test is fundamentally incompatible with Electron's architecture (not just a BoringSSL difference that can be guarded). Tests disabled here are completely skipped and never run.
|
||||
|
||||
# Critical: Read Before Committing
|
||||
|
||||
- Before ANY Phase One commits: Read `references/phase-one-commit-guidelines.md`
|
||||
- Before ANY Phase Two commits: Read `references/phase-two-commit-guidelines.md`
|
||||
- Before ANY Phase Three commits: Read `references/phase-three-commit-guidelines.md`
|
||||
|
||||
# High-Churn Patches
|
||||
|
||||
@@ -318,6 +201,5 @@ This skill has additional reference files in `references/`:
|
||||
- patch-analysis.md - How to analyze patch failures
|
||||
- phase-one-commit-guidelines.md - Commit format for Phase One
|
||||
- phase-two-commit-guidelines.md - Commit format for Phase Two
|
||||
- phase-three-commit-guidelines.md - Commit format for Phase Three
|
||||
|
||||
Read these when referenced in the workflow steps.
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
# Phase Three Commit Guidelines
|
||||
|
||||
Only follow these instructions if there are uncommitted changes after fixing a test failure during Phase Three.
|
||||
|
||||
Ignore other instructions about making commit messages, our guidelines are CRITICALLY IMPORTANT and must be followed.
|
||||
|
||||
## Commit Message Style
|
||||
|
||||
**Titles** follow the 60/80-character guideline: simple changes fit within 60 characters, otherwise the limit is 80 characters.
|
||||
|
||||
Always include a `Co-Authored-By` trailer identifying the AI model that assisted (e.g., `Co-Authored-By: <AI model attribution>`).
|
||||
|
||||
## Commit Types
|
||||
|
||||
### Patch updates (most test fixes)
|
||||
|
||||
Test fixes go into existing patches via the fixup workflow. Use `fix(patch):` prefix with a descriptive topic:
|
||||
|
||||
```
|
||||
fix(patch): {topic headline}
|
||||
|
||||
Ref: {Node.js commit or issue link}
|
||||
|
||||
Co-Authored-By: <AI model attribution>
|
||||
```
|
||||
|
||||
Examples:
|
||||
- `fix(patch): guard DH key test for BoringSSL`
|
||||
- `fix(patch): adapt new crypto tests for BoringSSL`
|
||||
- `fix(patch): correct thenable snapshot for Chromium V8`
|
||||
- `fix(patch): skip AES-KW tests with BoringSSL`
|
||||
|
||||
Group related test fixes into a single commit when they address the same root cause (e.g., multiple crypto tests all needing BoringSSL guards for the same missing cipher). Don't create one commit per test file if they share the same fix pattern.
|
||||
|
||||
### Snapshot regeneration
|
||||
|
||||
When a snapshot test fails because Chromium's V8 produces different output, regenerate it:
|
||||
|
||||
```bash
|
||||
NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs
|
||||
```
|
||||
|
||||
Then commit the updated snapshot patch with a title describing what changed:
|
||||
|
||||
```
|
||||
fix(patch): correct {name} snapshot for Chromium V8
|
||||
|
||||
Ref: {V8 CL or issue link if known}
|
||||
|
||||
Co-Authored-By: <AI model attribution>
|
||||
```
|
||||
|
||||
### Trivial patch updates
|
||||
|
||||
After any patch modification, check for dependent patches that only have index/hunk header changes:
|
||||
|
||||
```bash
|
||||
git status
|
||||
# If other .patch files show as modified with only trivial changes:
|
||||
git add patches/
|
||||
git commit -m "chore: update patches (trivial only)"
|
||||
```
|
||||
|
||||
## Finding References
|
||||
|
||||
For BoringSSL-related test fixes, the reference is typically the upstream Node.js PR that added the new test:
|
||||
|
||||
```bash
|
||||
cd ../third_party/electron_node
|
||||
git log --oneline -5 -- test/parallel/test-crypto-foo.js
|
||||
git log -1 <commit> --format="%B" | grep "PR-URL"
|
||||
```
|
||||
|
||||
For V8 behavioral differences, reference the Chromium CL:
|
||||
|
||||
```
|
||||
Ref: https://chromium-review.googlesource.com/c/v8/v8/+/NNNNNNN
|
||||
```
|
||||
|
||||
If no reference found after searching: `Ref: Unable to locate reference`
|
||||
@@ -35,7 +35,7 @@
|
||||
"ms-vscode.cpptools",
|
||||
"mutantdino.resourcemonitor",
|
||||
"dsanders11.vscode-electron-build-tools",
|
||||
"oxc.oxc-vscode",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"shakram02.bash-beautify",
|
||||
"marshallofsound.gnls-electron"
|
||||
],
|
||||
|
||||
79
.eslintrc.json
Normal file
79
.eslintrc.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"no-var": "error",
|
||||
"no-unused-vars": "off",
|
||||
"guard-for-in": "error",
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true
|
||||
}],
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"n/no-callback-literal": "off",
|
||||
"import/newline-after-import": "error",
|
||||
"import/order": ["error", {
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
},
|
||||
"newlines-between": "always",
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "@electron/internal/**",
|
||||
"group": "external",
|
||||
"position": "before"
|
||||
},
|
||||
{
|
||||
"pattern": "@electron/**",
|
||||
"group": "external",
|
||||
"position": "before"
|
||||
},
|
||||
{
|
||||
"pattern": "{electron,electron/**}",
|
||||
"group": "external",
|
||||
"position": "before"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": [],
|
||||
"distinctGroup": true,
|
||||
"groups": [
|
||||
"external",
|
||||
"builtin",
|
||||
["sibling", "parent"],
|
||||
"index",
|
||||
"type"
|
||||
]
|
||||
}]
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.ts",
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"no-redeclare": "off",
|
||||
"@typescript-eslint/no-redeclare": ["error"],
|
||||
"no-use-before-define": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.d.ts",
|
||||
"rules": {
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -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
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -39,8 +39,8 @@ body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System Version
|
||||
description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a and include whether you use Wayland or X11.
|
||||
placeholder: "e.g. Windows 11 25H2, macOS Tahoe 26.4.1, or Ubuntu 26.04 (Wayland)"
|
||||
description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a.
|
||||
placeholder: "e.g. Windows 10 version 1909, macOS Catalina 10.15.7, or Ubuntu 20.04"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/maintainer_issue.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/maintainer_issue.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Maintainer Issue (not for public use)
|
||||
description: Only to be created by Electron maintainers
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Confirmation
|
||||
options:
|
||||
- label: I am a [maintainer](https://github.com/orgs/electron/people) of the Electron project. (If not, please create a [different issue type](https://github.com/electron/electron/issues/new/).)
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
validations:
|
||||
required: true
|
||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -5,18 +5,13 @@ 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
|
||||
|
||||
Using a coding agent / AI? Read the policy: https://github.com/electron/governance/blob/main/policy/ai.md
|
||||
|
||||
NOTE: PRs submitted that do not follow this template will be automatically closed.
|
||||
-->
|
||||
|
||||
#### Checklist
|
||||
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||
|
||||
- [ ] I have built and tested this change
|
||||
- [ ] I have filled out the PR description
|
||||
- [ ] [I have reviewed and verified the changes](https://github.com/electron/governance/blob/main/policy/ai.md)
|
||||
- [ ] PR description included
|
||||
- [ ] I have built and tested this PR
|
||||
- [ ] `npm test` passes
|
||||
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
|
||||
- [ ] relevant API documentation, tutorials, and examples are updated and follow the [documentation style guide](https://github.com/electron/electron/blob/main/docs/development/style-guide.md)
|
||||
|
||||
59
.github/actions/build-electron/action.yml
vendored
59
.github/actions/build-electron/action.yml
vendored
@@ -40,29 +40,13 @@ runs:
|
||||
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
|
||||
- name: Set GN_EXTRA_ARGS for Windows
|
||||
shell: bash
|
||||
if: ${{ inputs.target-platform == 'win' }}
|
||||
if: ${{inputs.target-arch != 'x64' && inputs.target-platform == 'win' }}
|
||||
run: |
|
||||
# Resolve .obj paths to absolute in linker response files to work
|
||||
# around BindFlt concurrency bug in Windows containers.
|
||||
# https://github.com/microsoft/Windows-Containers/issues/635
|
||||
GN_APPENDED_ARGS="$GN_EXTRA_ARGS win_abs_link_wrapper=\"//electron/build/win/abs_link_wrapper.py\""
|
||||
if [ "${{ inputs.target-arch }}" != "x64" ]; then
|
||||
GN_APPENDED_ARGS="$GN_APPENDED_ARGS target_cpu=\"${{ inputs.target-arch }}\""
|
||||
fi
|
||||
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"${{ inputs.target-arch }}\""
|
||||
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
|
||||
- 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
|
||||
@@ -88,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
|
||||
@@ -113,28 +92,19 @@ runs:
|
||||
} else {
|
||||
e build --target electron:testing_build
|
||||
}
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "e build failed with exit code $LASTEXITCODE"
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
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: |
|
||||
@@ -332,10 +302,3 @@ runs:
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
24
.github/actions/build-image-sha/action.yml
vendored
24
.github/actions/build-image-sha/action.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: 'Build Image SHA'
|
||||
description: 'Single source of truth for the ghcr.io/electron/build image SHA'
|
||||
inputs:
|
||||
override:
|
||||
description: 'Optional override SHA (e.g. from a workflow_dispatch input)'
|
||||
required: false
|
||||
default: ''
|
||||
outputs:
|
||||
build-image-sha:
|
||||
description: 'The electron/build image SHA to use'
|
||||
value: ${{ steps.set.outputs.build-image-sha }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- id: set
|
||||
shell: bash
|
||||
env:
|
||||
OVERRIDE: ${{ inputs.override }}
|
||||
run: |
|
||||
if [ -n "$OVERRIDE" ]; then
|
||||
echo "build-image-sha=$OVERRIDE" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "build-image-sha=daad061f4b99a0ae1c841be4aa09188280a9c8a4" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
21
.github/actions/install-dependencies/action.yml
vendored
21
.github/actions/install-dependencies/action.yml
vendored
@@ -21,28 +21,11 @@ runs:
|
||||
if [ "$TARGET_ARCH" = "x86" ]; then
|
||||
export npm_config_arch="ia32"
|
||||
fi
|
||||
ARCH=$(uname -m)
|
||||
node script/yarn.js install --immutable --mode=skip-build
|
||||
# if running on linux arm skip yarn Builds
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" = "armv7l" ]; then
|
||||
echo "Skipping yarn build on linux arm"
|
||||
node script/yarn.js install --immutable --mode=skip-build
|
||||
else
|
||||
# Pre-seed the node-gyp header cache so the parallel native-addon
|
||||
# builds below don't race on a cold cache. Linux build containers
|
||||
# already ship a warm cache (electron/build-images#68), so only do
|
||||
# this on macOS / Windows runners.
|
||||
if [ "$(uname -s)" != "Linux" ]; then
|
||||
for i in 1 2 3; do
|
||||
if node node_modules/node-gyp/bin/node-gyp.js install; then
|
||||
break
|
||||
fi
|
||||
if [ "$i" = "3" ]; then
|
||||
echo "node-gyp header pre-seed failed after 3 attempts" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "node-gyp header pre-seed failed (attempt $i), retrying in 5s..." >&2
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
node script/yarn.js install --immutable
|
||||
fi
|
||||
|
||||
22
.github/problem-matchers/eslint-stylish.json
vendored
Normal file
22
.github/problem-matchers/eslint-stylish.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "eslint-stylish",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^\\s*([^\\s].*)$",
|
||||
"file": 1
|
||||
},
|
||||
{
|
||||
"regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$",
|
||||
"line": 1,
|
||||
"column": 2,
|
||||
"severity": 3,
|
||||
"message": 4,
|
||||
"code": 5,
|
||||
"loop": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
From aab86e682d6f40e110700f36c9c37f6655fb14f1 Mon Sep 17 00:00:00 2001
|
||||
From 85b561ea4dbc76ba98af020b970f3aa6b20fdb9e Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sam@electronjs.org>
|
||||
Date: Wed, 8 Apr 2026 23:24:15 -0700
|
||||
Subject: [PATCH] siso: reuse the outer *os.File for chunked ReadAt in
|
||||
@@ -25,10 +25,10 @@ it; see microsoft/Windows-Containers#<tbd>.
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/siso/toolsupport/ninjautil/file_parser.go b/siso/toolsupport/ninjautil/file_parser.go
|
||||
index f8c7eff..75b1d6e 100644
|
||||
index 8c18d084..63116662 100644
|
||||
--- a/siso/toolsupport/ninjautil/file_parser.go
|
||||
+++ b/siso/toolsupport/ninjautil/file_parser.go
|
||||
@@ -128,13 +128,6 @@ func (p *fileParser) readFile(ctx context.Context, fname string) ([]byte, error)
|
||||
@@ -111,13 +111,6 @@ func (p *fileParser) readFile(ctx context.Context, fname string) ([]byte, error)
|
||||
eg.Go(func() error {
|
||||
p.sema <- struct{}{}
|
||||
defer func() { <-p.sema }()
|
||||
@@ -43,5 +43,5 @@ index f8c7eff..75b1d6e 100644
|
||||
n, err := f.ReadAt(chunkBuf, pos)
|
||||
if err != nil {
|
||||
--
|
||||
2.52.0
|
||||
2.53.0
|
||||
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
From 1786f2266cba6a66343e5af2b724214930c8292f Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sam@electronjs.org>
|
||||
Date: Wed, 22 Apr 2026 16:27:51 -0700
|
||||
Subject: [PATCH] siso: retry transient ERROR_INVALID_PARAMETER when opening
|
||||
ninja files on Windows
|
||||
|
||||
ManifestParser.Load fans out across all subninja files (~90k in a
|
||||
Chromium build) at NumCPU parallelism. On Windows builders where out/
|
||||
is served through a filesystem filter driver (e.g. bindflt/wcifs for
|
||||
container bind mounts), CreateFileW can intermittently return
|
||||
ERROR_INVALID_PARAMETER under this concurrent open burst. The previous
|
||||
patch removes the redundant per-chunk re-open, but the single remaining
|
||||
open per file can still hit the race; without a retry a single transient
|
||||
failure aborts the entire manifest load.
|
||||
|
||||
Wrap the remaining os.Open call in readFile in a small Windows-only
|
||||
retry for ERROR_INVALID_PARAMETER (5 attempts, 5-80ms backoff). Each
|
||||
retry is logged via clog.Warningf and also written to stderr so it is
|
||||
visible in CI step output where glog warnings are file-only by default.
|
||||
Other platforms keep the direct os.Open path.
|
||||
---
|
||||
siso/toolsupport/ninjautil/file_parser.go | 3 +-
|
||||
siso/toolsupport/ninjautil/openfile_other.go | 18 +++++++
|
||||
.../toolsupport/ninjautil/openfile_windows.go | 50 +++++++++++++++++++
|
||||
3 files changed, 69 insertions(+), 2 deletions(-)
|
||||
create mode 100644 siso/toolsupport/ninjautil/openfile_other.go
|
||||
create mode 100644 siso/toolsupport/ninjautil/openfile_windows.go
|
||||
|
||||
diff --git a/siso/toolsupport/ninjautil/file_parser.go b/siso/toolsupport/ninjautil/file_parser.go
|
||||
index 75b1d6e..4a3e639 100644
|
||||
--- a/siso/toolsupport/ninjautil/file_parser.go
|
||||
+++ b/siso/toolsupport/ninjautil/file_parser.go
|
||||
@@ -7,7 +7,6 @@ package ninjautil
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
- "os"
|
||||
"path/filepath"
|
||||
"runtime/trace"
|
||||
"sync"
|
||||
@@ -108,7 +107,7 @@ func (p *fileParser) parseFile(ctx context.Context, fname string) error {
|
||||
// readFile reads a file of fname in parallel.
|
||||
func (p *fileParser) readFile(ctx context.Context, fname string) ([]byte, error) {
|
||||
defer trace.StartRegion(ctx, "ninja.read").End()
|
||||
- f, err := os.Open(fname)
|
||||
+ f, err := openFile(ctx, fname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diff --git a/siso/toolsupport/ninjautil/openfile_other.go b/siso/toolsupport/ninjautil/openfile_other.go
|
||||
new file mode 100644
|
||||
index 0000000..9fca690
|
||||
--- /dev/null
|
||||
+++ b/siso/toolsupport/ninjautil/openfile_other.go
|
||||
@@ -0,0 +1,18 @@
|
||||
+// Copyright 2026 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+//go:build !windows
|
||||
+
|
||||
+package ninjautil
|
||||
+
|
||||
+import (
|
||||
+ "context"
|
||||
+ "os"
|
||||
+)
|
||||
+
|
||||
+// openFile opens fname for reading.
|
||||
+// See openfile_windows.go for the Windows variant with transient-error retry.
|
||||
+func openFile(ctx context.Context, fname string) (*os.File, error) {
|
||||
+ return os.Open(fname)
|
||||
+}
|
||||
diff --git a/siso/toolsupport/ninjautil/openfile_windows.go b/siso/toolsupport/ninjautil/openfile_windows.go
|
||||
new file mode 100644
|
||||
index 0000000..f9d8e9d
|
||||
--- /dev/null
|
||||
+++ b/siso/toolsupport/ninjautil/openfile_windows.go
|
||||
@@ -0,0 +1,50 @@
|
||||
+// Copyright 2026 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+//go:build windows
|
||||
+
|
||||
+package ninjautil
|
||||
+
|
||||
+import (
|
||||
+ "context"
|
||||
+ "errors"
|
||||
+ "fmt"
|
||||
+ "os"
|
||||
+ "time"
|
||||
+
|
||||
+ "golang.org/x/sys/windows"
|
||||
+
|
||||
+ "go.chromium.org/build/siso/o11y/clog"
|
||||
+)
|
||||
+
|
||||
+// openFile opens fname for reading, retrying transient
|
||||
+// ERROR_INVALID_PARAMETER failures.
|
||||
+//
|
||||
+// On Windows, CreateFileW can intermittently return
|
||||
+// ERROR_INVALID_PARAMETER when the target lives behind a filesystem
|
||||
+// filter driver (e.g. bindflt/wcifs for container bind mounts) under
|
||||
+// highly concurrent opens. loadFile fans out across ~90k subninja
|
||||
+// files at NumCPU parallelism, so a single transient failure would
|
||||
+// otherwise abort the whole manifest load.
|
||||
+func openFile(ctx context.Context, fname string) (*os.File, error) {
|
||||
+ const maxAttempts = 5
|
||||
+ delay := 5 * time.Millisecond
|
||||
+ for i := 0; ; i++ {
|
||||
+ f, err := os.Open(fname)
|
||||
+ if err == nil {
|
||||
+ return f, nil
|
||||
+ }
|
||||
+ if i+1 >= maxAttempts || !errors.Is(err, windows.ERROR_INVALID_PARAMETER) {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ clog.Warningf(ctx, "open %s: %v; retrying (%d/%d) after %s", fname, err, i+1, maxAttempts, delay)
|
||||
+ fmt.Fprintf(os.Stderr, "siso: open %s: %v; retrying (%d/%d) after %s\n", fname, err, i+1, maxAttempts, delay)
|
||||
+ select {
|
||||
+ case <-time.After(delay):
|
||||
+ case <-ctx.Done():
|
||||
+ return nil, context.Cause(ctx)
|
||||
+ }
|
||||
+ delay *= 2
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
21
.github/workflows/apply-patches.yml
vendored
21
.github/workflows/apply-patches.yml
vendored
@@ -18,8 +18,6 @@ jobs:
|
||||
pull-requests: read
|
||||
outputs:
|
||||
has-patches: ${{ steps.filter.outputs.patches }}
|
||||
has-siso-patches: ${{ steps.filter.outputs.siso-patches }}
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
with:
|
||||
@@ -28,19 +26,13 @@ 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: |
|
||||
patches:
|
||||
- DEPS
|
||||
- 'patches/**'
|
||||
siso-patches:
|
||||
- DEPS
|
||||
- '.github/siso-patches/**'
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
|
||||
apply-patches:
|
||||
needs: setup
|
||||
@@ -49,7 +41,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
@@ -81,16 +73,9 @@ jobs:
|
||||
target-platform: linux
|
||||
- name: Upload Patch Conflict Fix
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: update-patches
|
||||
path: patches/update-patches.patch
|
||||
if-no-files-found: ignore
|
||||
archive: false
|
||||
|
||||
build-siso:
|
||||
needs: setup
|
||||
if: ${{ needs.setup.outputs.has-siso-patches == 'true' }}
|
||||
uses: ./.github/workflows/pipeline-segment-build-siso-windows.yml
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
4
.github/workflows/archaeologist-dig.yml
vendored
4
.github/workflows/archaeologist-dig.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js/npm
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
||||
with:
|
||||
node-version: 24.12.x
|
||||
- name: Setting Up Dig Site
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
sha-file: .dig-old
|
||||
filename: electron.old.d.ts
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
|
||||
with:
|
||||
name: artifacts
|
||||
path: electron/artifacts
|
||||
|
||||
9
.github/workflows/audit-branch-ci.yml
vendored
9
.github/workflows/audit-branch-ci.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: 22.17.x
|
||||
- name: Sparse checkout repository
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
.github
|
||||
.yarn
|
||||
- run: yarn workspaces focus @electron/gha-workflows
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
id: audit-errors
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -86,9 +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") &&
|
||||
!message.startsWith("The operation was canceled") &&
|
||||
!message.startsWith("Canceling since") &&
|
||||
!/Unable to make request/.test(message) &&
|
||||
!/The requested URL returned error/.test(message),
|
||||
)
|
||||
@@ -157,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@03ea5433c137af7c0495bc0cad1af10403fc800c # v3.0.2
|
||||
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
|
||||
with:
|
||||
payload: |
|
||||
link: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||
|
||||
83
.github/workflows/branch-created.yml
vendored
83
.github/workflows/branch-created.yml
vendored
@@ -31,8 +31,8 @@ jobs:
|
||||
else
|
||||
echo "Not a release branch: $BRANCH_NAME"
|
||||
fi
|
||||
- name: Determine Next Unsupported Major Version
|
||||
id: determine-next-unsupported-major
|
||||
- name: Determine Unsupported Major Version
|
||||
id: determine-unsupported-major
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
env:
|
||||
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
@@ -50,27 +50,26 @@ jobs:
|
||||
|
||||
# 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" '
|
||||
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
|
||||
if [[ -z "$UNSUPPORTED_MAJOR" || "$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"
|
||||
echo "UNSUPPORTED_MAJOR=$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 }}
|
||||
UNSUPPORTED_MAJOR: ${{ steps.determine-unsupported-major.outputs.UNSUPPORTED_MAJOR }}
|
||||
run: |
|
||||
PREVIOUS_MAJOR=$((MAJOR - 1))
|
||||
UNSUPPORTED_MAJOR=$((NEXT_UNSUPPORTED_MAJOR - 1))
|
||||
|
||||
# Create new labels
|
||||
gh label create $MAJOR-x-y --color 8d9ee8 || true
|
||||
@@ -98,19 +97,19 @@ jobs:
|
||||
done
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Generate Release Project Board Metadata
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
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 }}
|
||||
UNSUPPORTED_MAJOR: ${{ steps.determine-unsupported-major.outputs.UNSUPPORTED_MAJOR }}
|
||||
SCHEDULE: ${{ steps.determine-unsupported-major.outputs.SCHEDULE }}
|
||||
with:
|
||||
script: |
|
||||
const schedule = JSON.parse(process.env.SCHEDULE)
|
||||
@@ -145,7 +144,7 @@ jobs:
|
||||
major,
|
||||
"next-major": nextMajor,
|
||||
"prev-major": prevMajor,
|
||||
"ending-support-major": parseInt(process.env.NEXT_UNSUPPORTED_MAJOR),
|
||||
"ending-support-major": parseInt(process.env.UNSUPPORTED_MAJOR),
|
||||
"beta-date": betaDate,
|
||||
"beta-prep-week": betaPrepWeek.toISOString().split('T')[0],
|
||||
"beta-prep-week-end": betaPrepWeekEnd.toISOString().split('T')[0],
|
||||
@@ -157,7 +156,7 @@ jobs:
|
||||
}))
|
||||
- name: Create Release Project Board
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/copy-project@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/copy-project@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
id: create-release-board
|
||||
with:
|
||||
drafts: true
|
||||
@@ -170,60 +169,6 @@ jobs:
|
||||
template-view: ${{ steps.generate-project-metadata.outputs.template-view }}
|
||||
title: ${{ steps.generate-project-metadata.outputs.major }}-x-y
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
- name: Randomly Assign Draft Issues to Release WG Members
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: dsanders11/project-actions/github-script@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
env:
|
||||
PROJECT_ID: ${{ steps.create-release-board.outputs.id }}
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
script: |
|
||||
const { data: members } = await github.rest.teams.listMembersInOrg({
|
||||
org: 'electron',
|
||||
team_slug: 'wg-releases',
|
||||
});
|
||||
|
||||
const excludedLogins = ['nikwen'];
|
||||
const memberLogins = new Set(members.map(m => m.login));
|
||||
for (const login of excludedLogins) {
|
||||
if (!memberLogins.has(login)) {
|
||||
core.warning(`Excluded member "${login}" is not in @electron/wg-releases`);
|
||||
}
|
||||
}
|
||||
|
||||
const eligible = members.filter(m => !excludedLogins.includes(m.login));
|
||||
|
||||
if (eligible.length === 0) {
|
||||
core.warning('No eligible members found in @electron/wg-releases team');
|
||||
return;
|
||||
}
|
||||
|
||||
const projectId = process.env.PROJECT_ID;
|
||||
const draftIssues = await actions.getDraftIssues(projectId);
|
||||
|
||||
if (draftIssues.length === 0) {
|
||||
core.info('No draft issues found in the project');
|
||||
return;
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle for uniform random assignment
|
||||
const shuffled = [...eligible];
|
||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
||||
}
|
||||
|
||||
// Assign draft issues round-robin across team members
|
||||
for (let i = 0; i < draftIssues.length; i++) {
|
||||
const member = shuffled[i % shuffled.length];
|
||||
const draftIssue = draftIssues[i];
|
||||
core.info(`Assigning "${draftIssue.content.title}" to ${member.login}`);
|
||||
await actions.editItem(projectId, draftIssue.content.id, {
|
||||
assignees: [member.login],
|
||||
});
|
||||
}
|
||||
|
||||
core.info(`Assigned ${draftIssues.length} draft issues to ${eligible.length} team members`);
|
||||
- name: Dump Release Project Board Contents
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
run: gh project item-list ${{ steps.create-release-board.outputs.number }} --owner electron --format json | jq
|
||||
@@ -231,7 +176,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@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/find-project@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
id: find-prev-release-board
|
||||
with:
|
||||
fail-if-project-not-found: false
|
||||
@@ -239,7 +184,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@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
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 }}
|
||||
|
||||
34
.github/workflows/build-git-cache.yml
vendored
34
.github/workflows/build-git-cache.yml
vendored
@@ -2,38 +2,25 @@ name: Build Git Cache
|
||||
# This workflow updates git cache on the cross-instance cache volumes
|
||||
# It runs daily at midnight.
|
||||
|
||||
on:
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
|
||||
build-git-cache-linux:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- name: Checkout Electron
|
||||
@@ -47,12 +34,12 @@ jobs:
|
||||
target-platform: linux
|
||||
|
||||
build-git-cache-windows:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
|
||||
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
|
||||
volumes:
|
||||
- /mnt/win-cache:/mnt/win-cache
|
||||
@@ -72,13 +59,14 @@ jobs:
|
||||
target-platform: win
|
||||
|
||||
build-git-cache-macos:
|
||||
# This job updates the same git cache as linux, so it needs to run after the linux one.
|
||||
needs: [setup, build-git-cache-linux]
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
# This job updates the same git cache as linux, so it needs to run after the linux one.
|
||||
needs: build-git-cache-linux
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
@@ -94,4 +82,4 @@ jobs:
|
||||
- name: Build Git Cache
|
||||
uses: ./src/electron/.github/actions/build-git-cache
|
||||
with:
|
||||
target-platform: macos
|
||||
target-platform: macos
|
||||
32
.github/workflows/build.yml
vendored
32
.github/workflows/build.yml
vendored
@@ -6,8 +6,8 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: ''
|
||||
required: false
|
||||
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
|
||||
required: true
|
||||
skip-macos:
|
||||
type: boolean
|
||||
description: 'Skip macOS builds'
|
||||
@@ -48,40 +48,39 @@ permissions: {}
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
outputs:
|
||||
docs: ${{ steps.filter.outputs.docs }}
|
||||
src: ${{ steps.filter.outputs.src }}
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
|
||||
docs-only: ${{ steps.set-output.outputs.docs-only }}
|
||||
steps:
|
||||
- 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: |
|
||||
docs:
|
||||
- 'docs/**'
|
||||
- '.claude/**'
|
||||
- README.md
|
||||
- SECURITY.md
|
||||
- CONTRIBUTING.md
|
||||
- CODE_OF_CONDUCT.md
|
||||
src:
|
||||
- '!{docs,.claude}/**'
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
with:
|
||||
override: ${{ inputs.build-image-sha }}
|
||||
- name: Set Docs Only
|
||||
- '!docs/**'
|
||||
- name: Set Outputs for Build Image SHA & Docs Only
|
||||
id: set-output
|
||||
run: |
|
||||
if [ -z "${{ inputs.build-image-sha }}" ]; then
|
||||
echo "build-image-sha=eac3529546ea8f3aa356d31e345715eef342233b" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
echo "docs-only=${{ steps.filter.outputs.docs == 'true' && steps.filter.outputs.src == 'false' }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Lint Jobs
|
||||
@@ -275,11 +274,10 @@ jobs:
|
||||
contents: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-tidy-and-test.yml
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
|
||||
needs: checkout-macos
|
||||
with:
|
||||
build-runs-on: macos-15-xlarge
|
||||
clang-tidy-runs-on: macos-15-large
|
||||
test-runs-on: macos-15
|
||||
target-platform: macos
|
||||
target-arch: arm64
|
||||
@@ -394,14 +392,12 @@ jobs:
|
||||
contents: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-tidy-and-test.yml
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
|
||||
needs: [checkout-windows, build-siso-windows]
|
||||
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
|
||||
with:
|
||||
build-runs-on: electron-arc-centralus-windows-amd64-16core
|
||||
clang-tidy-runs-on: electron-arc-centralus-linux-amd64-8core
|
||||
test-runs-on: windows-latest
|
||||
clang-tidy-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/win-cache:/mnt/win-cache"]}'
|
||||
target-platform: win
|
||||
target-arch: x64
|
||||
is-release: false
|
||||
|
||||
@@ -13,26 +13,13 @@ on:
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
|
||||
clean-orphaned-uploads:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
|
||||
144
.github/workflows/clean-src-cache.yml
vendored
144
.github/workflows/clean-src-cache.yml
vendored
@@ -7,162 +7,28 @@ name: Clean Source Cache
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
|
||||
clean-src-cache:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
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:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
|
||||
options: --user root
|
||||
volumes:
|
||||
- /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
|
||||
|
||||
4
.github/workflows/issue-commented.yml
vendored
4
.github/workflows/issue-commented.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
AUTHOR_ASSOCIATION=$(gh api /repos/electron/electron/issues/comments/${{ github.event.comment.id }} --jq '.author_association')
|
||||
echo "author_association=$AUTHOR_ASSOCIATION" >> "$GITHUB_OUTPUT"
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
if: ${{ !contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), steps.get-author-association.outputs.author_association) }}
|
||||
id: generate-token
|
||||
with:
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: *get-author-association
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
if: ${{ contains(fromJSON('["MEMBER", "OWNER"]'), steps.get-author-association.outputs.author_association) }}
|
||||
id: generate-token
|
||||
with:
|
||||
|
||||
12
.github/workflows/issue-labeled.yml
vendored
12
.github/workflows/issue-labeled.yml
vendored
@@ -15,13 +15,13 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
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
|
||||
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
@@ -36,13 +36,13 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
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
|
||||
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
@@ -70,13 +70,13 @@ jobs:
|
||||
fi
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
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 }}
|
||||
|
||||
10
.github/workflows/issue-opened.yml
vendored
10
.github/workflows/issue-opened.yml
vendored
@@ -14,13 +14,13 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Add to Issue Triage
|
||||
uses: dsanders11/project-actions/add-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/add-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
field: Reporter
|
||||
field-value: ${{ github.event.issue.user.login }}
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
.yarn
|
||||
- run: yarn workspaces focus @electron/gha-workflows
|
||||
- name: Add labels
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
id: add-labels
|
||||
env:
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
@@ -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 }}
|
||||
|
||||
4
.github/workflows/issue-transferred.yml
vendored
4
.github/workflows/issue-transferred.yml
vendored
@@ -14,13 +14,13 @@ jobs:
|
||||
if: ${{ !github.event.changes.new_repository.private }}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Remove from issue triage
|
||||
uses: dsanders11/project-actions/delete-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/delete-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
|
||||
4
.github/workflows/issue-unlabeled.yml
vendored
4
.github/workflows/issue-unlabeled.yml
vendored
@@ -26,14 +26,14 @@ jobs:
|
||||
fi
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
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
|
||||
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
|
||||
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 90
|
||||
|
||||
34
.github/workflows/linux-publish.yml
vendored
34
.github/workflows/linux-publish.yml
vendored
@@ -6,8 +6,7 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: ''
|
||||
required: false
|
||||
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
required: false
|
||||
@@ -21,28 +20,13 @@ on:
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
with:
|
||||
override: ${{ inputs.build-image-sha }}
|
||||
|
||||
checkout-linux:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
@@ -66,11 +50,11 @@ jobs:
|
||||
attestations: write
|
||||
contents: read
|
||||
id-token: write
|
||||
needs: [setup, checkout-linux]
|
||||
needs: checkout-linux
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
target-platform: linux
|
||||
target-arch: x64
|
||||
is-release: true
|
||||
@@ -86,11 +70,11 @@ jobs:
|
||||
attestations: write
|
||||
contents: read
|
||||
id-token: write
|
||||
needs: [setup, checkout-linux]
|
||||
needs: checkout-linux
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
target-platform: linux
|
||||
target-arch: arm
|
||||
is-release: true
|
||||
@@ -106,11 +90,11 @@ jobs:
|
||||
attestations: write
|
||||
contents: read
|
||||
id-token: write
|
||||
needs: [setup, checkout-linux]
|
||||
needs: checkout-linux
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
target-platform: linux
|
||||
target-arch: arm64
|
||||
is-release: true
|
||||
|
||||
23
.github/workflows/macos-publish.yml
vendored
23
.github/workflows/macos-publish.yml
vendored
@@ -6,8 +6,8 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: ''
|
||||
required: false
|
||||
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
|
||||
required: true
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
required: false
|
||||
@@ -21,28 +21,13 @@ on:
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
with:
|
||||
override: ${{ inputs.build-image-sha }}
|
||||
|
||||
checkout-macos:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
|
||||
@@ -51,21 +51,4 @@ jobs:
|
||||
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 @${PR_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." | gh pr review $PR_URL -r --body-file=-
|
||||
|
||||
1
.github/workflows/pipeline-electron-lint.yml
vendored
1
.github/workflows/pipeline-electron-lint.yml
vendored
@@ -76,6 +76,7 @@ jobs:
|
||||
- name: Add problem matchers
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::add-matcher::src/electron/.github/problem-matchers/eslint-stylish.json"
|
||||
echo "::add-matcher::src/electron/.github/problem-matchers/markdownlint.json"
|
||||
- name: Run Lint
|
||||
shell: bash
|
||||
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
run: df -h
|
||||
- name: Setup Node.js/npm
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
||||
with:
|
||||
node-version: 22.21.x
|
||||
cache: yarn
|
||||
|
||||
@@ -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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
with:
|
||||
name: out_gen_artifacts_${{ env.ARTIFACT_KEY }}
|
||||
path: ./src/out/${{ env.ELECTRON_OUT_DIR }}/gen
|
||||
@@ -137,32 +137,13 @@ jobs:
|
||||
run: |
|
||||
e init -f --root=$(pwd) --out=${ELECTRON_OUT_DIR} testing --target-cpu ${TARGET_ARCH} --remote-build none
|
||||
|
||||
# For macOS use_remoteexec=false will cause GN errors, so even though we're doing no remote build, set it
|
||||
export GN_EXTRA_ARGS="use_remoteexec=true target_cpu=\"${TARGET_ARCH}\""
|
||||
export GN_EXTRA_ARGS="target_cpu=\"${TARGET_ARCH}\""
|
||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||
export GN_EXTRA_ARGS="$GN_EXTRA_ARGS use_v8_context_snapshot=true target_os=\"win\""
|
||||
fi
|
||||
|
||||
e build --only-gen
|
||||
|
||||
# Copy macOS framework headers so clang-tidy can find them via -F.
|
||||
# This must happen after e build --only-gen since e init -f may
|
||||
# recreate the output directory.
|
||||
if [ "${{ inputs.target-platform }}" = "macos" ]; then
|
||||
OUT=src/out/${ELECTRON_OUT_DIR}
|
||||
SQRL=src/third_party/squirrel.mac
|
||||
|
||||
mkdir -p ${OUT}/{ReactiveObjC,Squirrel,Mantle}.framework/Headers
|
||||
|
||||
cp ${SQRL}/vendor/ReactiveObjC/ReactiveObjC/*.h ${OUT}/ReactiveObjC.framework/Headers/
|
||||
cp ${SQRL}/vendor/ReactiveObjC/ReactiveObjC/extobjc/*.h ${OUT}/ReactiveObjC.framework/Headers/
|
||||
|
||||
cp ${SQRL}/Squirrel/*.h ${OUT}/Squirrel.framework/Headers/
|
||||
|
||||
cp ${SQRL}/vendor/Mantle/Mantle/include/*.h ${OUT}/Mantle.framework/Headers/
|
||||
cp ${SQRL}/vendor/Mantle/Mantle/extobjc/include/*.h ${OUT}/Mantle.framework/Headers/
|
||||
fi
|
||||
|
||||
cd src/electron
|
||||
node script/yarn.js lint:clang-tidy --jobs 8 --out-dir ../out/${ELECTRON_OUT_DIR}
|
||||
- name: Remove Clang problem matcher
|
||||
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
run: df -h
|
||||
- name: Setup Node.js/npm
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
||||
with:
|
||||
node-version: 22.21.x
|
||||
cache: yarn
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Download Generated Artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
|
||||
with:
|
||||
name: generated_artifacts_linux_arm64
|
||||
path: ./generated_artifacts_linux_arm64
|
||||
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
cp $(which node) /mnt/runner-externals/node24/bin/
|
||||
- name: Setup Node.js/npm
|
||||
if: ${{ inputs.target-platform == 'win' }}
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
|
||||
with:
|
||||
node-version: 22.21.x
|
||||
- name: Add TCC permissions on macOS
|
||||
@@ -175,12 +175,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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
with:
|
||||
name: src_artifacts_${{ env.ARTIFACT_KEY }}
|
||||
path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
|
||||
@@ -315,7 +315,7 @@ jobs:
|
||||
if: always() && !cancelled()
|
||||
- name: Upload Test Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
|
||||
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
|
||||
|
||||
@@ -67,12 +67,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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
with:
|
||||
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
|
||||
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
|
||||
@@ -123,12 +123,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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
|
||||
with:
|
||||
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
|
||||
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
|
||||
|
||||
64
.github/workflows/pr-template-check.yml
vendored
64
.github/workflows/pr-template-check.yml
vendored
@@ -1,64 +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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.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 || '';
|
||||
// Allow through if body contains a valid backport line
|
||||
const backportRegex = /Backport of (?:#|https:\/\/github.com\/electron\/electron\/pull\/)\d+/i;
|
||||
if (backportRegex.test(body)) {
|
||||
console.log('Backport PR detected, skipping required section check.');
|
||||
return;
|
||||
}
|
||||
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',
|
||||
});
|
||||
}
|
||||
56
.github/workflows/pr-triage-automation.yml
vendored
56
.github/workflows/pr-triage-automation.yml
vendored
@@ -1,56 +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.state == 'open'
|
||||
&& 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
|
||||
&& github.event.issue.state == 'open'
|
||||
&& !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@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Get project item status
|
||||
uses: dsanders11/project-actions/get-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
id: get-item
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 118
|
||||
fail-if-item-not-found: false
|
||||
- name: Set status to Needs Review
|
||||
if: >-
|
||||
(steps.get-item.outputs.field-status == '🛑 Needs Submitter Response'
|
||||
|| steps.get-item.outputs.field-status == '🟡 WIP')
|
||||
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 118
|
||||
field: Status
|
||||
field-value: 🌀 Needs Review
|
||||
fail-if-item-not-found: false
|
||||
14
.github/workflows/pull-request-labeled.yml
vendored
14
.github/workflows/pull-request-labeled.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Trigger Slack workflow
|
||||
uses: slackapi/slack-github-action@03ea5433c137af7c0495bc0cad1af10403fc800c # v3.0.2
|
||||
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
|
||||
with:
|
||||
webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
|
||||
webhook-type: webhook-trigger
|
||||
@@ -36,13 +36,13 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
org: electron
|
||||
- name: Set status
|
||||
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/edit-item@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
project-number: 94
|
||||
@@ -50,17 +50,17 @@ jobs:
|
||||
field-value: ✅ Reviewed
|
||||
pull-request-labeled-ai-pr:
|
||||
name: ai-pr label added
|
||||
if: github.event.label.name == 'ai-pr' && github.event.pull_request.state != 'closed'
|
||||
if: github.event.label.name == 'ai-pr'
|
||||
runs-on: ubuntu-latest
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
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 +72,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 }}
|
||||
|
||||
1
.github/workflows/rerun-apply-patches.yml
vendored
1
.github/workflows/rerun-apply-patches.yml
vendored
@@ -8,7 +8,6 @@ on:
|
||||
paths:
|
||||
- 'DEPS'
|
||||
- 'patches/**'
|
||||
- '.github/siso-patches/**'
|
||||
|
||||
permissions: {}
|
||||
|
||||
|
||||
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -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@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5
|
||||
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.29.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
4
.github/workflows/stable-prep-items.yml
vendored
4
.github/workflows/stable-prep-items.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
@@ -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@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
|
||||
uses: dsanders11/project-actions/completed-by@2134fe7cc71c58b7ae259c82a8e63c6058255678 # v1.7.0
|
||||
with:
|
||||
field: Prep Status
|
||||
field-value: ✅ Complete
|
||||
|
||||
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
needs: stale
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
27
.github/workflows/windows-publish.yml
vendored
27
.github/workflows/windows-publish.yml
vendored
@@ -6,8 +6,8 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: ''
|
||||
required: false
|
||||
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
|
||||
required: true
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
required: false
|
||||
@@ -21,28 +21,13 @@ on:
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
- name: Set Build Image SHA
|
||||
id: build-image-sha
|
||||
uses: ./.github/actions/build-image-sha
|
||||
with:
|
||||
override: ${{ inputs.build-image-sha }}
|
||||
|
||||
checkout-windows:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
runs-on: electron-arc-centralus-linux-amd64-32core
|
||||
permissions:
|
||||
contents: read
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
|
||||
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
|
||||
volumes:
|
||||
- /mnt/win-cache:/mnt/win-cache
|
||||
@@ -52,6 +37,8 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
|
||||
TARGET_OS: 'win'
|
||||
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
|
||||
outputs:
|
||||
build-image-sha: ${{ inputs.build-image-sha }}
|
||||
steps:
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
|
||||
@@ -67,7 +54,7 @@ jobs:
|
||||
# Build the patched siso binary in parallel with checkout-windows; the
|
||||
# publish-*-win jobs consume it via SISO_PATH.
|
||||
build-siso-windows:
|
||||
needs: setup
|
||||
if: github.repository == 'electron/electron'
|
||||
uses: ./.github/workflows/pipeline-segment-build-siso-windows.yml
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"sortImports": {
|
||||
"newlinesBetween": true,
|
||||
"groups": [
|
||||
"electron-internal",
|
||||
"electron-scoped",
|
||||
"electron",
|
||||
"external",
|
||||
"builtin",
|
||||
["sibling", "parent"],
|
||||
"index",
|
||||
"type",
|
||||
"unknown"
|
||||
],
|
||||
"customGroups": [
|
||||
{
|
||||
"groupName": "electron-internal",
|
||||
"elementNamePattern": ["@electron/internal", "@electron/internal/**"]
|
||||
},
|
||||
{
|
||||
"groupName": "electron-scoped",
|
||||
"elementNamePattern": ["@electron/**"]
|
||||
},
|
||||
{
|
||||
"groupName": "electron",
|
||||
"elementNamePattern": ["electron", "electron/**"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"node_modules",
|
||||
"out",
|
||||
"ts-gen",
|
||||
"spec/node_modules",
|
||||
"spec/fixtures/native-addon",
|
||||
".github/workflows/node_modules",
|
||||
"docs/fiddles",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
"shell/common/node_includes.h",
|
||||
"spec/fixtures/pages/jquery-3.6.0.min.js"
|
||||
]
|
||||
}
|
||||
329
.oxlintrc.json
329
.oxlintrc.json
@@ -1,329 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": [
|
||||
"typescript",
|
||||
"import",
|
||||
"node",
|
||||
"promise",
|
||||
"unicorn"
|
||||
],
|
||||
"jsPlugins": [
|
||||
{
|
||||
"name": "no-only-tests",
|
||||
"specifier": "./script/lint-plugins/no-only-tests.mjs"
|
||||
}
|
||||
],
|
||||
"categories": {
|
||||
"correctness": "off"
|
||||
},
|
||||
"options": {
|
||||
"typeAware": false
|
||||
},
|
||||
"env": {
|
||||
"builtin": true,
|
||||
"browser": true
|
||||
},
|
||||
"ignorePatterns": [
|
||||
".github/workflows/node_modules",
|
||||
"spec/node_modules",
|
||||
"spec/fixtures/native-addon",
|
||||
"shell/browser/resources/win/resource.h",
|
||||
"shell/common/node_includes.h",
|
||||
"spec/fixtures/pages/jquery-3.6.0.min.js"
|
||||
],
|
||||
"rules": {
|
||||
"no-var": "error",
|
||||
"accessor-pairs": [
|
||||
"error",
|
||||
{
|
||||
"setWithoutGet": true,
|
||||
"enforceForClassMembers": true
|
||||
}
|
||||
],
|
||||
"array-callback-return": [
|
||||
"error",
|
||||
{
|
||||
"allowImplicit": false,
|
||||
"checkForEach": false
|
||||
}
|
||||
],
|
||||
"constructor-super": "error",
|
||||
"curly": [
|
||||
"error",
|
||||
"multi-line"
|
||||
],
|
||||
"default-case-last": "error",
|
||||
"eqeqeq": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"null": "ignore"
|
||||
}
|
||||
],
|
||||
"new-cap": [
|
||||
"error",
|
||||
{
|
||||
"newIsCap": true,
|
||||
"capIsNew": false,
|
||||
"properties": true
|
||||
}
|
||||
],
|
||||
"no-array-constructor": "error",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-caller": "error",
|
||||
"no-case-declarations": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-compare-neg-zero": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-constant-condition": [
|
||||
"error",
|
||||
{
|
||||
"checkLoops": false
|
||||
}
|
||||
],
|
||||
"no-control-regex": "error",
|
||||
"no-debugger": "error",
|
||||
"no-delete-var": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-useless-backreference": "error",
|
||||
"no-empty": [
|
||||
"error",
|
||||
{
|
||||
"allowEmptyCatch": true
|
||||
}
|
||||
],
|
||||
"no-empty-character-class": "error",
|
||||
"no-empty-pattern": "error",
|
||||
"no-eval": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-global-assign": "error",
|
||||
"no-import-assign": "error",
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-iterator": "error",
|
||||
"no-labels": [
|
||||
"error",
|
||||
{
|
||||
"allowLoop": false,
|
||||
"allowSwitch": false
|
||||
}
|
||||
],
|
||||
"no-lone-blocks": "error",
|
||||
"no-loss-of-precision": "error",
|
||||
"no-misleading-character-class": "error",
|
||||
"no-prototype-builtins": "error",
|
||||
"no-useless-catch": "error",
|
||||
"no-useless-constructor": "error",
|
||||
"no-use-before-define": [
|
||||
"error",
|
||||
{
|
||||
"functions": false,
|
||||
"classes": false,
|
||||
"variables": false
|
||||
}
|
||||
],
|
||||
"no-multi-str": "error",
|
||||
"no-new": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-proto": "error",
|
||||
"no-redeclare": [
|
||||
"error"
|
||||
],
|
||||
"no-regex-spaces": "error",
|
||||
"no-return-assign": [
|
||||
"error",
|
||||
"except-parens"
|
||||
],
|
||||
"no-self-assign": [
|
||||
"error",
|
||||
{
|
||||
"props": true
|
||||
}
|
||||
],
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-this-before-super": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": [
|
||||
"error",
|
||||
{
|
||||
"defaultAssignment": false
|
||||
}
|
||||
],
|
||||
"no-unreachable": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unsafe-negation": "error",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"argsIgnorePattern": "^_",
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
],
|
||||
"no-useless-call": "error",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-escape": "error",
|
||||
"no-useless-rename": "error",
|
||||
"no-useless-return": "error",
|
||||
"no-void": "error",
|
||||
"no-with": "error",
|
||||
"prefer-const": [
|
||||
"error",
|
||||
{
|
||||
"destructuring": "all"
|
||||
}
|
||||
],
|
||||
"prefer-promise-reject-errors": "error",
|
||||
"symbol-description": "error",
|
||||
"unicode-bom": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"use-isnan": [
|
||||
"error",
|
||||
{
|
||||
"enforceForSwitchCase": true,
|
||||
"enforceForIndexOf": true
|
||||
}
|
||||
],
|
||||
"valid-typeof": [
|
||||
"error",
|
||||
{
|
||||
"requireStringLiterals": true
|
||||
}
|
||||
],
|
||||
"yoda": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"import/export": "error",
|
||||
"import/first": "error",
|
||||
"import/no-absolute-path": [
|
||||
"error",
|
||||
{
|
||||
"esmodule": true,
|
||||
"commonjs": true,
|
||||
"amd": false
|
||||
}
|
||||
],
|
||||
"import/no-duplicates": "error",
|
||||
"import/no-named-default": "error",
|
||||
"import/no-webpack-loader-syntax": "error",
|
||||
"promise/param-names": "error",
|
||||
"guard-for-in": "error",
|
||||
"node/handle-callback-err": [
|
||||
"error",
|
||||
"^(err|error)$"
|
||||
],
|
||||
"node/no-exports-assign": "error",
|
||||
"node/no-new-require": "error",
|
||||
"node/no-path-concat": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
|
||||
"rules": {
|
||||
"no-use-before-define": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["lib/browser/**", "lib/utility/**"],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": ["electron", "electron/renderer"],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/isolated_renderer/*",
|
||||
"@electron/internal/renderer/*",
|
||||
"@electron/internal/sandboxed_worker/*",
|
||||
"@electron/internal/worker/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"lib/renderer/**",
|
||||
"lib/worker/**",
|
||||
"lib/preload_realm/**",
|
||||
"lib/sandboxed_renderer/**",
|
||||
"lib/isolated_renderer/**"
|
||||
],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": ["electron", "electron/main"],
|
||||
"patterns": ["./*", "../*", "@electron/internal/browser/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["lib/common/**"],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": ["electron", "electron/main", "electron/renderer"],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/browser/*",
|
||||
"@electron/internal/isolated_renderer/*",
|
||||
"@electron/internal/renderer/*",
|
||||
"@electron/internal/sandboxed_worker/*",
|
||||
"@electron/internal/worker/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"build/**",
|
||||
"script/**",
|
||||
"docs/**",
|
||||
"default_app/**",
|
||||
"spec/**"
|
||||
],
|
||||
"rules": {
|
||||
"unicorn/prefer-node-protocol": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["spec/**/*.ts", "spec/**/*.js", "spec/**/*.mjs"],
|
||||
"rules": {
|
||||
"no-only-tests/no-only-tests": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["**/*.d.ts"],
|
||||
"rules": {
|
||||
"no-useless-constructor": "off",
|
||||
"no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
# Vendored Yarn release
|
||||
|
||||
This directory holds the Yarn release used by this repo (`yarnPath` in
|
||||
`.yarnrc.yml`). The release file is checked in so every contributor and CI job
|
||||
runs the exact same Yarn, and so we can carry small local patches when needed.
|
||||
|
||||
`releases/yarn-4.12.0.cjs` currently carries one such patch, described below.
|
||||
If you bump the Yarn version, read the **Upgrading Yarn** section first.
|
||||
|
||||
## Patch: use `JsZipImpl` for the node-modules link step
|
||||
|
||||
### What changed
|
||||
|
||||
Two call sites in `releases/yarn-4.12.0.cjs` are modified so the
|
||||
`node-modules` linker (and the `pnpm`-loose linker) construct their read-only
|
||||
`ZipOpenFS` with `customZipImplementation: ST` — Yarn's pure-JS `JsZipImpl` —
|
||||
instead of falling through to the default WASM-backed `LibZipImpl`:
|
||||
|
||||
```text
|
||||
new $f({maxOpenFiles:80,readOnlyArchives:!0})
|
||||
→ new $f({maxOpenFiles:80,readOnlyArchives:!0,customZipImplementation:ST})
|
||||
```
|
||||
|
||||
A comment block at the top of the `.cjs` file marks the file as patched and
|
||||
points back here.
|
||||
|
||||
### Why
|
||||
|
||||
On the `linux-arm` CI test shards we run a 32-bit `arm32v7` container. During
|
||||
`yarn install`'s **Link step**, Yarn opens up to 80 cache zips concurrently.
|
||||
With `LibZipImpl`, each open zip is `readFileSync`'d into a Node `Buffer`
|
||||
**and copied again into the WASM linear memory**, and every file read does a
|
||||
WASM `_malloc(size)` for the entry. The WASM heap has to grow as a single
|
||||
contiguous region of the 32-bit address space; once enough zips are resident,
|
||||
the `_malloc` for a large entry — most often `typescript/lib/typescript.js`
|
||||
(~9 MB inside a ~22 MB zip) — fails.
|
||||
|
||||
Yarn's cross-FS `copyFilePromise` swallows the underlying error and re-throws
|
||||
a generic one, so CI shows:
|
||||
|
||||
```text
|
||||
YN0001: While persisting .../typescript-patch-...zip/node_modules/typescript/
|
||||
EINVAL: invalid argument, copyfile '/node_modules/typescript/lib/typescript.js' -> '...'
|
||||
```
|
||||
|
||||
The unmasked form (occasionally seen on `pdfjs-dist`) is the WASM-heap failure
|
||||
string `Couldn't allocate enough memory`. This started failing ~1-in-3
|
||||
`linux-arm / test` shards at **Install Dependencies** on 2026-04-13, after
|
||||
[#50692](https://github.com/electron/electron/pull/50692) grew the cache enough
|
||||
to push the 32-bit process over the edge nondeterministically — e.g.
|
||||
[run 24739817558](https://github.com/electron/electron/actions/runs/24739817558/job/72380803746).
|
||||
|
||||
`JsZipImpl` avoids the problem entirely: it opens the zip by file descriptor,
|
||||
reads only the central directory into memory, and `readSync`s individual
|
||||
entries into ordinary Node `Buffer`s — **no WASM heap involved**. It is
|
||||
read-only and path-based, which is exactly how the linker uses these archives.
|
||||
|
||||
There is no `.yarnrc.yml` setting or environment variable to select the zip
|
||||
implementation (verified against the bundle), so editing the vendored release
|
||||
is the only way to switch it short of re-implementing the linker in a plugin.
|
||||
|
||||
Upstream references:
|
||||
[yarnpkg/berry#3972](https://github.com/yarnpkg/berry/issues/3972),
|
||||
[yarnpkg/berry#6722](https://github.com/yarnpkg/berry/issues/6722),
|
||||
[yarnpkg/berry#6550](https://github.com/yarnpkg/berry/issues/6550).
|
||||
|
||||
### Upgrading Yarn
|
||||
|
||||
When bumping `releases/yarn-*.cjs`:
|
||||
|
||||
1. Check whether upstream now defaults `readOnlyArchives` opens to `JsZipImpl`,
|
||||
or exposes a config knob for the zip implementation. If so, drop this patch.
|
||||
2. Otherwise, re-apply: search the new bundle for
|
||||
`maxOpenFiles:80,readOnlyArchives:!0` (the surrounding minified identifiers
|
||||
will differ) and add `,customZipImplementation:<JsZipImpl symbol>` — that
|
||||
symbol is whatever the new bundle exports as `JsZipImpl` from
|
||||
`@yarnpkg/libzip`.
|
||||
3. Re-add the header comment pointing back to this README.
|
||||
4. Verify with
|
||||
`rm -rf node_modules spec/node_modules && node script/yarn.js install --immutable --mode=skip-build`
|
||||
and confirm `node_modules/typescript/lib/typescript.js` is byte-identical to
|
||||
an unpatched install.
|
||||
7
.yarn/releases/yarn-4.12.0.cjs
vendored
7
.yarn/releases/yarn-4.12.0.cjs
vendored
File diff suppressed because one or more lines are too long
27
BUILD.gn
27
BUILD.gn
@@ -151,25 +151,6 @@ config("branding") {
|
||||
|
||||
config("electron_lib_config") {
|
||||
include_dirs = [ "." ]
|
||||
cflags = []
|
||||
if (is_clang && clang_use_chrome_plugins) {
|
||||
# The plugin is built directly into clang, so there's no need to load it
|
||||
# dynamically.
|
||||
cflags += [
|
||||
"-Xclang",
|
||||
"-add-plugin",
|
||||
"-Xclang",
|
||||
"blink-gc-plugin",
|
||||
"-Xclang",
|
||||
"-plugin-arg-blink-gc-plugin",
|
||||
"-Xclang",
|
||||
"check-directory=electron/shell/",
|
||||
"-Xclang",
|
||||
"-plugin-arg-blink-gc-plugin",
|
||||
"-Xclang",
|
||||
"check-directory=gin/",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# We generate the definitions twice here, once in //electron/electron.d.ts
|
||||
@@ -499,10 +480,8 @@ source_set("electron_lib") {
|
||||
"//components/certificate_transparency",
|
||||
"//components/compose:buildflags",
|
||||
"//components/embedder_support:user_agent",
|
||||
"//components/heap_profiling/multi_process",
|
||||
"//components/input",
|
||||
"//components/language/core/browser",
|
||||
"//components/memory_system",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/browser",
|
||||
"//components/network_hints/common:mojo_bindings",
|
||||
@@ -528,7 +507,6 @@ source_set("electron_lib") {
|
||||
"//content/public/utility",
|
||||
"//device/bluetooth",
|
||||
"//device/bluetooth/public/cpp",
|
||||
"//device/fido",
|
||||
"//gin",
|
||||
"//gpu/ipc/client",
|
||||
"//media/capture/mojom:video_capture",
|
||||
@@ -802,7 +780,7 @@ source_set("electron_lib") {
|
||||
"//components/zoom",
|
||||
"//extensions/browser",
|
||||
"//extensions/browser/api:api_provider",
|
||||
"//extensions/browser/mime_handler",
|
||||
"//extensions/browser/mime_handler:stream_info",
|
||||
"//extensions/browser/updater",
|
||||
"//extensions/common",
|
||||
"//extensions/common:core_api_provider",
|
||||
@@ -1671,9 +1649,8 @@ action("node_version_header") {
|
||||
action("generate_node_headers") {
|
||||
deps = [ ":generate_config_gypi" ]
|
||||
script = "script/node/generate_node_headers.py"
|
||||
inputs = auto_filenames.node_header_sources
|
||||
outputs = [ "$root_gen_dir/node_headers.json" ]
|
||||
args = [ rebase_path("$root_gen_dir") ]
|
||||
outputs = [ "$root_gen_dir/node_headers.json" ]
|
||||
}
|
||||
|
||||
action("tar_node_headers") {
|
||||
|
||||
12
CLAUDE.md
12
CLAUDE.md
@@ -1,14 +1,5 @@
|
||||
# Electron Development Guide
|
||||
|
||||
## Running node_modules binaries
|
||||
|
||||
**Never use `npx`.** It is considered dangerous because it can silently fetch and execute arbitrary packages from the registry. Always run binaries through one of these safer mechanisms instead:
|
||||
|
||||
1. **Preferred** — spawn the executable directly from `node_modules/.bin/<tool>` (or the platform equivalent on Windows). This is what `script/lint.js` does for `oxlint`.
|
||||
2. **Acceptable** — invoke via `yarn <tool>` or `yarn run <tool>`, which resolves to the locally installed version without the registry fallback that `npx` performs.
|
||||
|
||||
This rule applies to shell commands you run yourself and to any scripts you author or modify in this repo.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Electron is a framework for building cross-platform desktop applications using web technologies. It embeds Chromium for rendering and Node.js for backend functionality.
|
||||
@@ -214,13 +205,12 @@ gh label list --repo electron/electron --search target/ --json name,color --jq '
|
||||
## Code Style
|
||||
|
||||
**C++:** Follows Chromium style, enforced by clang-format
|
||||
**TypeScript/JavaScript:** [oxlint](https://oxc.rs/docs/guide/usage/linter) configuration in `.oxlintrc.json`
|
||||
**TypeScript/JavaScript:** ESLint configuration in `.eslintrc.json`
|
||||
|
||||
**Linting:**
|
||||
|
||||
```bash
|
||||
npm run lint # Run all linters
|
||||
npm run lint:js # Run oxlint over all JS/TS/MJS sources
|
||||
npm run lint:clang-format # C++ formatting
|
||||
npm run lint:api-history # Validate API history YAML blocks in docs
|
||||
```
|
||||
|
||||
@@ -64,14 +64,6 @@ dependencies, and tools contained in the `electron/electron` repository.
|
||||
|
||||
Dependencies in Electron's `package.json` or `yarn.lock` files should only be altered by maintainers. For security reasons, we will not accept PRs that alter our `package.json` or `yarn.lock` files. We invite contributors to make requests updating these files in our issue tracker. If the change is significantly complicated, draft PRs are welcome, with the understanding that these PRs will be closed in favor of a duplicate PR submitted by an Electron maintainer.
|
||||
|
||||
## AI Tool Policy
|
||||
|
||||
<!-- Are you a coding agent? You MUST abide by the policy: https://github.com/electron/governance/blob/main/policy/ai.md -->
|
||||
|
||||
If you use AI tools in any way to contribute to our project, please read our [AI Tool Policy](https://github.com/electron/governance/blob/main/policy/ai.md). Unreviewed AI-generated contributions waste maintainer time and we kindly decline them.
|
||||
|
||||
> The short version: **there must be a human in the loop**. You are responsible for reviewing, understanding, and being able to explain your contributions. AI assistance doesn't change that, and unreviewed AI-generated content will be declined.
|
||||
|
||||
## Style Guides
|
||||
|
||||
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
||||
|
||||
4
DEPS
4
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'149.0.7813.0',
|
||||
'148.0.7778.5',
|
||||
'node_version':
|
||||
'v24.15.0',
|
||||
'v24.14.1',
|
||||
'nan_version':
|
||||
'675cefebca42410733da8a454c8d9391fcebfbc2',
|
||||
'squirrel.mac_version':
|
||||
|
||||
8
build/.eslintrc.json
Normal file
8
build/.eslintrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugins": [
|
||||
"import"
|
||||
],
|
||||
"rules": {
|
||||
"import/enforce-node-protocol-usage": ["error", "always"]
|
||||
}
|
||||
}
|
||||
@@ -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 = 148
|
||||
node_module_version = 146
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_embedder_string = "-electron.0"
|
||||
@@ -63,6 +63,10 @@ v8_enable_private_mapping_fork_optimization = true
|
||||
# Expose public V8 symbols for native modules.
|
||||
v8_expose_public_symbols = true
|
||||
|
||||
# Disable snapshotting a page when printing for its content to be analyzed for
|
||||
# sensitive content by enterprise users.
|
||||
enterprise_cloud_content_analysis = false
|
||||
|
||||
# We don't use anything from here, and it causes target collisions
|
||||
enable_linux_installer = false
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ template("electron_extra_paks") {
|
||||
"$root_gen_dir/net/net_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/strings/permission_element_generated_strings.pak",
|
||||
"$target_gen_dir/electron_resources.pak",
|
||||
]
|
||||
deps = [
|
||||
@@ -84,7 +83,6 @@ template("electron_extra_paks") {
|
||||
"//net:net_resources",
|
||||
"//third_party/blink/public:devtools_inspector_resources",
|
||||
"//third_party/blink/public:resources",
|
||||
"//third_party/blink/public/strings:permission_element_generated_strings",
|
||||
"//ui/webui/resources",
|
||||
]
|
||||
if (defined(invoker.deps)) {
|
||||
@@ -189,7 +187,6 @@ template("electron_paks") {
|
||||
"${root_gen_dir}/extensions/strings/extensions_strings_",
|
||||
"${root_gen_dir}/services/strings/services_strings_",
|
||||
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
|
||||
"${root_gen_dir}/third_party/blink/public/strings/permission_element_strings_",
|
||||
"${root_gen_dir}/ui/strings/app_locale_settings_",
|
||||
"${root_gen_dir}/ui/strings/auto_image_annotation_strings_",
|
||||
"${root_gen_dir}/ui/strings/ax_strings_",
|
||||
@@ -207,7 +204,6 @@ template("electron_paks") {
|
||||
"//extensions/strings",
|
||||
"//services/strings",
|
||||
"//third_party/blink/public/strings",
|
||||
"//third_party/blink/public/strings:permission_element_strings",
|
||||
"//ui/strings:app_locale_settings",
|
||||
"//ui/strings:auto_image_annotation_strings",
|
||||
"//ui/strings:ax_strings",
|
||||
|
||||
@@ -8,13 +8,10 @@ const path = require('node:path');
|
||||
const electronRoot = path.resolve(__dirname, '../..');
|
||||
|
||||
class AccessDependenciesPlugin {
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap('AccessDependenciesPlugin', (compilation) => {
|
||||
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', (modules) => {
|
||||
const filePaths = modules
|
||||
.map((m) => m.resource)
|
||||
.filter((p) => p)
|
||||
.map((p) => path.relative(electronRoot, p));
|
||||
apply (compiler) {
|
||||
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
|
||||
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
|
||||
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p));
|
||||
console.info(JSON.stringify(filePaths));
|
||||
});
|
||||
});
|
||||
@@ -34,14 +31,7 @@ module.exports = ({
|
||||
entry = path.resolve(electronRoot, 'lib', target, 'init.js');
|
||||
}
|
||||
|
||||
const electronAPIFile = path.resolve(
|
||||
electronRoot,
|
||||
'lib',
|
||||
loadElectronFromAlternateTarget || target,
|
||||
'api',
|
||||
'exports',
|
||||
'electron.ts'
|
||||
);
|
||||
const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
|
||||
|
||||
return (env = {}, argv = {}) => {
|
||||
const onlyPrintingGraph = !!env.PRINT_WEBPACK_GRAPH;
|
||||
@@ -71,59 +61,49 @@ module.exports = ({
|
||||
}
|
||||
|
||||
if (targetDeletesNodeGlobals) {
|
||||
plugins.push(
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer'],
|
||||
global: ['@electron/internal/common/webpack-provider', '_global'],
|
||||
process: ['@electron/internal/common/webpack-provider', 'process']
|
||||
})
|
||||
);
|
||||
plugins.push(new webpack.ProvidePlugin({
|
||||
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer'],
|
||||
global: ['@electron/internal/common/webpack-provider', '_global'],
|
||||
process: ['@electron/internal/common/webpack-provider', 'process']
|
||||
}));
|
||||
}
|
||||
|
||||
// Webpack 5 no longer polyfills process or Buffer.
|
||||
if (!alwaysHasNode) {
|
||||
plugins.push(
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
process: 'process/browser'
|
||||
})
|
||||
);
|
||||
plugins.push(new webpack.ProvidePlugin({
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
process: 'process/browser'
|
||||
}));
|
||||
}
|
||||
|
||||
plugins.push(
|
||||
new webpack.ProvidePlugin({
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
|
||||
})
|
||||
);
|
||||
plugins.push(new webpack.ProvidePlugin({
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
|
||||
}));
|
||||
|
||||
plugins.push(new webpack.DefinePlugin(defines));
|
||||
|
||||
if (wrapInitWithProfilingTimeout) {
|
||||
plugins.push(
|
||||
new WrapperPlugin({
|
||||
header: 'function ___electron_webpack_init__() {',
|
||||
footer: `
|
||||
plugins.push(new WrapperPlugin({
|
||||
header: 'function ___electron_webpack_init__() {',
|
||||
footer: `
|
||||
};
|
||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||
setTimeout(___electron_webpack_init__, 0);
|
||||
} else {
|
||||
___electron_webpack_init__();
|
||||
}`
|
||||
})
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
if (wrapInitWithTryCatch) {
|
||||
plugins.push(
|
||||
new WrapperPlugin({
|
||||
header: 'try {',
|
||||
footer: `
|
||||
plugins.push(new WrapperPlugin({
|
||||
header: 'try {',
|
||||
footer: `
|
||||
} catch (err) {
|
||||
console.error('Electron ${outputFilename} script failed to run');
|
||||
console.error(err);
|
||||
}`
|
||||
})
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -153,26 +133,23 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
||||
loader: 'null-loader'
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
||||
transpileOnly: onlyPrintingGraph,
|
||||
ignoreDiagnostics: [
|
||||
// File '{0}' is not under 'rootDir' '{1}'.
|
||||
6059,
|
||||
// Private field '{0}' must be declared in an enclosing class.
|
||||
1111
|
||||
]
|
||||
}
|
||||
rules: [{
|
||||
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
||||
loader: 'null-loader'
|
||||
}, {
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
||||
transpileOnly: onlyPrintingGraph,
|
||||
ignoreDiagnostics: [
|
||||
// File '{0}' is not under 'rootDir' '{1}'.
|
||||
6059,
|
||||
// Private field '{0}' must be declared in an enclosing class.
|
||||
1111
|
||||
]
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2026 GitHub, Inc.
|
||||
# Use of this source code is governed by the MIT license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Wrapper for lld-link that resolves relative paths to absolute.
|
||||
|
||||
Usage: abs_link_wrapper.py <lld-link> <args...>
|
||||
|
||||
The first argument is the real linker executable. The script resolves
|
||||
relative .obj/.rlib/.res/.lib paths in both @rspfile contents and direct
|
||||
command-line arguments to absolute paths, then invokes the real linker.
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def _is_file_path(token):
|
||||
"""Check if a token looks like a relative file path (not a flag or bare lib name)."""
|
||||
# Strip surrounding quotes
|
||||
t = token.strip('"')
|
||||
# Linker flags start with / or -
|
||||
if t.startswith('/') or t.startswith('-'):
|
||||
return False
|
||||
# Must contain a directory separator to be a relative path.
|
||||
# Bare names like "advapi32.lib" are system libraries resolved via
|
||||
# -libpath: or /winsysroot and must not be turned into absolute paths.
|
||||
if '/' not in t and '\\' not in t:
|
||||
return False
|
||||
# File extensions we care about
|
||||
return t.endswith(('.obj', '.res', '.lib', '.a', '.o', '.rlib'))
|
||||
|
||||
|
||||
def _resolve_rsp(rsp_path):
|
||||
"""Rewrite relative file paths in the rsp file to absolute paths."""
|
||||
with open(rsp_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
lines = []
|
||||
changed = False
|
||||
for line in content.splitlines():
|
||||
tokens = []
|
||||
for token in line.split():
|
||||
stripped = token.strip('"')
|
||||
if _is_file_path(token) and not os.path.isabs(stripped):
|
||||
abs_path = os.path.abspath(stripped)
|
||||
tokens.append('"' + abs_path + '"')
|
||||
changed = True
|
||||
else:
|
||||
tokens.append(token)
|
||||
lines.append(' '.join(tokens))
|
||||
|
||||
if not changed:
|
||||
return rsp_path
|
||||
|
||||
abs_rsp = rsp_path + '.abs'
|
||||
with open(abs_rsp, 'w') as f:
|
||||
f.write('\n'.join(lines))
|
||||
return abs_rsp
|
||||
|
||||
|
||||
def _resolve_arg(arg):
|
||||
"""Resolve a single command-line argument if it's a relative file path."""
|
||||
stripped = arg.strip('"')
|
||||
if _is_file_path(arg) and not os.path.isabs(stripped):
|
||||
return os.path.abspath(stripped)
|
||||
return arg
|
||||
|
||||
|
||||
def main():
|
||||
args = []
|
||||
for arg in sys.argv[1:]:
|
||||
if arg.startswith('@'):
|
||||
rsp_path = arg[1:].strip('"')
|
||||
resolved = _resolve_rsp(rsp_path)
|
||||
args.append('@' + resolved)
|
||||
else:
|
||||
args.append(_resolve_arg(arg))
|
||||
|
||||
return subprocess.call(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -21,8 +21,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/browser_features.h",
|
||||
"//chrome/browser/browser_process.cc",
|
||||
"//chrome/browser/browser_process.h",
|
||||
"//chrome/browser/device_notifications/device_connection_tracker.h",
|
||||
"//chrome/browser/device_notifications/device_system_tray_icon.h",
|
||||
"//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
|
||||
"//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
|
||||
"//chrome/browser/devtools/devtools_dispatch_http_request_params.cc",
|
||||
@@ -40,7 +38,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/devtools/visual_logging.h",
|
||||
"//chrome/browser/file_system_access/file_system_access_features.cc",
|
||||
"//chrome/browser/file_system_access/file_system_access_features.h",
|
||||
"//chrome/browser/hid/hid_system_tray_icon.h",
|
||||
"//chrome/browser/icon_loader.cc",
|
||||
"//chrome/browser/icon_loader.h",
|
||||
"//chrome/browser/icon_manager.cc",
|
||||
@@ -159,7 +156,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/webui/accessibility/accessibility_ui.h",
|
||||
"//chrome/browser/usb/usb_blocklist.cc",
|
||||
"//chrome/browser/usb/usb_blocklist.h",
|
||||
"//chrome/browser/usb/usb_system_tray_icon.h",
|
||||
"//extensions/browser/app_window/size_constraints.cc",
|
||||
"//extensions/browser/app_window/size_constraints.h",
|
||||
"//ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc",
|
||||
@@ -251,6 +247,10 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
|
||||
]
|
||||
sources += [
|
||||
"//chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.cc",
|
||||
"//chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.h",
|
||||
]
|
||||
public_deps += [ "//components/dbus" ]
|
||||
}
|
||||
|
||||
@@ -389,17 +389,16 @@ static_library("chrome") {
|
||||
"//chrome/browser/pdf/chrome_pdf_stream_delegate.h",
|
||||
"//chrome/browser/pdf/pdf_extension_util.cc",
|
||||
"//chrome/browser/pdf/pdf_extension_util.h",
|
||||
"//chrome/browser/pdf/pdf_handler_stream_delegate.cc",
|
||||
"//chrome/browser/pdf/pdf_handler_stream_delegate.h",
|
||||
"//chrome/browser/pdf/pdf_help_bubble_handler_factory.cc",
|
||||
"//chrome/browser/pdf/pdf_help_bubble_handler_factory.h",
|
||||
"//chrome/browser/pdf/pdf_viewer_stream_manager.cc",
|
||||
"//chrome/browser/pdf/pdf_viewer_stream_manager.h",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.cc",
|
||||
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.h",
|
||||
]
|
||||
deps += [
|
||||
"//components/pdf/browser",
|
||||
"//components/pdf/renderer",
|
||||
"//components/zoom",
|
||||
"//ui/base/interaction",
|
||||
"//ui/webui/resources/cr_components/help_bubble:mojo_bindings",
|
||||
]
|
||||
|
||||
8
default_app/.eslintrc.json
Normal file
8
default_app/.eslintrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"plugins": [
|
||||
"import"
|
||||
],
|
||||
"rules": {
|
||||
"import/enforce-node-protocol-usage": ["error", "always"]
|
||||
}
|
||||
}
|
||||
@@ -61,12 +61,13 @@ app.whenReady().then(() => {
|
||||
// Find the shortest path to the electron binary
|
||||
const absoluteElectronPath = process.execPath;
|
||||
const relativeElectronPath = path.relative(process.cwd(), absoluteElectronPath);
|
||||
const electronPath =
|
||||
absoluteElectronPath.length < relativeElectronPath.length ? absoluteElectronPath : relativeElectronPath;
|
||||
const electronPath = absoluteElectronPath.length < relativeElectronPath.length
|
||||
? absoluteElectronPath
|
||||
: relativeElectronPath;
|
||||
|
||||
const indexPath = path.resolve(app.getAppPath(), 'index.html');
|
||||
|
||||
function isTrustedSender(webContents: Electron.WebContents) {
|
||||
function isTrustedSender (webContents: Electron.WebContents) {
|
||||
if (webContents !== (mainWindow && mainWindow.webContents)) {
|
||||
return false;
|
||||
}
|
||||
@@ -82,7 +83,7 @@ ipcMain.handle('bootstrap', (event) => {
|
||||
return isTrustedSender(event.sender) ? electronPath : null;
|
||||
});
|
||||
|
||||
async function createWindow(backgroundColor?: string) {
|
||||
async function createWindow (backgroundColor?: string) {
|
||||
await app.whenReady();
|
||||
|
||||
const options: Electron.BrowserWindowConstructorOptions = {
|
||||
@@ -107,7 +108,7 @@ async function createWindow(backgroundColor?: string) {
|
||||
mainWindow = new BrowserWindow(options);
|
||||
mainWindow.on('ready-to-show', () => mainWindow!.show());
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.setWindowOpenHandler(details => {
|
||||
shell.openExternal(details.url);
|
||||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ type DefaultAppOptions = {
|
||||
interactive: boolean;
|
||||
abi: boolean;
|
||||
modules: string[];
|
||||
};
|
||||
}
|
||||
|
||||
// Parse command line options.
|
||||
const argv = process.argv.slice(1);
|
||||
@@ -74,7 +74,7 @@ if (option.modules.length > 0) {
|
||||
(Module as any)._preloadModules(option.modules);
|
||||
}
|
||||
|
||||
async function loadApplicationPackage(packagePath: string) {
|
||||
async function loadApplicationPackage (packagePath: string) {
|
||||
// Add a flag indicating app is started from default app.
|
||||
Object.defineProperty(process, 'defaultApp', {
|
||||
configurable: false,
|
||||
@@ -92,11 +92,9 @@ async function loadApplicationPackage(packagePath: string) {
|
||||
const emitWarning = process.emitWarning;
|
||||
try {
|
||||
process.emitWarning = () => {};
|
||||
packageJson = (
|
||||
await import(url.pathToFileURL(packageJsonPath).toString(), {
|
||||
with: { type: 'json' }
|
||||
})
|
||||
).default;
|
||||
packageJson = (await import(url.pathToFileURL(packageJsonPath).toString(), {
|
||||
with: { type: 'json' }
|
||||
})).default;
|
||||
} catch (e) {
|
||||
showErrorMessage(`Unable to parse ${packageJsonPath}\n\n${(e as Error).message}`);
|
||||
return;
|
||||
@@ -145,23 +143,23 @@ async function loadApplicationPackage(packagePath: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function showErrorMessage(message: string) {
|
||||
function showErrorMessage (message: string) {
|
||||
app.focus();
|
||||
dialog.showErrorBox('Error launching app', message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function loadApplicationByURL(appUrl: string) {
|
||||
async function loadApplicationByURL (appUrl: string) {
|
||||
const { loadURL } = await import('./default_app.js');
|
||||
loadURL(appUrl);
|
||||
}
|
||||
|
||||
async function loadApplicationByFile(appPath: string) {
|
||||
async function loadApplicationByFile (appPath: string) {
|
||||
const { loadFile } = await import('./default_app.js');
|
||||
loadFile(appPath);
|
||||
}
|
||||
|
||||
async function startRepl() {
|
||||
async function startRepl () {
|
||||
if (process.platform === 'win32') {
|
||||
console.error('Electron REPL not currently supported on Windows');
|
||||
process.exit(1);
|
||||
@@ -189,7 +187,7 @@ async function startRepl() {
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
function defineBuiltin(context: any, name: string, getter: Function) {
|
||||
function defineBuiltin (context: any, name: string, getter: Function) {
|
||||
const setReal = (val: any) => {
|
||||
// Deleting the property before re-assigning it disables the
|
||||
// getter/setter mechanism.
|
||||
@@ -227,42 +225,11 @@ async function startRepl() {
|
||||
// we only trigger custom tab-completion when no common words are
|
||||
// potentially matches.
|
||||
const commonWords = [
|
||||
'async',
|
||||
'await',
|
||||
'break',
|
||||
'case',
|
||||
'catch',
|
||||
'const',
|
||||
'continue',
|
||||
'debugger',
|
||||
'default',
|
||||
'delete',
|
||||
'do',
|
||||
'else',
|
||||
'export',
|
||||
'false',
|
||||
'finally',
|
||||
'for',
|
||||
'function',
|
||||
'if',
|
||||
'import',
|
||||
'in',
|
||||
'instanceof',
|
||||
'let',
|
||||
'new',
|
||||
'null',
|
||||
'return',
|
||||
'switch',
|
||||
'this',
|
||||
'throw',
|
||||
'true',
|
||||
'try',
|
||||
'typeof',
|
||||
'var',
|
||||
'void',
|
||||
'while',
|
||||
'with',
|
||||
'yield'
|
||||
'async', 'await', 'break', 'case', 'catch', 'const', 'continue',
|
||||
'debugger', 'default', 'delete', 'do', 'else', 'export', 'false',
|
||||
'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let',
|
||||
'new', 'null', 'return', 'switch', 'this', 'throw', 'true', 'try',
|
||||
'typeof', 'var', 'void', 'while', 'with', 'yield'
|
||||
];
|
||||
|
||||
const electronBuiltins = [...Object.keys(electron), 'original-fs', 'electron'];
|
||||
|
||||
@@ -2,10 +2,10 @@ const { ipcRenderer, contextBridge } = require('electron/renderer');
|
||||
|
||||
const policy = window.trustedTypes.createPolicy('electron-default-app', {
|
||||
// we trust the SVG contents
|
||||
createHTML: (input) => input
|
||||
createHTML: input => input
|
||||
});
|
||||
|
||||
async function getOcticonSvg(name: string) {
|
||||
async function getOcticonSvg (name: string) {
|
||||
try {
|
||||
const response = await fetch(`octicon/${name}.svg`);
|
||||
const div = document.createElement('div');
|
||||
@@ -16,7 +16,7 @@ async function getOcticonSvg(name: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSVG(element: HTMLSpanElement) {
|
||||
async function loadSVG (element: HTMLSpanElement) {
|
||||
for (const cssClass of element.classList) {
|
||||
if (cssClass.startsWith('octicon-')) {
|
||||
const icon = await getOcticonSvg(cssClass.substr(8));
|
||||
@@ -32,9 +32,9 @@ async function loadSVG(element: HTMLSpanElement) {
|
||||
}
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
async function initialize () {
|
||||
const electronPath = await ipcRenderer.invoke('bootstrap');
|
||||
function replaceText(selector: string, text: string, link?: string) {
|
||||
function replaceText (selector: string, text: string, link?: string) {
|
||||
const element = document.querySelector<HTMLElement>(selector);
|
||||
if (element) {
|
||||
if (link) {
|
||||
@@ -51,11 +51,7 @@ async function initialize() {
|
||||
|
||||
replaceText('.electron-version', `Electron v${process.versions.electron}`, 'https://electronjs.org/docs');
|
||||
replaceText('.chrome-version', `Chromium v${process.versions.chrome}`, 'https://developer.chrome.com/docs/chromium');
|
||||
replaceText(
|
||||
'.node-version',
|
||||
`Node v${process.versions.node}`,
|
||||
`https://nodejs.org/docs/v${process.versions.node}/api`
|
||||
);
|
||||
replaceText('.node-version', `Node v${process.versions.node}`, `https://nodejs.org/docs/v${process.versions.node}/api`);
|
||||
replaceText('.v8-version', `v8 v${process.versions.v8}`, 'https://v8.dev/docs');
|
||||
replaceText('.command-example', `${electronPath} path-to-app`);
|
||||
|
||||
|
||||
35
docs/.eslintrc.json
Normal file
35
docs/.eslintrc.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"plugins": [
|
||||
"import",
|
||||
"markdown"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.md", "**/*.md"],
|
||||
"processor": "markdown/markdown"
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"import/order": ["error", {
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
},
|
||||
"newlines-between": "always",
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "{electron,electron/**}",
|
||||
"group": "builtin",
|
||||
"position": "before"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": []
|
||||
}],
|
||||
"n/no-callback-literal": "off",
|
||||
"no-undef": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-vars": "off",
|
||||
"import/enforce-node-protocol-usage": ["error", "always"]
|
||||
}
|
||||
}
|
||||
@@ -1233,51 +1233,6 @@ This API must be called after the `ready` event is emitted.
|
||||
[doh-providers]: https://source.chromium.org/chromium/chromium/src/+/main:net/dns/public/doh_provider_entry.cc;l=31?q=%22DohProviderEntry::GetList()%22&ss=chromium%2Fchromium%2Fsrc
|
||||
[RFC8484 § 3]: https://datatracker.ietf.org/doc/html/rfc8484#section-3
|
||||
|
||||
### `app.configureWebAuthn(options)` _macOS_
|
||||
|
||||
* `options` Object
|
||||
* `touchID` Object (optional) - Enables the Touch ID / Secure Enclave platform
|
||||
authenticator for [Web Authentication](https://www.w3.org/TR/webauthn-2/)
|
||||
requests.
|
||||
* `keychainAccessGroup` string - The keychain access group that WebAuthn
|
||||
credentials will be stored under. This value **must** also be present in
|
||||
your app's `keychain-access-groups` code-signing entitlement, and is
|
||||
typically of the form `<TEAM_ID>.<BUNDLE_ID>.webauthn`.
|
||||
|
||||
Configures platform authenticators for the Web Authentication API
|
||||
(`navigator.credentials.create()` / `navigator.credentials.get()`). Until this
|
||||
is called, `PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()`
|
||||
resolves to `false` and platform-authenticator requests are not serviced.
|
||||
|
||||
When `touchID` is provided, WebAuthn credentials are stored in the macOS
|
||||
keychain and bound to this device's Secure Enclave. Electron automatically
|
||||
generates and persists a per-[`session`](session.md) metadata secret so that
|
||||
credentials created in one partition are not visible to another.
|
||||
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
|
||||
app.configureWebAuthn({
|
||||
touchID: {
|
||||
keychainAccessGroup: 'A1B2C3D4E5.com.example.app.webauthn'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
With the matching entitlement in your app's `entitlements.plist`:
|
||||
|
||||
```xml
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>A1B2C3D4E5.com.example.app.webauthn</string>
|
||||
</array>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Touch ID WebAuthn credentials are device-bound and are not synced via iCloud
|
||||
> Keychain. They are only available on Macs with a Secure Enclave (Apple
|
||||
> silicon, or Intel Macs with a T2 chip).
|
||||
|
||||
### `app.disableHardwareAcceleration()`
|
||||
|
||||
Disables hardware acceleration for current app.
|
||||
|
||||
@@ -319,17 +319,6 @@ By default inspector websocket url is available in stderr and under /json/list e
|
||||
|
||||
Enable support for DevTools network inspector events, for visibility into requests made by the nodejs `http` and `https` modules.
|
||||
|
||||
### `--experimental-inspector-network-resource`
|
||||
|
||||
Enable support for resolving source maps over the network when using the Node.js inspector.
|
||||
|
||||
When enabled, DevTools can retrieve remote source maps for main and utility
|
||||
process scripts via the Node.js inspector.
|
||||
|
||||
**Note:** When enabled, the Node.js inspector will make network requests to
|
||||
URLs specified in source maps. Be mindful of this in environments where the
|
||||
process has access to internal networks.
|
||||
|
||||
### `--no-deprecation`
|
||||
|
||||
Silence deprecation warnings.
|
||||
|
||||
@@ -124,65 +124,4 @@ Returns `Promise<Object>` - Resolves with an object containing the `value` and `
|
||||
Get the maximum usage across processes of trace buffer as a percentage of the
|
||||
full state.
|
||||
|
||||
### `contentTracing.enableHeapProfiling([options])` _Experimental_
|
||||
|
||||
<!--
|
||||
```YAML history
|
||||
added:
|
||||
- pr-url: https://github.com/electron/electron/pull/50826
|
||||
```
|
||||
-->
|
||||
|
||||
* `options` ([EnableHeapProfilingOptions](structures/enable-heap-profiling-options.md)) (optional)
|
||||
|
||||
Returns `Promise<void>` - Resolves once heap profiling has been enabled.
|
||||
|
||||
Enable [heap profiling](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/memory-infra/heap_profiler.md)
|
||||
for MemoryInfra traces. Equivalent to the `--memlog` switch in Chrome.
|
||||
|
||||
Only takes effect if the `disabled-by-default-memory-infra` category is included.
|
||||
|
||||
Needs to be called before `contentTracing.startRecording()`.
|
||||
|
||||
Usage:
|
||||
|
||||
```js
|
||||
const { contentTracing } = require('electron')
|
||||
|
||||
async function recordTrace () {
|
||||
await contentTracing.enableHeapProfiling()
|
||||
await contentTracing.startRecording({
|
||||
included_categories: ['disabled-by-default-memory-infra'],
|
||||
excluded_categories: ['*'],
|
||||
memory_dump_config: {
|
||||
triggers: [
|
||||
{ mode: 'detailed', periodic_interval_ms: 1000 }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
|
||||
const filePath = await contentTracing.stopRecording()
|
||||
}
|
||||
```
|
||||
|
||||
To view the recorded heap dumps:
|
||||
|
||||
1. Download the breakpad symbols for your Electron version from the Electron GitHub
|
||||
[releases](https://github.com/electron/electron/releases)
|
||||
2. Clone the [Electron source code](../development/build-instructions-gn.md)
|
||||
3. In your Chromium checkout for Electron, run this command to symbolicate the heap dump:
|
||||
|
||||
```bash
|
||||
python3 third_party/catapult/tracing/bin/symbolize_trace --use-breakpad-symbols --breakpad-symbols-directory /path/to/breakpad_symbols /path/to/trace.json
|
||||
```
|
||||
|
||||
4. Open the symbolicated trace in `chrome://tracing` (the Perfetto UI does not support memory dumps
|
||||
yet)
|
||||
5. Click on one of the `M` symbols
|
||||
6. Click on a `☰` triple bar icon (e.g., in the `malloc` column)
|
||||
|
||||
<img src="../images/viewing-heap-dumps.png" alt="Screenshot showing how to view a heapdump in Chromium's tracing view" />
|
||||
|
||||
[trace viewer]: https://chromium.googlesource.com/catapult/+/HEAD/tracing/README.md
|
||||
|
||||
@@ -28,10 +28,7 @@ added:
|
||||
* `window` [BaseWindow](base-window.md) (optional)
|
||||
* `options` Object
|
||||
* `title` string (optional)
|
||||
* `defaultPath` string (optional) - Absolute directory path, absolute file
|
||||
path, or file name to use by default. If not provided, the dialog will
|
||||
default to the user's Downloads folder, or their home directory if Downloads
|
||||
doesn't exist.
|
||||
* `defaultPath` string (optional)
|
||||
* `buttonLabel` string (optional) - Custom label for the confirmation button, when
|
||||
left empty the default label will be used.
|
||||
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
|
||||
@@ -112,10 +109,7 @@ changes:
|
||||
* `window` [BaseWindow](base-window.md) (optional)
|
||||
* `options` Object
|
||||
* `title` string (optional)
|
||||
* `defaultPath` string (optional) - Absolute directory path, absolute file
|
||||
path, or file name to use by default. If not provided, the dialog will
|
||||
default to the user's Downloads folder, or their home directory if Downloads
|
||||
doesn't exist.
|
||||
* `defaultPath` string (optional)
|
||||
* `buttonLabel` string (optional) - Custom label for the confirmation button, when
|
||||
left empty the default label will be used.
|
||||
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
|
||||
@@ -204,9 +198,7 @@ added:
|
||||
* `options` Object
|
||||
* `title` string (optional) - The dialog title. Cannot be displayed on some _Linux_ desktop environments.
|
||||
* `defaultPath` string (optional) - Absolute directory path, absolute file
|
||||
path, or file name to use by default. If not provided, the dialog will
|
||||
default to the user's Downloads folder, or their home directory if Downloads
|
||||
doesn't exist.
|
||||
path, or file name to use by default.
|
||||
* `buttonLabel` string (optional) - Custom label for the confirmation button, when
|
||||
left empty the default label will be used.
|
||||
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
|
||||
@@ -246,9 +238,7 @@ changes:
|
||||
* `options` Object
|
||||
* `title` string (optional) - The dialog title. Cannot be displayed on some _Linux_ desktop environments.
|
||||
* `defaultPath` string (optional) - Absolute directory path, absolute file
|
||||
path, or file name to use by default. If not provided, the dialog will
|
||||
default to the user's Downloads folder, or their home directory if Downloads
|
||||
doesn't exist.
|
||||
path, or file name to use by default.
|
||||
* `buttonLabel` string (optional) - Custom label for the confirmation button, when
|
||||
left empty the default label will be used.
|
||||
* `filters` [FileFilter[]](structures/file-filter.md) (optional)
|
||||
|
||||
@@ -56,9 +56,6 @@ Returns `string` - The badge string of the dock.
|
||||
|
||||
Hides the dock icon.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Known issue:** Calling `dock.hide()` within one second of a previous call will have no effect. As a workaround, ensure at least one second has elapsed between calls — for example, by deferring with a `setTimeout` of 1100ms or more after a previous call.
|
||||
|
||||
#### `dock.show()` _macOS_
|
||||
|
||||
Returns `Promise<void>` - Resolves when the dock icon is shown.
|
||||
|
||||
@@ -203,22 +203,13 @@ the one downloaded by `npm install`. Usage:
|
||||
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing
|
||||
```
|
||||
|
||||
### `ELECTRON_INSTALL_PLATFORM`
|
||||
### `ELECTRON_SKIP_BINARY_DOWNLOAD`
|
||||
|
||||
Manually overrides platform used by `electron` package during an install.
|
||||
This can be useful if you are on one platform (e.g macOS) but want to
|
||||
download binaries for another platform (e.g Windows or Linux). Usage:
|
||||
If you want to install your project's dependencies but don't need to use Electron functionality,
|
||||
you can set the `ELECTRON_SKIP_BINARY_DOWNLOAD` environment variable to prevent the binary from being
|
||||
downloaded. For instance, this feature can be useful in continuous integration environments when
|
||||
running unit tests that mock out the `electron` module.
|
||||
|
||||
```sh
|
||||
ELECTRON_INSTALL_PLATFORM=darwin npm install
|
||||
```
|
||||
|
||||
### `ELECTRON_INSTALL_ARCH`
|
||||
|
||||
Manually overrides architecture used by `electron` package during an install.
|
||||
This can be useful if you are on one arch (e.g `arm64`) but want to download
|
||||
binaries meant for another arch. Note that this will not work under Rosetta. Usage:
|
||||
|
||||
```sh
|
||||
ELECTRON_INSTALL_ARCH=arm64 npm install
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install
|
||||
```
|
||||
|
||||
@@ -31,7 +31,6 @@ See [`Menu`](menu.md) for examples.
|
||||
* `header` - Only available on macOS 14 and up.
|
||||
* `palette` - Only available on macOS 14 and up.
|
||||
* `label` string (optional)
|
||||
* `accessibilityLabel` string (optional) _macOS_
|
||||
* `sublabel` string (optional) _macOS_ - Available in macOS >= 14.4
|
||||
* `toolTip` string (optional) _macOS_ - Hover text for this menu item.
|
||||
* `accelerator` string (optional) - An [Accelerator](../tutorial/keyboard-shortcuts.md#accelerators) string.
|
||||
@@ -84,12 +83,6 @@ A `string` indicating the item's visible label.
|
||||
|
||||
This property can be dynamically changed.
|
||||
|
||||
#### `menuItem.accessibilityLabel` _macOS_
|
||||
|
||||
A `string` indicating the item's accessibility label (used by assistive technology), if set.
|
||||
|
||||
This property can be dynamically changed.
|
||||
|
||||
#### `menuItem.click`
|
||||
|
||||
A `Function` that is fired when the MenuItem receives a click event.
|
||||
|
||||
@@ -76,45 +76,6 @@ app.whenReady().then(() => {
|
||||
})
|
||||
```
|
||||
|
||||
#### `Notification.getHistory()` _macOS_
|
||||
|
||||
Returns `Promise<Notification[]>` - Resolves with an array of `Notification` objects representing all delivered notifications still present in Notification Center.
|
||||
|
||||
Each returned `Notification` is a live object connected to the corresponding delivered notification. Interaction events (`click`, `reply`, `action`, `close`) will fire on these objects when the user interacts with the notification in Notification Center. This is useful after an app restart to re-attach event handlers to notifications from a previous session.
|
||||
|
||||
The returned notifications have their `id`, `groupId`, `title`, `subtitle`, and `body` properties populated from information available in the Notification Center. Other properties (e.g., `actions`, `silent`, `icon`) are not available from delivered notifications and will have default values.
|
||||
|
||||
> [!NOTE]
|
||||
> Like all macOS notification APIs, this method requires the application to be
|
||||
> code-signed. In unsigned development builds, notifications are not delivered
|
||||
> to Notification Center and this method will resolve with an empty array.
|
||||
|
||||
> [!NOTE]
|
||||
> Unlike notifications created with `new Notification()`, notifications returned
|
||||
> by `getHistory()` will remain visible in Notification Center when the object
|
||||
> is garbage collected. Calling `show()` on a restored notification will remove
|
||||
> the original from Notification Center and post a new one with the same
|
||||
> properties.
|
||||
|
||||
```js
|
||||
const { Notification, app } = require('electron')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
// Restore notifications from a previous session
|
||||
const notifications = await Notification.getHistory()
|
||||
for (const n of notifications) {
|
||||
console.log(`Found delivered notification: ${n.id} - ${n.title}`)
|
||||
n.on('click', () => {
|
||||
console.log(`User clicked: ${n.id}`)
|
||||
})
|
||||
n.on('reply', (event) => {
|
||||
console.log(`User replied to ${n.id}: ${event.reply}`)
|
||||
})
|
||||
}
|
||||
// Keep references so events continue to fire
|
||||
})
|
||||
```
|
||||
|
||||
### `new Notification([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
@@ -331,10 +292,6 @@ call this method before the OS will display it.
|
||||
If the notification has been shown before, this method will dismiss the previously
|
||||
shown notification and create a new one with identical properties.
|
||||
|
||||
On macOS, calling `show()` on a notification returned by `Notification.getHistory()` will
|
||||
remove the original notification from Notification Center and post a new one with the same
|
||||
properties.
|
||||
|
||||
```js
|
||||
const { Notification, app } = require('electron')
|
||||
|
||||
|
||||
@@ -59,12 +59,7 @@ On Windows, returns true once the app has emitted the `ready` event.
|
||||
|
||||
### `safeStorage.isAsyncEncryptionAvailable()`
|
||||
|
||||
Returns `Promise<boolean>` - Resolves with whether encryption is available for
|
||||
asynchronous safeStorage operations.
|
||||
|
||||
The asynchronous encryptor is initialized lazily the first time this method,
|
||||
`encryptStringAsync`, or `decryptStringAsync` is called after the app is ready.
|
||||
The returned promise resolves once initialization completes.
|
||||
Returns `Promise<Boolean>` - Whether encryption is available for asynchronous safeStorage operations.
|
||||
|
||||
### `safeStorage.encryptString(plainText)`
|
||||
|
||||
|
||||
@@ -629,54 +629,6 @@ Emitted after `USBDevice.forget()` has been called. This event can be used
|
||||
to help maintain persistent storage of permissions when
|
||||
`setDevicePermissionHandler` is used.
|
||||
|
||||
#### Event: 'select-webauthn-account'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `relyingPartyId` string - The relying party identifier from the WebAuthn request.
|
||||
* `accounts` [WebAuthnAccount[]](structures/webauthn-account.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `callback` Function
|
||||
* `credentialId` string | null (optional)
|
||||
|
||||
Emitted when a call to `navigator.credentials.get()` resolves multiple
|
||||
discoverable WebAuthn credentials and the user must choose one. `callback`
|
||||
should be called with the `credentialId` of the selected account; passing no
|
||||
arguments — or a `credentialId` that does not match one of the provided
|
||||
accounts — will cancel the request and the page will receive a
|
||||
`NotAllowedError`. If no listener is registered for this event, the request is
|
||||
cancelled with the same error. The credential request remains pending until
|
||||
the listener invokes the callback, so always invoke it exactly once — typically
|
||||
from a `try { … } finally { callback(…) }` block.
|
||||
|
||||
On macOS, the Touch ID platform authenticator surfaces accounts via this event
|
||||
once it has been configured with
|
||||
[`app.configureWebAuthn`](app.md#appconfigurewebauthnoptions-macos). The event
|
||||
may also fire on other platforms when a roaming FIDO2 authenticator returns
|
||||
multiple discoverable credentials.
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.configureWebAuthn({
|
||||
touchID: { keychainAccessGroup: 'A1B2C3D4E5.com.example.app.webauthn' }
|
||||
})
|
||||
|
||||
win = new BrowserWindow()
|
||||
|
||||
win.webContents.session.on('select-webauthn-account', (event, details, callback) => {
|
||||
const selected = details.accounts.find((a) => a.name === 'alice@example.com')
|
||||
callback(selected?.credentialId)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Instance Methods
|
||||
|
||||
The following methods are available on instances of `Session`:
|
||||
@@ -698,7 +650,7 @@ Clears the session’s HTTP cache.
|
||||
`scheme://host:port`.
|
||||
* `storages` string[] (optional) - The types of storages to clear, can be
|
||||
`cookies`, `filesystem`, `indexdb`, `localstorage`,
|
||||
`shadercache`, `serviceworkers`, `cachestorage`. If not
|
||||
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
|
||||
specified, clear all storage types.
|
||||
|
||||
Returns `Promise<void>` - resolves when the storage data has been cleared.
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# EnableHeapProfilingOptions Object
|
||||
|
||||
* `mode` string (optional) - Controls which processes are profiled. Equivalent to `--memlog` in
|
||||
Chrome. Default is `all`.
|
||||
* `all` - Profile all processes.
|
||||
* `browser` - Profile only the browser process.
|
||||
* `gpu` - Profile only the GPU process.
|
||||
* `minimal` - Profile only the browser and GPU processes.
|
||||
* `renderer-sampling` - Profile at most 1 renderer process. Each renderer process has a fixed
|
||||
probability of being profiled when the renderer process is started or, for existing processes,
|
||||
when heap profiling is enabled.
|
||||
* `all-renderers` - Profile all renderer processes.
|
||||
* `utility-sampling` - Each utility process has a fixed probability of being profiled.
|
||||
* `all-utilities` - Profile all utility processes.
|
||||
* `utility-and-browser` - Profile all utility processes and the browser process.
|
||||
* `samplingRate` number (optional) - Controls the sampling interval in bytes. The lower the
|
||||
interval, the more precise the profile is. However it comes at the cost of performance. Default
|
||||
is `100000` (100KB). That is enough to observe allocation sites that make allocations >500KB
|
||||
total, where total equals to a single allocation size times the number of such allocations at the
|
||||
same call site. Equivalent to `--memlog-sampling-rate` in Chrome. Must be an integer between
|
||||
`1000` and `10000000`.
|
||||
* `stackMode` string (optional) - Controls the type of metadata recorded for each allocation.
|
||||
Equivalent to `--memlog-stack-mode` in Chrome. Default is `native`.
|
||||
* `native` - Instruction addresses from unwinding the stack.
|
||||
* `native-with-thread-names` - Instruction addresses from unwinding the stack. Includes the thread
|
||||
name as the first frame.
|
||||
@@ -5,7 +5,6 @@
|
||||
* `rgba` - 32bpp RGBA (byte-order), 1 plane.
|
||||
* `rgbaf16` - Half float RGBA, 1 plane.
|
||||
* `nv12` - 12bpp with Y plane followed by a 2x2 interleaved UV plane.
|
||||
* `nv16` - 16bpp with Y plane followed by a 2x1 interleaved UV plane.
|
||||
* `p010le` - 4:2:0 10-bit YUV (little-endian), Y plane followed by a 2x2 interleaved UV plane.
|
||||
* `colorSpace` [ColorSpace](color-space.md) (optional) - The color space of the texture.
|
||||
* `codedSize` [Size](size.md) - The full dimensions of the shared texture.
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
The actual output pixel format and color space of the texture should refer to [`OffscreenSharedTexture`](../structures/offscreen-shared-texture.md) object in the `paint` event.
|
||||
* `argb` - The requested output texture format is 8-bit unorm RGBA, with SRGB SDR color space.
|
||||
* `rgbaf16` - The requested output texture format is 16-bit float RGBA, with scRGB HDR color space.
|
||||
* `nv12` - The requested output texture format is 12bpp with Y plane followed by a 2x2 interleaved UV plane, with REC709 color space.
|
||||
* `deviceScaleFactor` number (optional) _Experimental_ - The device scale factor of the offscreen rendering output. If not set, will use `1` as default.
|
||||
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
||||
the specified `preload` script in a separate JavaScript context. Defaults
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# WebAuthnAccount Object
|
||||
|
||||
* `credentialId` string - URL-safe base64-encoded (no padding) credential ID of
|
||||
the discoverable credential. Matches `PublicKeyCredential.id` returned by
|
||||
`navigator.credentials.get()` in the renderer.
|
||||
* `userHandle` string (optional) - URL-safe base64-encoded (no padding) user
|
||||
handle (`user.id`) that was provided when the credential was created.
|
||||
* `name` string (optional) - Human-palatable identifier for the account (for example, an email address or username).
|
||||
* `displayName` string (optional) - Human-palatable name for the account, intended for display.
|
||||
@@ -17,16 +17,6 @@ Process: [Main](../glossary.md#main-process)<br />
|
||||
* `env` Object (optional) - Environment key-value pairs. Default is `process.env`.
|
||||
* `execArgv` string[] (optional) - List of string arguments passed to the executable.
|
||||
* `cwd` string (optional) - Current working directory of the child process.
|
||||
* `session` [Session](session.md) (optional) - Sets the session used by the process for network
|
||||
requests. By default, network requests from the utility process will use the system network
|
||||
context which does not have HTTP cache support. Setting a session enables HTTP caching and
|
||||
other session-specific network features. See [session](session.md) for more information.
|
||||
* `partition` string (optional) - Sets the session used by the process according to the
|
||||
session's partition string. If `partition` starts with `persist:`, the process will use a
|
||||
persistent session available to all pages in the app with the same `partition`. If there is
|
||||
no `persist:` prefix, the process will use an in-memory session. By assigning the same
|
||||
`partition`, multiple processes can share the same session. If the `session` option is set,
|
||||
this option is ignored.
|
||||
* `stdio` (string[] | string) (optional) - Allows configuring the mode for `stdout` and `stderr`
|
||||
of the child process. Default is `inherit`.
|
||||
String value can be one of `pipe`, `ignore`, `inherit`, for more details on these values you can refer to
|
||||
@@ -54,9 +44,7 @@ Process: [Main](../glossary.md#main-process)<br />
|
||||
that run third-party or otherwise untrusted code. Default is `false`.
|
||||
* `respondToAuthRequestsFromMainProcess` boolean (optional) - With this flag, all HTTP 401 and 407 network
|
||||
requests created via the [net module](net.md) will allow responding to them via the
|
||||
[`login`](#event-login) event on the `UtilityProcess` instance when a `session` is provided, or via
|
||||
the [`app#login`](app.md#event-login) event in the main process when using the default system network
|
||||
context. Without this flag, auth challenges are handled by the default
|
||||
[`app#login`](app.md#event-login) event in the main process instead of the default
|
||||
[`login`](client-request.md#event-login) event on the [`ClientRequest`](client-request.md) object. Default is
|
||||
`false`.
|
||||
|
||||
@@ -188,45 +176,6 @@ Returns:
|
||||
|
||||
Emitted when the child process sends a message using [`process.parentPort.postMessage()`](process.md#processparentport).
|
||||
|
||||
#### Event: 'login'
|
||||
|
||||
Returns:
|
||||
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `pid` number
|
||||
* `authInfo` Object
|
||||
* `isProxy` boolean
|
||||
* `scheme` string
|
||||
* `host` string
|
||||
* `port` Integer
|
||||
* `realm` string
|
||||
* `callback` Function
|
||||
* `username` string (optional)
|
||||
* `password` string (optional)
|
||||
|
||||
Emitted when the utility process encounters an HTTP 401 or 407 authentication challenge, if the
|
||||
process was created with both `respondToAuthRequestsFromMainProcess: true` and a `session` option.
|
||||
The `callback` should be called with credentials to respond to the challenge. Calling `callback`
|
||||
without arguments will cancel the request.
|
||||
|
||||
This behaves the same as the [`login` event on `app`](app.md#event-login) but is scoped to the
|
||||
individual utility process instance.
|
||||
|
||||
```js
|
||||
const { session, utilityProcess } = require('electron')
|
||||
|
||||
const ses = session.defaultSession
|
||||
const child = utilityProcess.fork('./worker.js', [], {
|
||||
session: ses,
|
||||
respondToAuthRequestsFromMainProcess: true
|
||||
})
|
||||
|
||||
child.on('login', (authenticationResponseDetails, authInfo, callback) => {
|
||||
callback('username', 'password')
|
||||
})
|
||||
```
|
||||
|
||||
[`child_process.fork`]: https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options
|
||||
[Services API]: https://chromium.googlesource.com/chromium/src/+/main/docs/mojo_and_services.md
|
||||
[stdio]: https://nodejs.org/dist/latest/docs/api/child_process.html#optionsstdio
|
||||
|
||||
@@ -117,13 +117,6 @@ Examples of valid `color` values:
|
||||
> [!NOTE]
|
||||
> The area cutout of the view's border still captures clicks.
|
||||
|
||||
#### `view.setBackgroundBlur(blurRadius)`
|
||||
|
||||
* `blurRadius` Integer - The radius of the background blur effect (in pixels).
|
||||
|
||||
> [!NOTE]
|
||||
> You must set a background color with an alpha channel (e.g. `#80ffffff`) in order for the blur effect to be visible.
|
||||
|
||||
#### `view.setVisible(visible)`
|
||||
|
||||
* `visible` boolean - If false, the view will be hidden from display.
|
||||
|
||||
@@ -226,16 +226,7 @@ Returns:
|
||||
Only defined when the window is being created by a form that set
|
||||
`target=_blank`.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window` or `other`. Corresponds to the manner
|
||||
an associated link was clicked. See Chromium's
|
||||
[WindowOpenDisposition](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/window_open_disposition.h).
|
||||
* `default` - Indicates Chromium deems in-window navigation valid
|
||||
for a window open call.
|
||||
* `foreground-tab` - Corresponds to a left click or shift + middle click.
|
||||
* `background-tab` - Corresponds to a middle click or ctrl/cmd + click.
|
||||
* `new-window` - Corresponds to a shift + left click.
|
||||
* `other` - A catch-all for the remaining Chromium dispositions not
|
||||
handled by Electron.
|
||||
`background-tab`, `new-window` or `other`.
|
||||
|
||||
Emitted _after_ successful creation of a window via `window.open` in the renderer.
|
||||
Not emitted if the creation of the window is canceled from
|
||||
@@ -1458,17 +1449,8 @@ Ignore application menu shortcuts while this web contents is focused.
|
||||
* `url` string - The _resolved_ version of the URL passed to `window.open()`. e.g. opening a window with `window.open('foo')` will yield something like `https://the-origin/the/current/path/foo`.
|
||||
* `frameName` string - Name of the window provided in `window.open()`
|
||||
* `features` string - Comma separated list of window features provided to `window.open()`.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window` or `other`. Corresponds to the manner
|
||||
an associated link was clicked. See Chromium's
|
||||
[WindowOpenDisposition](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/window_open_disposition.h).
|
||||
* `default` - Indicates Chromium deems in-window navigation valid
|
||||
for a window open call.
|
||||
* `foreground-tab` - Corresponds to a left click or shift + middle click.
|
||||
* `background-tab` - Corresponds to a middle click or ctrl/cmd + click.
|
||||
* `new-window` - Corresponds to a shift + left click.
|
||||
* `other` - A catch-all for the remaining Chromium dispositions not
|
||||
handled by Electron.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
|
||||
`new-window` or `other`.
|
||||
* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
|
||||
passed to the new window. May or may not result in the `Referer` header being
|
||||
sent, depending on the referrer policy.
|
||||
@@ -1603,20 +1585,6 @@ Centers the current text selection in web page.
|
||||
|
||||
Copy the image at the given position to the clipboard.
|
||||
|
||||
#### `contents.copyVideoFrameAt(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
When executed on a video media element, copies the frame at (x, y) to the clipboard.
|
||||
|
||||
#### `contents.saveVideoFrameAs(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
When executed on a video media element, shows a save dialog and saves the frame at (x, y) to disk.
|
||||
|
||||
#### `contents.paste()`
|
||||
|
||||
Executes the editing command `paste` in web page.
|
||||
@@ -2293,20 +2261,6 @@ Returns `Integer` - The Chromium internal `pid` of the associated renderer. Can
|
||||
be compared to the `frameProcessId` passed by frame specific navigation events
|
||||
(e.g. `did-frame-navigate`)
|
||||
|
||||
#### `contents.clone()`
|
||||
|
||||
Returns `WebContents` - A cloned WebContents instance. This method creates a copy
|
||||
of the WebContents with the following attributes:
|
||||
|
||||
* **WebPreferences** - All preferences from the original WebContents are copied
|
||||
* **SiteInstance** - Uses the same SiteInstance as the original. This means the cloned WebContents will reuse the same render process as the original when loading same-origin pages, and only spawn a new render process for cross-origin navigations. This process allocation behavior is consistent with window.open and tab duplication in Chromium. For more details, see [Chromium's Site Isolation](https://www.chromium.org/developers/design-documents/site-isolation/) design document.
|
||||
* **Opener relationship** - Inherits the opener (window.opener) relationship
|
||||
* **Navigation state** - Copies the navigation history and controller state
|
||||
|
||||
The cloned WebContents is an independent instance with its own lifecycle that can be destroyed separately and will not contain any open web pages.
|
||||
|
||||
This API is useful for use cases where you want to create a new WebContents that shares the same render process with the original for same-origin content, while maintaining full lifecycle independence. Additionally, reusing the existing render process can help optimize memory usage and page load speed to a certain extent, as it eliminates the overhead of spawning and initializing a new render process from scratch.
|
||||
|
||||
#### `contents.takeHeapSnapshot(filePath)`
|
||||
|
||||
* `filePath` string - Path to the output file.
|
||||
|
||||
@@ -175,20 +175,6 @@ app.on('web-contents-created', (_, webContents) => {
|
||||
})
|
||||
```
|
||||
|
||||
#### `frame.copyVideoFrameAt(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
When executed on a video media element, copies the frame at (x, y) to the clipboard.
|
||||
|
||||
#### `frame.saveVideoFrameAs(x, y)`
|
||||
|
||||
* `x` Integer
|
||||
* `y` Integer
|
||||
|
||||
When executed on a video media element, shows a save dialog and saves the frame at (x, y) to disk.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `frame.ipc` _Readonly_
|
||||
|
||||
@@ -12,45 +12,6 @@ This document uses the following convention to categorize breaking changes:
|
||||
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (43.0)
|
||||
|
||||
### Behavior Changed: `chrome.scripting` CSS injection matches more fallback frames
|
||||
|
||||
Extensions using `chrome.scripting.insertCSS()` or `chrome.scripting.removeCSS()`
|
||||
now follow Chrome's behavior when Electron cannot match a frame's URL directly,
|
||||
such as with `about:blank` or `data:` frames. If the extension has access to the
|
||||
page that created the frame, CSS may now be inserted into or removed from those
|
||||
fallback frames as well.
|
||||
|
||||
Apps or extensions that relied on Electron skipping those frames should narrow their
|
||||
injection target, frame IDs, or match patterns.
|
||||
|
||||
### Behavior Changed: Dialog methods default to Downloads directory
|
||||
|
||||
The `defaultPath` option for the following methods now defaults to the user's Downloads folder (or their home directory if Downloads doesn't exist) when not explicitly provided:
|
||||
|
||||
* `dialog.showOpenDialog`
|
||||
* `dialog.showOpenDialogSync`
|
||||
* `dialog.showSaveDialog`
|
||||
* `dialog.showSaveDialogSync`
|
||||
|
||||
Previously, when no `defaultPath` was provided, the underlying OS file dialog would determine the initial directory — typically remembering the last directory the user navigated to, or falling back to an OS-specific default. Now, Electron explicitly sets the initial directory to Downloads, which also means the OS will no longer track and restore the last-used directory between dialog invocations.
|
||||
|
||||
To preserve the old behavior, you can track the last-used directory yourself and pass it as `defaultPath`:
|
||||
|
||||
```js
|
||||
const path = require('node:path')
|
||||
|
||||
let lastUsedPath
|
||||
const result = await dialog.showOpenDialog({
|
||||
defaultPath: lastUsedPath
|
||||
})
|
||||
|
||||
if (!result.canceled && result.filePaths.length > 0) {
|
||||
lastUsedPath = path.dirname(result.filePaths[0])
|
||||
}
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (42.0)
|
||||
|
||||
### Behavior Changed: macOS notifications now use `UNNotification` API
|
||||
@@ -134,12 +95,6 @@ When a cookie is deleted, the change cause remains `explicit`.
|
||||
When the cookie being set is identical to an existing one (same name, domain, path, and value, with no actual changes), the change cause is `inserted-no-change-overwrite`.
|
||||
When the value of the cookie being set remains unchanged but some of its attributes are updated, such as the expiration attribute, the change cause will be `inserted-no-value-change-overwrite`.
|
||||
|
||||
### Deprecated: `showHiddenFiles` in Dialogs on Linux
|
||||
|
||||
This property will still be honored on macOS and Windows, but support on Linux
|
||||
will be removed in Electron 42. GTK intends for this to be a user choice rather
|
||||
than an app choice and has removed the API to do this programmatically.
|
||||
|
||||
## Planned Breaking API Changes (40.0)
|
||||
|
||||
### Deprecated: `clipboard` API access from renderer processes
|
||||
@@ -153,6 +108,12 @@ your preload script and expose it using the [contextBridge](https://www.electron
|
||||
Debug symbols for MacOS (dSYM) now use xz compression in order to handle larger file sizes. `dsym.zip` files are now
|
||||
`dsym.tar.xz` files. End users using debug symbols may need to update their zip utilities.
|
||||
|
||||
### Deprecated: `showHiddenFiles` in Dialogs on Linux
|
||||
|
||||
This property will still be honored on macOS and Windows, but support on Linux
|
||||
will be removed in Electron 42. GTK intends for this to be a user choice rather
|
||||
than an app choice and has removed the API to do this programmatically.
|
||||
|
||||
## Planned Breaking API Changes (39.0)
|
||||
|
||||
### Deprecated: `--host-rules` command line switch
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
These are the style guidelines for coding in Electron.
|
||||
|
||||
You can run `npm run lint` to show any style issues detected by `cpplint` and
|
||||
`oxlint`.
|
||||
`eslint`.
|
||||
|
||||
## General Code
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB |
@@ -87,13 +87,6 @@ if (!gotTheLock) {
|
||||
// Create mainWindow, load the rest of the app, etc...
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
// Check for deep link on cold start
|
||||
if (process.argv.length >= 2) {
|
||||
const lastArg = process.argv[process.argv.length - 1]
|
||||
if (lastArg.startsWith('electron-fiddle://')) {
|
||||
dialog.showErrorBox('Welcome Back', `You arrived from: ${lastArg}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -107,7 +107,7 @@ When signing the app with `@electron/osx-sign`, it will automatically add the
|
||||
necessary entitlements to your app's entitlements.
|
||||
|
||||
<details>
|
||||
<summary>Extra steps without `@electron/osx-sign`</summary>
|
||||
<summary>Extra steps without `electron-osx-sign`</summary>
|
||||
|
||||
If you are signing your app without using `@electron/osx-sign`, you must ensure
|
||||
the app bundle's entitlements have at least following keys:
|
||||
|
||||
@@ -91,7 +91,6 @@ auto_filenames = {
|
||||
"docs/api/structures/custom-scheme.md",
|
||||
"docs/api/structures/desktop-capturer-source.md",
|
||||
"docs/api/structures/display.md",
|
||||
"docs/api/structures/enable-heap-profiling-options.md",
|
||||
"docs/api/structures/extension-info.md",
|
||||
"docs/api/structures/extension.md",
|
||||
"docs/api/structures/file-filter.md",
|
||||
@@ -171,355 +170,15 @@ auto_filenames = {
|
||||
"docs/api/structures/web-preferences.md",
|
||||
"docs/api/structures/web-request-filter.md",
|
||||
"docs/api/structures/web-source.md",
|
||||
"docs/api/structures/webauthn-account.md",
|
||||
"docs/api/structures/window-open-handler-response.md",
|
||||
"docs/api/structures/window-session-end-event.md",
|
||||
]
|
||||
|
||||
node_header_sources = [
|
||||
"../third_party/electron_node/src/acorn_version.h",
|
||||
"../third_party/electron_node/src/aliased_buffer-inl.h",
|
||||
"../third_party/electron_node/src/aliased_buffer.h",
|
||||
"../third_party/electron_node/src/aliased_struct-inl.h",
|
||||
"../third_party/electron_node/src/aliased_struct.h",
|
||||
"../third_party/electron_node/src/amaro_version.h",
|
||||
"../third_party/electron_node/src/async_context_frame.h",
|
||||
"../third_party/electron_node/src/async_wrap-inl.h",
|
||||
"../third_party/electron_node/src/async_wrap.h",
|
||||
"../third_party/electron_node/src/base_object-inl.h",
|
||||
"../third_party/electron_node/src/base_object.h",
|
||||
"../third_party/electron_node/src/base_object_types.h",
|
||||
"../third_party/electron_node/src/blob_serializer_deserializer-inl.h",
|
||||
"../third_party/electron_node/src/blob_serializer_deserializer.h",
|
||||
"../third_party/electron_node/src/callback_queue-inl.h",
|
||||
"../third_party/electron_node/src/callback_queue.h",
|
||||
"../third_party/electron_node/src/cares_wrap.h",
|
||||
"../third_party/electron_node/src/cleanup_queue-inl.h",
|
||||
"../third_party/electron_node/src/cleanup_queue.h",
|
||||
"../third_party/electron_node/src/compile_cache.h",
|
||||
"../third_party/electron_node/src/connect_wrap.h",
|
||||
"../third_party/electron_node/src/connection_wrap.h",
|
||||
"../third_party/electron_node/src/cppgc_helpers-inl.h",
|
||||
"../third_party/electron_node/src/cppgc_helpers.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_aes.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_argon2.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_bio.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_chacha20_poly1305.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_cipher.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_clienthello-inl.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_clienthello.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_common.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_context.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_dh.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_dsa.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_ec.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_hash.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_hkdf.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_hmac.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_kem.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_keygen.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_keys.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_kmac.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_ml_dsa.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_pbkdf2.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_random.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_rsa.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_scrypt.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_sig.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_spkac.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_timing.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_tls.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_util.h",
|
||||
"../third_party/electron_node/src/crypto/crypto_x509.h",
|
||||
"../third_party/electron_node/src/dataqueue/queue.h",
|
||||
"../third_party/electron_node/src/debug_utils-inl.h",
|
||||
"../third_party/electron_node/src/debug_utils.h",
|
||||
"../third_party/electron_node/src/diagnosticfilename-inl.h",
|
||||
"../third_party/electron_node/src/embedded_data.h",
|
||||
"../third_party/electron_node/src/encoding_binding.h",
|
||||
"../third_party/electron_node/src/env-inl.h",
|
||||
"../third_party/electron_node/src/env.h",
|
||||
"../third_party/electron_node/src/env_properties.h",
|
||||
"../third_party/electron_node/src/handle_wrap.h",
|
||||
"../third_party/electron_node/src/histogram-inl.h",
|
||||
"../third_party/electron_node/src/histogram.h",
|
||||
"../third_party/electron_node/src/inspector/io_agent.h",
|
||||
"../third_party/electron_node/src/inspector/main_thread_interface.h",
|
||||
"../third_party/electron_node/src/inspector/network_agent.h",
|
||||
"../third_party/electron_node/src/inspector/network_inspector.h",
|
||||
"../third_party/electron_node/src/inspector/network_requests_buffer.h",
|
||||
"../third_party/electron_node/src/inspector/network_resource_manager.h",
|
||||
"../third_party/electron_node/src/inspector/node_json.h",
|
||||
"../third_party/electron_node/src/inspector/node_string.h",
|
||||
"../third_party/electron_node/src/inspector/protocol_helper.h",
|
||||
"../third_party/electron_node/src/inspector/runtime_agent.h",
|
||||
"../third_party/electron_node/src/inspector/target_agent.h",
|
||||
"../third_party/electron_node/src/inspector/tracing_agent.h",
|
||||
"../third_party/electron_node/src/inspector/worker_agent.h",
|
||||
"../third_party/electron_node/src/inspector/worker_inspector.h",
|
||||
"../third_party/electron_node/src/inspector_agent.h",
|
||||
"../third_party/electron_node/src/inspector_io.h",
|
||||
"../third_party/electron_node/src/inspector_profiler.h",
|
||||
"../third_party/electron_node/src/inspector_socket.h",
|
||||
"../third_party/electron_node/src/inspector_socket_server.h",
|
||||
"../third_party/electron_node/src/js_native_api.h",
|
||||
"../third_party/electron_node/src/js_native_api_types.h",
|
||||
"../third_party/electron_node/src/js_native_api_v8.h",
|
||||
"../third_party/electron_node/src/js_native_api_v8_internals.h",
|
||||
"../third_party/electron_node/src/js_stream.h",
|
||||
"../third_party/electron_node/src/json_utils.h",
|
||||
"../third_party/electron_node/src/large_pages/node_large_page.h",
|
||||
"../third_party/electron_node/src/lru_cache-inl.h",
|
||||
"../third_party/electron_node/src/memory_tracker-inl.h",
|
||||
"../third_party/electron_node/src/memory_tracker.h",
|
||||
"../third_party/electron_node/src/module_wrap.h",
|
||||
"../third_party/electron_node/src/node.h",
|
||||
"../third_party/electron_node/src/node_api.h",
|
||||
"../third_party/electron_node/src/node_api_internals.h",
|
||||
"../third_party/electron_node/src/node_api_types.h",
|
||||
"../third_party/electron_node/src/node_binding.h",
|
||||
"../third_party/electron_node/src/node_blob.h",
|
||||
"../third_party/electron_node/src/node_bob-inl.h",
|
||||
"../third_party/electron_node/src/node_bob.h",
|
||||
"../third_party/electron_node/src/node_buffer.h",
|
||||
"../third_party/electron_node/src/node_builtins.h",
|
||||
"../third_party/electron_node/src/node_config_file.h",
|
||||
"../third_party/electron_node/src/node_constants.h",
|
||||
"../third_party/electron_node/src/node_context_data.h",
|
||||
"../third_party/electron_node/src/node_contextify.h",
|
||||
"../third_party/electron_node/src/node_crypto.h",
|
||||
"../third_party/electron_node/src/node_debug.h",
|
||||
"../third_party/electron_node/src/node_dir.h",
|
||||
"../third_party/electron_node/src/node_dotenv.h",
|
||||
"../third_party/electron_node/src/node_errors.h",
|
||||
"../third_party/electron_node/src/node_exit_code.h",
|
||||
"../third_party/electron_node/src/node_external_reference.h",
|
||||
"../third_party/electron_node/src/node_file-inl.h",
|
||||
"../third_party/electron_node/src/node_file.h",
|
||||
"../third_party/electron_node/src/node_http2.h",
|
||||
"../third_party/electron_node/src/node_http2_state.h",
|
||||
"../third_party/electron_node/src/node_http_common-inl.h",
|
||||
"../third_party/electron_node/src/node_http_common.h",
|
||||
"../third_party/electron_node/src/node_i18n.h",
|
||||
"../third_party/electron_node/src/node_internals.h",
|
||||
"../third_party/electron_node/src/node_locks.h",
|
||||
"../third_party/electron_node/src/node_main_instance.h",
|
||||
"../third_party/electron_node/src/node_mem-inl.h",
|
||||
"../third_party/electron_node/src/node_mem.h",
|
||||
"../third_party/electron_node/src/node_messaging.h",
|
||||
"../third_party/electron_node/src/node_metadata.h",
|
||||
"../third_party/electron_node/src/node_modules.h",
|
||||
"../third_party/electron_node/src/node_mutex.h",
|
||||
"../third_party/electron_node/src/node_object_wrap.h",
|
||||
"../third_party/electron_node/src/node_options-inl.h",
|
||||
"../third_party/electron_node/src/node_options.h",
|
||||
"../third_party/electron_node/src/node_perf.h",
|
||||
"../third_party/electron_node/src/node_perf_common.h",
|
||||
"../third_party/electron_node/src/node_platform.h",
|
||||
"../third_party/electron_node/src/node_process-inl.h",
|
||||
"../third_party/electron_node/src/node_process.h",
|
||||
"../third_party/electron_node/src/node_realm-inl.h",
|
||||
"../third_party/electron_node/src/node_realm.h",
|
||||
"../third_party/electron_node/src/node_report.h",
|
||||
"../third_party/electron_node/src/node_revert.h",
|
||||
"../third_party/electron_node/src/node_root_certs.h",
|
||||
"../third_party/electron_node/src/node_sea.h",
|
||||
"../third_party/electron_node/src/node_shadow_realm.h",
|
||||
"../third_party/electron_node/src/node_snapshot_builder.h",
|
||||
"../third_party/electron_node/src/node_snapshotable.h",
|
||||
"../third_party/electron_node/src/node_sockaddr-inl.h",
|
||||
"../third_party/electron_node/src/node_sockaddr.h",
|
||||
"../third_party/electron_node/src/node_sqlite.h",
|
||||
"../third_party/electron_node/src/node_stat_watcher.h",
|
||||
"../third_party/electron_node/src/node_task_runner.h",
|
||||
"../third_party/electron_node/src/node_threadsafe_cow-inl.h",
|
||||
"../third_party/electron_node/src/node_threadsafe_cow.h",
|
||||
"../third_party/electron_node/src/node_union_bytes.h",
|
||||
"../third_party/electron_node/src/node_url.h",
|
||||
"../third_party/electron_node/src/node_url_pattern.h",
|
||||
"../third_party/electron_node/src/node_v8.h",
|
||||
"../third_party/electron_node/src/node_v8_platform-inl.h",
|
||||
"../third_party/electron_node/src/node_version.h",
|
||||
"../third_party/electron_node/src/node_wasi.h",
|
||||
"../third_party/electron_node/src/node_wasm_web_api.h",
|
||||
"../third_party/electron_node/src/node_watchdog.h",
|
||||
"../third_party/electron_node/src/node_webstorage.h",
|
||||
"../third_party/electron_node/src/node_worker.h",
|
||||
"../third_party/electron_node/src/path.h",
|
||||
"../third_party/electron_node/src/permission/addon_permission.h",
|
||||
"../third_party/electron_node/src/permission/child_process_permission.h",
|
||||
"../third_party/electron_node/src/permission/fs_permission.h",
|
||||
"../third_party/electron_node/src/permission/inspector_permission.h",
|
||||
"../third_party/electron_node/src/permission/permission.h",
|
||||
"../third_party/electron_node/src/permission/permission_base.h",
|
||||
"../third_party/electron_node/src/permission/wasi_permission.h",
|
||||
"../third_party/electron_node/src/permission/worker_permission.h",
|
||||
"../third_party/electron_node/src/pipe_wrap.h",
|
||||
"../third_party/electron_node/src/quic/application.h",
|
||||
"../third_party/electron_node/src/quic/bindingdata.h",
|
||||
"../third_party/electron_node/src/quic/cid.h",
|
||||
"../third_party/electron_node/src/quic/data.h",
|
||||
"../third_party/electron_node/src/quic/defs.h",
|
||||
"../third_party/electron_node/src/quic/endpoint.h",
|
||||
"../third_party/electron_node/src/quic/http3.h",
|
||||
"../third_party/electron_node/src/quic/logstream.h",
|
||||
"../third_party/electron_node/src/quic/packet.h",
|
||||
"../third_party/electron_node/src/quic/preferredaddress.h",
|
||||
"../third_party/electron_node/src/quic/session.h",
|
||||
"../third_party/electron_node/src/quic/sessionticket.h",
|
||||
"../third_party/electron_node/src/quic/streams.h",
|
||||
"../third_party/electron_node/src/quic/tlscontext.h",
|
||||
"../third_party/electron_node/src/quic/tokens.h",
|
||||
"../third_party/electron_node/src/quic/transportparams.h",
|
||||
"../third_party/electron_node/src/req_wrap-inl.h",
|
||||
"../third_party/electron_node/src/req_wrap.h",
|
||||
"../third_party/electron_node/src/spawn_sync.h",
|
||||
"../third_party/electron_node/src/stream_base-inl.h",
|
||||
"../third_party/electron_node/src/stream_base.h",
|
||||
"../third_party/electron_node/src/stream_pipe.h",
|
||||
"../third_party/electron_node/src/stream_wrap.h",
|
||||
"../third_party/electron_node/src/string_bytes.h",
|
||||
"../third_party/electron_node/src/string_decoder-inl.h",
|
||||
"../third_party/electron_node/src/string_decoder.h",
|
||||
"../third_party/electron_node/src/tcp_wrap.h",
|
||||
"../third_party/electron_node/src/threadpoolwork-inl.h",
|
||||
"../third_party/electron_node/src/timer_wrap-inl.h",
|
||||
"../third_party/electron_node/src/timer_wrap.h",
|
||||
"../third_party/electron_node/src/timers.h",
|
||||
"../third_party/electron_node/src/tracing/agent.h",
|
||||
"../third_party/electron_node/src/tracing/node_trace_buffer.h",
|
||||
"../third_party/electron_node/src/tracing/node_trace_writer.h",
|
||||
"../third_party/electron_node/src/tracing/trace_categories.h",
|
||||
"../third_party/electron_node/src/tracing/trace_event.h",
|
||||
"../third_party/electron_node/src/tracing/trace_event_common.h",
|
||||
"../third_party/electron_node/src/tracing/traced_value.h",
|
||||
"../third_party/electron_node/src/tty_wrap.h",
|
||||
"../third_party/electron_node/src/udp_wrap.h",
|
||||
"../third_party/electron_node/src/undici_version.h",
|
||||
"../third_party/electron_node/src/util-inl.h",
|
||||
"../third_party/electron_node/src/util.h",
|
||||
"../third_party/electron_node/src/zlib_version.h",
|
||||
"../third_party/electron_node/tools/install.py",
|
||||
"../v8/include/cppgc/allocation.h",
|
||||
"../v8/include/cppgc/common.h",
|
||||
"../v8/include/cppgc/cross-thread-persistent.h",
|
||||
"../v8/include/cppgc/custom-space.h",
|
||||
"../v8/include/cppgc/default-platform.h",
|
||||
"../v8/include/cppgc/explicit-management.h",
|
||||
"../v8/include/cppgc/garbage-collected.h",
|
||||
"../v8/include/cppgc/heap-consistency.h",
|
||||
"../v8/include/cppgc/heap-handle.h",
|
||||
"../v8/include/cppgc/heap-state.h",
|
||||
"../v8/include/cppgc/heap-statistics.h",
|
||||
"../v8/include/cppgc/heap.h",
|
||||
"../v8/include/cppgc/internal/api-constants.h",
|
||||
"../v8/include/cppgc/internal/atomic-entry-flag.h",
|
||||
"../v8/include/cppgc/internal/base-page-handle.h",
|
||||
"../v8/include/cppgc/internal/caged-heap-local-data.h",
|
||||
"../v8/include/cppgc/internal/caged-heap.h",
|
||||
"../v8/include/cppgc/internal/compiler-specific.h",
|
||||
"../v8/include/cppgc/internal/conditional-stack-allocated.h",
|
||||
"../v8/include/cppgc/internal/finalizer-trait.h",
|
||||
"../v8/include/cppgc/internal/gc-info.h",
|
||||
"../v8/include/cppgc/internal/logging.h",
|
||||
"../v8/include/cppgc/internal/member-storage.h",
|
||||
"../v8/include/cppgc/internal/name-trait.h",
|
||||
"../v8/include/cppgc/internal/persistent-node.h",
|
||||
"../v8/include/cppgc/internal/pointer-policies.h",
|
||||
"../v8/include/cppgc/internal/write-barrier.h",
|
||||
"../v8/include/cppgc/liveness-broker.h",
|
||||
"../v8/include/cppgc/macros.h",
|
||||
"../v8/include/cppgc/member.h",
|
||||
"../v8/include/cppgc/name-provider.h",
|
||||
"../v8/include/cppgc/object-size-trait.h",
|
||||
"../v8/include/cppgc/persistent.h",
|
||||
"../v8/include/cppgc/platform.h",
|
||||
"../v8/include/cppgc/prefinalizer.h",
|
||||
"../v8/include/cppgc/process-heap-statistics.h",
|
||||
"../v8/include/cppgc/sentinel-pointer.h",
|
||||
"../v8/include/cppgc/source-location.h",
|
||||
"../v8/include/cppgc/tagged-member.h",
|
||||
"../v8/include/cppgc/testing.h",
|
||||
"../v8/include/cppgc/trace-trait.h",
|
||||
"../v8/include/cppgc/type-traits.h",
|
||||
"../v8/include/cppgc/visitor.h",
|
||||
"../v8/include/libplatform/libplatform-export.h",
|
||||
"../v8/include/libplatform/libplatform.h",
|
||||
"../v8/include/libplatform/v8-tracing.h",
|
||||
"../v8/include/v8-array-buffer.h",
|
||||
"../v8/include/v8-callbacks.h",
|
||||
"../v8/include/v8-container.h",
|
||||
"../v8/include/v8-context.h",
|
||||
"../v8/include/v8-cpp-heap-external.h",
|
||||
"../v8/include/v8-cppgc.h",
|
||||
"../v8/include/v8-data.h",
|
||||
"../v8/include/v8-date.h",
|
||||
"../v8/include/v8-debug.h",
|
||||
"../v8/include/v8-embedder-heap.h",
|
||||
"../v8/include/v8-embedder-state-scope.h",
|
||||
"../v8/include/v8-exception.h",
|
||||
"../v8/include/v8-extension.h",
|
||||
"../v8/include/v8-external-memory-accounter.h",
|
||||
"../v8/include/v8-external.h",
|
||||
"../v8/include/v8-fast-api-calls.h",
|
||||
"../v8/include/v8-forward.h",
|
||||
"../v8/include/v8-function-callback.h",
|
||||
"../v8/include/v8-function.h",
|
||||
"../v8/include/v8-handle-base.h",
|
||||
"../v8/include/v8-initialization.h",
|
||||
"../v8/include/v8-inspector-protocol.h",
|
||||
"../v8/include/v8-inspector.h",
|
||||
"../v8/include/v8-internal.h",
|
||||
"../v8/include/v8-isolate.h",
|
||||
"../v8/include/v8-json.h",
|
||||
"../v8/include/v8-local-handle.h",
|
||||
"../v8/include/v8-locker.h",
|
||||
"../v8/include/v8-maybe.h",
|
||||
"../v8/include/v8-memory-span.h",
|
||||
"../v8/include/v8-message.h",
|
||||
"../v8/include/v8-metrics.h",
|
||||
"../v8/include/v8-microtask-queue.h",
|
||||
"../v8/include/v8-microtask.h",
|
||||
"../v8/include/v8-object.h",
|
||||
"../v8/include/v8-persistent-handle.h",
|
||||
"../v8/include/v8-platform.h",
|
||||
"../v8/include/v8-primitive-object.h",
|
||||
"../v8/include/v8-primitive.h",
|
||||
"../v8/include/v8-profiler.h",
|
||||
"../v8/include/v8-promise.h",
|
||||
"../v8/include/v8-proxy.h",
|
||||
"../v8/include/v8-regexp.h",
|
||||
"../v8/include/v8-sandbox.h",
|
||||
"../v8/include/v8-script.h",
|
||||
"../v8/include/v8-snapshot.h",
|
||||
"../v8/include/v8-source-location.h",
|
||||
"../v8/include/v8-statistics.h",
|
||||
"../v8/include/v8-template.h",
|
||||
"../v8/include/v8-trace-categories.h",
|
||||
"../v8/include/v8-traced-handle.h",
|
||||
"../v8/include/v8-typed-array.h",
|
||||
"../v8/include/v8-unwinder-state.h",
|
||||
"../v8/include/v8-unwinder.h",
|
||||
"../v8/include/v8-util.h",
|
||||
"../v8/include/v8-value-serializer-version.h",
|
||||
"../v8/include/v8-value-serializer.h",
|
||||
"../v8/include/v8-value.h",
|
||||
"../v8/include/v8-version-string.h",
|
||||
"../v8/include/v8-version.h",
|
||||
"../v8/include/v8-wasm-trap-handler-posix.h",
|
||||
"../v8/include/v8-wasm-trap-handler-win.h",
|
||||
"../v8/include/v8-wasm.h",
|
||||
"../v8/include/v8-weak-callback-info.h",
|
||||
"../v8/include/v8.h",
|
||||
"../v8/include/v8config.h",
|
||||
]
|
||||
|
||||
sandbox_bundle_deps = [
|
||||
"lib/common/api/native-image.ts",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/deprecate.ts",
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/timers-shim.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
|
||||
@@ -48,8 +48,8 @@ filenames = {
|
||||
"shell/browser/ui/views/opaque_frame_view.h",
|
||||
"shell/browser/ui/views/caption_button_placeholder_container.cc",
|
||||
"shell/browser/ui/views/caption_button_placeholder_container.h",
|
||||
"shell/browser/ui/views/native_frame_view_linux.cc",
|
||||
"shell/browser/ui/views/native_frame_view_linux.h",
|
||||
"shell/browser/ui/views/client_frame_view_linux.cc",
|
||||
"shell/browser/ui/views/client_frame_view_linux.h",
|
||||
"shell/browser/ui/views/linux_frame_layout.cc",
|
||||
"shell/browser/ui/views/linux_frame_layout.h",
|
||||
"shell/common/application_info_linux.cc",
|
||||
@@ -440,6 +440,8 @@ filenames = {
|
||||
"shell/browser/microtasks_runner.h",
|
||||
"shell/browser/native_window.cc",
|
||||
"shell/browser/native_window.h",
|
||||
"shell/browser/native_window_features.cc",
|
||||
"shell/browser/native_window_features.h",
|
||||
"shell/browser/native_window_observer.h",
|
||||
"shell/browser/net/asar/asar_file_validator.cc",
|
||||
"shell/browser/net/asar/asar_file_validator.h",
|
||||
@@ -564,8 +566,6 @@ filenames = {
|
||||
"shell/browser/web_view_guest_delegate.h",
|
||||
"shell/browser/web_view_manager.cc",
|
||||
"shell/browser/web_view_manager.h",
|
||||
"shell/browser/webauthn/electron_authenticator_request_client_delegate.cc",
|
||||
"shell/browser/webauthn/electron_authenticator_request_client_delegate.h",
|
||||
"shell/browser/webauthn/electron_authenticator_request_delegate.cc",
|
||||
"shell/browser/webauthn/electron_authenticator_request_delegate.h",
|
||||
"shell/browser/window_list.cc",
|
||||
@@ -688,7 +688,6 @@ filenames = {
|
||||
"shell/common/gin_helper/wrappable.cc",
|
||||
"shell/common/gin_helper/wrappable.h",
|
||||
"shell/common/gin_helper/wrappable_base.h",
|
||||
"shell/common/gin_helper/wrappable_pointer_tags.h",
|
||||
"shell/common/heap_snapshot.cc",
|
||||
"shell/common/heap_snapshot.h",
|
||||
"shell/common/key_weak_map.h",
|
||||
@@ -743,8 +742,6 @@ filenames = {
|
||||
"shell/renderer/electron_sandboxed_renderer_client.h",
|
||||
"shell/renderer/electron_smooth_round_rect.cc",
|
||||
"shell/renderer/electron_smooth_round_rect.h",
|
||||
"shell/renderer/oom_stack_trace.cc",
|
||||
"shell/renderer/oom_stack_trace.h",
|
||||
"shell/renderer/preload_realm_context.cc",
|
||||
"shell/renderer/preload_realm_context.h",
|
||||
"shell/renderer/preload_utils.cc",
|
||||
@@ -774,6 +771,8 @@ filenames = {
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.cc",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
@@ -804,6 +803,8 @@ filenames = {
|
||||
"shell/browser/extensions/electron_kiosk_delegate.h",
|
||||
"shell/browser/extensions/electron_messaging_delegate.cc",
|
||||
"shell/browser/extensions/electron_messaging_delegate.h",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/electron_navigation_ui_data.h",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.cc",
|
||||
"shell/browser/extensions/electron_process_manager_delegate.h",
|
||||
"shell/common/extensions/electron_extensions_api_provider.cc",
|
||||
|
||||
@@ -158,8 +158,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_intersection.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_symmetric_difference.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_union.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shift_left.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shift_right.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shuffle.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_sort.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_sort_heap.h",
|
||||
@@ -217,8 +215,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__atomic/atomic_lock_free.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_ref.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_sync.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_sync_timed.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_waitable_traits.h",
|
||||
"//third_party/libc++/src/include/__atomic/check_memory_order.h",
|
||||
"//third_party/libc++/src/include/__atomic/contention_t.h",
|
||||
"//third_party/libc++/src/include/__atomic/fence.h",
|
||||
@@ -334,14 +330,11 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__config",
|
||||
"//third_party/libc++/src/include/__config_site.in",
|
||||
"//third_party/libc++/src/include/__configuration/abi.h",
|
||||
"//third_party/libc++/src/include/__configuration/attributes.h",
|
||||
"//third_party/libc++/src/include/__configuration/availability.h",
|
||||
"//third_party/libc++/src/include/__configuration/compiler.h",
|
||||
"//third_party/libc++/src/include/__configuration/diagnostic_suppression.h",
|
||||
"//third_party/libc++/src/include/__configuration/experimental.h",
|
||||
"//third_party/libc++/src/include/__configuration/hardening.h",
|
||||
"//third_party/libc++/src/include/__configuration/language.h",
|
||||
"//third_party/libc++/src/include/__configuration/namespace.h",
|
||||
"//third_party/libc++/src/include/__configuration/platform.h",
|
||||
"//third_party/libc++/src/include/__coroutine/coroutine_handle.h",
|
||||
"//third_party/libc++/src/include/__coroutine/coroutine_traits.h",
|
||||
@@ -982,7 +975,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__format/format_to_n_result.h",
|
||||
"//third_party/libc++/src/include/__format/formatter.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_bool.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_bool_impl.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_char.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_floating_point.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_integer.h",
|
||||
@@ -1060,7 +1052,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__iterator/aliasing_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/back_insert_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/bounded_iter.h",
|
||||
"//third_party/libc++/src/include/__iterator/capacity_aware_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/common_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/concepts.h",
|
||||
"//third_party/libc++/src/include/__iterator/counted_iterator.h",
|
||||
@@ -1191,7 +1182,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__memory/unique_temporary_buffer.h",
|
||||
"//third_party/libc++/src/include/__memory/uses_allocator.h",
|
||||
"//third_party/libc++/src/include/__memory/uses_allocator_construction.h",
|
||||
"//third_party/libc++/src/include/__memory/valid_range.h",
|
||||
"//third_party/libc++/src/include/__memory_resource/memory_resource.h",
|
||||
"//third_party/libc++/src/include/__memory_resource/monotonic_buffer_resource.h",
|
||||
"//third_party/libc++/src/include/__memory_resource/polymorphic_allocator.h",
|
||||
@@ -1307,7 +1297,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__ranges/empty_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/enable_borrowed_range.h",
|
||||
"//third_party/libc++/src/include/__ranges/enable_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/enumerate_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/filter_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/from_range.h",
|
||||
"//third_party/libc++/src/include/__ranges/iota_view.h",
|
||||
@@ -1505,7 +1494,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__utility/as_lvalue.h",
|
||||
"//third_party/libc++/src/include/__utility/auto_cast.h",
|
||||
"//third_party/libc++/src/include/__utility/cmp.h",
|
||||
"//third_party/libc++/src/include/__utility/constant_wrapper.h",
|
||||
"//third_party/libc++/src/include/__utility/convert_to_integral.h",
|
||||
"//third_party/libc++/src/include/__utility/declval.h",
|
||||
"//third_party/libc++/src/include/__utility/default_three_way_comparator.h",
|
||||
@@ -1518,6 +1506,7 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__utility/in_place.h",
|
||||
"//third_party/libc++/src/include/__utility/integer_sequence.h",
|
||||
"//third_party/libc++/src/include/__utility/is_pointer_in_range.h",
|
||||
"//third_party/libc++/src/include/__utility/is_valid_range.h",
|
||||
"//third_party/libc++/src/include/__utility/lazy_synth_three_way_comparator.h",
|
||||
"//third_party/libc++/src/include/__utility/move.h",
|
||||
"//third_party/libc++/src/include/__utility/no_destroy.h",
|
||||
@@ -1613,6 +1602,7 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/filesystem",
|
||||
"//third_party/libc++/src/include/flat_map",
|
||||
"//third_party/libc++/src/include/flat_set",
|
||||
"//third_party/libc++/src/include/float.h",
|
||||
"//third_party/libc++/src/include/format",
|
||||
"//third_party/libc++/src/include/forward_list",
|
||||
"//third_party/libc++/src/include/fstream",
|
||||
|
||||
21
lib/browser/.eslintrc.json
Normal file
21
lib/browser/.eslintrc.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"electron",
|
||||
"electron/renderer"
|
||||
],
|
||||
"patterns": [
|
||||
"./*",
|
||||
"../*",
|
||||
"@electron/internal/isolated_renderer/*",
|
||||
"@electron/internal/renderer/*",
|
||||
"@electron/internal/sandboxed_worker/*",
|
||||
"@electron/internal/worker/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,7 @@ Object.assign(app, {
|
||||
commandLine: {
|
||||
hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
|
||||
getSwitchValue: (theSwitch: string) => commandLine.getSwitchValue(String(theSwitch)),
|
||||
appendSwitch: (theSwitch: string, value?: string) =>
|
||||
commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
|
||||
appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
|
||||
appendArgument: (arg: string) => commandLine.appendArgument(String(arg)),
|
||||
removeSwitch: (theSwitch: string) => commandLine.removeSwitch(String(theSwitch))
|
||||
} as Electron.CommandLine
|
||||
@@ -51,10 +50,10 @@ Object.assign(app, {
|
||||
// we define this here because it'd be overly complicated to
|
||||
// do in native land
|
||||
Object.defineProperty(app, 'applicationMenu', {
|
||||
get() {
|
||||
get () {
|
||||
return Menu.getApplicationMenu();
|
||||
},
|
||||
set(menu: Electron.Menu | null) {
|
||||
set (menu: Electron.Menu | null) {
|
||||
return Menu.setApplicationMenu(menu);
|
||||
}
|
||||
});
|
||||
@@ -117,22 +116,17 @@ for (const name of events) {
|
||||
}
|
||||
|
||||
app._clientCertRequestPasswordHandler = null;
|
||||
app.setClientCertRequestPasswordHandler = function (
|
||||
handler: (params: Electron.ClientCertRequestParams) => Promise<string>
|
||||
) {
|
||||
app.setClientCertRequestPasswordHandler = function (handler: (params: Electron.ClientCertRequestParams) => Promise<string>) {
|
||||
app._clientCertRequestPasswordHandler = handler;
|
||||
};
|
||||
|
||||
app.on(
|
||||
'-client-certificate-request-password',
|
||||
async (event: Electron.Event<Electron.ClientCertRequestParams>, callback: (password: string) => void) => {
|
||||
event.preventDefault();
|
||||
const { hostname, tokenName, isRetry } = event;
|
||||
if (!app._clientCertRequestPasswordHandler) {
|
||||
callback('');
|
||||
return;
|
||||
}
|
||||
const password = await app._clientCertRequestPasswordHandler({ hostname, tokenName, isRetry });
|
||||
callback(password);
|
||||
app.on('-client-certificate-request-password', async (event: Electron.Event<Electron.ClientCertRequestParams>, callback: (password: string) => void) => {
|
||||
event.preventDefault();
|
||||
const { hostname, tokenName, isRetry } = event;
|
||||
if (!app._clientCertRequestPasswordHandler) {
|
||||
callback('');
|
||||
return;
|
||||
}
|
||||
);
|
||||
const password = await app._clientCertRequestPasswordHandler({ hostname, tokenName, isRetry });
|
||||
callback(password);
|
||||
});
|
||||
|
||||
@@ -135,7 +135,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
allowAnyVersion: boolean = false;
|
||||
|
||||
// Private: Validate that the URL points to an MSIX file (following redirects)
|
||||
private async validateMsixUrl(url: string): Promise<void> {
|
||||
private async validateMsixUrl (url: string): Promise<void> {
|
||||
try {
|
||||
// Make a HEAD request to follow redirects and get the final URL
|
||||
const response = await net.fetch(url, {
|
||||
@@ -153,9 +153,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
const hasMsixExtension = pathname.endsWith('.msix') || pathname.endsWith('.msixbundle');
|
||||
|
||||
if (!hasMsixExtension) {
|
||||
throw new Error(
|
||||
`Update URL does not point to an MSIX file. Expected .msix or .msixbundle extension, got final URL: ${finalUrl}`
|
||||
);
|
||||
throw new Error(`Update URL does not point to an MSIX file. Expected .msix or .msixbundle extension, got final URL: ${finalUrl}`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof TypeError) {
|
||||
@@ -166,7 +164,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
}
|
||||
|
||||
// Private: Check if URL is a direct MSIX file (following redirects)
|
||||
private async isDirectMsixUrl(url: string, emitError: boolean = false): Promise<boolean> {
|
||||
private async isDirectMsixUrl (url: string, emitError: boolean = false): Promise<boolean> {
|
||||
try {
|
||||
await this.validateMsixUrl(url);
|
||||
return true;
|
||||
@@ -180,12 +178,12 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
|
||||
// Supports both versioning (x.y.z) and Windows version format (x.y.z.a)
|
||||
// Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if v1 === v2
|
||||
private compareVersions(v1: string, v2: string): number {
|
||||
const parts1 = v1.split('.').map((part) => {
|
||||
private compareVersions (v1: string, v2: string): number {
|
||||
const parts1 = v1.split('.').map(part => {
|
||||
const parsed = parseInt(part, 10);
|
||||
return isNaN(parsed) ? 0 : parsed;
|
||||
});
|
||||
const parts2 = v2.split('.').map((part) => {
|
||||
const parts2 = v2.split('.').map(part => {
|
||||
const parsed = parseInt(part, 10);
|
||||
return isNaN(parsed) ? 0 : parsed;
|
||||
});
|
||||
@@ -205,12 +203,9 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
|
||||
// Private: Parse the static releases array format
|
||||
// This is a static JSON file containing all releases
|
||||
private parseStaticReleasFile(
|
||||
json: any,
|
||||
currentVersion: string
|
||||
): { ok: boolean; available: boolean; url?: string; name?: string; notes?: string; pub_date?: string } {
|
||||
private parseStaticReleasFile (json: any, currentVersion: string): { ok: boolean; available: boolean; url?: string; name?: string; notes?: string; pub_date?: string } {
|
||||
if (!Array.isArray(json.releases) || !json.currentRelease || typeof json.currentRelease !== 'string') {
|
||||
this.emitError(new Error("Invalid releases format. Expected 'releases' array and 'currentRelease' string."));
|
||||
this.emitError(new Error('Invalid releases format. Expected \'releases\' array and \'currentRelease\' string.'));
|
||||
return { ok: false, available: false };
|
||||
}
|
||||
|
||||
@@ -239,18 +234,14 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
const releaseEntry = json.releases.find((r: any) => r.version === currentReleaseVersion);
|
||||
|
||||
if (!releaseEntry || !releaseEntry.updateTo) {
|
||||
this.emitError(
|
||||
new Error(`Release entry for version '${currentReleaseVersion}' not found or missing 'updateTo' property.`)
|
||||
);
|
||||
this.emitError(new Error(`Release entry for version '${currentReleaseVersion}' not found or missing 'updateTo' property.`));
|
||||
return { ok: false, available: false };
|
||||
}
|
||||
|
||||
const updateTo = releaseEntry.updateTo;
|
||||
|
||||
if (!updateTo.url) {
|
||||
this.emitError(
|
||||
new Error(`Invalid release entry. 'updateTo.url' is missing for version ${currentReleaseVersion}.`)
|
||||
);
|
||||
this.emitError(new Error(`Invalid release entry. 'updateTo.url' is missing for version ${currentReleaseVersion}.`));
|
||||
return { ok: false, available: false };
|
||||
}
|
||||
|
||||
@@ -264,22 +255,15 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
};
|
||||
}
|
||||
|
||||
private parseDynamicReleasFile(json: any): {
|
||||
ok: boolean;
|
||||
available: boolean;
|
||||
url?: string;
|
||||
name?: string;
|
||||
notes?: string;
|
||||
pub_date?: string;
|
||||
} {
|
||||
private parseDynamicReleasFile (json: any): { ok: boolean; available: boolean; url?: string; name?: string; notes?: string; pub_date?: string } {
|
||||
if (!json.url) {
|
||||
this.emitError(new Error("Invalid releases format. Expected 'url' string property."));
|
||||
this.emitError(new Error('Invalid releases format. Expected \'url\' string property.'));
|
||||
return { ok: false, available: false };
|
||||
}
|
||||
return { ok: true, available: true, url: json.url, name: json.name, notes: json.notes, pub_date: json.pub_date };
|
||||
}
|
||||
|
||||
private async fetchSquirrelJson(url: string) {
|
||||
private async fetchSquirrelJson (url: string) {
|
||||
const headers: Record<string, string> = {
|
||||
...this.updateHeaders,
|
||||
Accept: 'application/json' // Always set Accept header, overriding any user-provided Accept
|
||||
@@ -315,8 +299,8 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
private async getUpdateInfo(url: string): Promise<UpdateInfo> {
|
||||
if (url && (await this.isDirectMsixUrl(url))) {
|
||||
private async getUpdateInfo (url: string): Promise<UpdateInfo> {
|
||||
if (url && await this.isDirectMsixUrl(url)) {
|
||||
return { ok: true, available: true, updateUrl: url, releaseDate: new Date() };
|
||||
} else {
|
||||
const updateJson = await this.fetchSquirrelJson(url);
|
||||
@@ -337,7 +321,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
const releaseName = updateJson.name ?? '';
|
||||
releaseDate = releaseDate ?? new Date();
|
||||
|
||||
if (!(await this.isDirectMsixUrl(updateUrl, true))) {
|
||||
if (!await this.isDirectMsixUrl(updateUrl, true)) {
|
||||
return { ok: false };
|
||||
} else {
|
||||
return {
|
||||
@@ -353,11 +337,11 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
getFeedURL() {
|
||||
getFeedURL () {
|
||||
return this.updateURL ?? '';
|
||||
}
|
||||
|
||||
setFeedURL(options: { url: string; headers?: Record<string, string>; allowAnyVersion?: boolean } | string) {
|
||||
setFeedURL (options: { url: string; headers?: Record<string, string>; allowAnyVersion?: boolean } | string) {
|
||||
let updateURL: string;
|
||||
let headers: Record<string, string> | undefined;
|
||||
let allowAnyVersion: boolean | undefined;
|
||||
@@ -367,23 +351,23 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
headers = options.headers;
|
||||
allowAnyVersion = options.allowAnyVersion;
|
||||
} else {
|
||||
throw new TypeError("Expected options object to contain a 'url' string property in setFeedUrl call");
|
||||
throw new TypeError('Expected options object to contain a \'url\' string property in setFeedUrl call');
|
||||
}
|
||||
} else if (typeof options === 'string') {
|
||||
updateURL = options;
|
||||
} else {
|
||||
throw new TypeError("Expected an options object with a 'url' property to be provided");
|
||||
throw new TypeError('Expected an options object with a \'url\' property to be provided');
|
||||
}
|
||||
this.updateURL = updateURL;
|
||||
this.updateHeaders = headers ?? null;
|
||||
this.allowAnyVersion = allowAnyVersion ?? false;
|
||||
}
|
||||
|
||||
getPackageInfo(): MSIXPackageInfo {
|
||||
getPackageInfo (): MSIXPackageInfo {
|
||||
return msixUpdate.getPackageInfo() as MSIXPackageInfo;
|
||||
}
|
||||
|
||||
async checkForUpdates() {
|
||||
async checkForUpdates () {
|
||||
const url = this.updateURL;
|
||||
if (!url) {
|
||||
return this.emitError(new Error('Update URL is not set'));
|
||||
@@ -398,11 +382,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
// If appInstallerUri is set, Windows App Installer manages updates automatically
|
||||
// Prevent updates here to avoid conflicts
|
||||
if (packageInfo.appInstallerUri) {
|
||||
return this.emitError(
|
||||
new Error(
|
||||
'Auto-updates are managed by Windows App Installer. Updates are not allowed when installed via Application Manifest.'
|
||||
)
|
||||
);
|
||||
return this.emitError(new Error('Auto-updates are managed by Windows App Installer. Updates are not allowed when installed via Application Manifest.'));
|
||||
}
|
||||
|
||||
this.emit('checking-for-update');
|
||||
@@ -425,26 +405,18 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
forceUpdateFromAnyVersion: this.allowAnyVersion
|
||||
} as UpdateMsixOptions);
|
||||
|
||||
this.emit(
|
||||
'update-downloaded',
|
||||
{},
|
||||
msixUrlInfo.releaseNotes,
|
||||
msixUrlInfo.releaseName,
|
||||
msixUrlInfo.releaseDate,
|
||||
msixUrlInfo.updateUrl,
|
||||
() => {
|
||||
this.quitAndInstall();
|
||||
}
|
||||
);
|
||||
this.emit('update-downloaded', {}, msixUrlInfo.releaseNotes, msixUrlInfo.releaseName, msixUrlInfo.releaseDate, msixUrlInfo.updateUrl, () => {
|
||||
this.quitAndInstall();
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.emitError(error as Error);
|
||||
}
|
||||
}
|
||||
|
||||
async quitAndInstall() {
|
||||
async quitAndInstall () {
|
||||
if (!this.updateAvailable) {
|
||||
this.emitError(new Error("No update available, can't quit and install"));
|
||||
this.emitError(new Error('No update available, can\'t quit and install'));
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
@@ -469,7 +441,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
|
||||
// Private: Emit both error object and message, this is to keep compatibility
|
||||
// with Old APIs.
|
||||
emitError(error: Error) {
|
||||
emitError (error: Error) {
|
||||
this.emit('error', error, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,40 +8,40 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
updateAvailable: boolean = false;
|
||||
updateURL: string | null = null;
|
||||
|
||||
quitAndInstall() {
|
||||
quitAndInstall () {
|
||||
if (!this.updateAvailable) {
|
||||
return this.emitError(new Error("No update available, can't quit and install"));
|
||||
return this.emitError(new Error('No update available, can\'t quit and install'));
|
||||
}
|
||||
squirrelUpdate.processStart();
|
||||
app.quit();
|
||||
}
|
||||
|
||||
getFeedURL() {
|
||||
getFeedURL () {
|
||||
return this.updateURL ?? '';
|
||||
}
|
||||
|
||||
getPackageInfo() {
|
||||
getPackageInfo () {
|
||||
// Squirrel-based Windows apps don't have MSIX package information
|
||||
return undefined;
|
||||
}
|
||||
|
||||
setFeedURL(options: { url: string } | string) {
|
||||
setFeedURL (options: { url: string } | string) {
|
||||
let updateURL: string;
|
||||
if (typeof options === 'object') {
|
||||
if (typeof options.url === 'string') {
|
||||
updateURL = options.url;
|
||||
} else {
|
||||
throw new TypeError("Expected options object to contain a 'url' string property in setFeedUrl call");
|
||||
throw new TypeError('Expected options object to contain a \'url\' string property in setFeedUrl call');
|
||||
}
|
||||
} else if (typeof options === 'string') {
|
||||
updateURL = options;
|
||||
} else {
|
||||
throw new TypeError("Expected an options object with a 'url' property to be provided");
|
||||
throw new TypeError('Expected an options object with a \'url\' property to be provided');
|
||||
}
|
||||
this.updateURL = updateURL;
|
||||
}
|
||||
|
||||
async checkForUpdates() {
|
||||
async checkForUpdates () {
|
||||
const url = this.updateURL;
|
||||
if (!url) {
|
||||
return this.emitError(new Error('Update URL is not set'));
|
||||
@@ -72,7 +72,7 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
|
||||
|
||||
// Private: Emit both error object and message, this is to keep compatibility
|
||||
// with Old APIs.
|
||||
emitError(error: Error) {
|
||||
emitError (error: Error) {
|
||||
this.emit('error', error, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { updateMsix, registerPackage, registerRestartOnUpdate, getPackageInfo } = process._linkedBinding(
|
||||
'electron_browser_msix_updater'
|
||||
);
|
||||
const { updateMsix, registerPackage, registerRestartOnUpdate, getPackageInfo } =
|
||||
process._linkedBinding('electron_browser_msix_updater');
|
||||
|
||||
export { updateMsix, registerPackage, registerRestartOnUpdate, getPackageInfo };
|
||||
|
||||
@@ -34,12 +34,8 @@ const spawnUpdate = async function (args: string[], options: { detached: boolean
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
spawnedProcess.stdout.on('data', (data) => {
|
||||
stdout += data;
|
||||
});
|
||||
spawnedProcess.stderr.on('data', (data) => {
|
||||
stderr += data;
|
||||
});
|
||||
spawnedProcess.stdout.on('data', (data) => { stdout += data; });
|
||||
spawnedProcess.stderr.on('data', (data) => { stderr += data; });
|
||||
|
||||
spawnedProcess.on('error', (error) => {
|
||||
spawnedProcess = undefined;
|
||||
@@ -63,12 +59,12 @@ const spawnUpdate = async function (args: string[], options: { detached: boolean
|
||||
};
|
||||
|
||||
// Start an instance of the installed app.
|
||||
export function processStart() {
|
||||
export function processStart () {
|
||||
spawnUpdate(['--processStartAndWait', exeName], { detached: true });
|
||||
}
|
||||
|
||||
// Download the releases specified by the URL and write new results to stdout.
|
||||
export async function checkForUpdate(updateURL: string): Promise<any> {
|
||||
export async function checkForUpdate (updateURL: string): Promise<any> {
|
||||
const stdout = await spawnUpdate(['--checkForUpdate', updateURL], { detached: false });
|
||||
try {
|
||||
// Last line of output is the JSON details about the releases
|
||||
@@ -80,12 +76,12 @@ export async function checkForUpdate(updateURL: string): Promise<any> {
|
||||
}
|
||||
|
||||
// Update the application to the latest remote version specified by URL.
|
||||
export async function update(updateURL: string): Promise<void> {
|
||||
export async function update (updateURL: string): Promise<void> {
|
||||
await spawnUpdate(['--update', updateURL], { detached: false });
|
||||
}
|
||||
|
||||
// Is the Update.exe installed with the current application?
|
||||
export function supported() {
|
||||
export function supported () {
|
||||
try {
|
||||
fs.accessSync(updateExe, fs.constants.R_OK);
|
||||
return true;
|
||||
|
||||
@@ -25,156 +25,88 @@ BaseWindow.prototype.setTouchBar = function (touchBar) {
|
||||
// Properties
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'autoHideMenuBar', {
|
||||
get: function () {
|
||||
return this.isMenuBarAutoHide();
|
||||
},
|
||||
set: function (autoHide) {
|
||||
this.setAutoHideMenuBar(autoHide);
|
||||
}
|
||||
get: function () { return this.isMenuBarAutoHide(); },
|
||||
set: function (autoHide) { this.setAutoHideMenuBar(autoHide); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'visibleOnAllWorkspaces', {
|
||||
get: function () {
|
||||
return this.isVisibleOnAllWorkspaces();
|
||||
},
|
||||
set: function (visible) {
|
||||
this.setVisibleOnAllWorkspaces(visible);
|
||||
}
|
||||
get: function () { return this.isVisibleOnAllWorkspaces(); },
|
||||
set: function (visible) { this.setVisibleOnAllWorkspaces(visible); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'fullScreen', {
|
||||
get: function () {
|
||||
return this.isFullScreen();
|
||||
},
|
||||
set: function (full) {
|
||||
this.setFullScreen(full);
|
||||
}
|
||||
get: function () { return this.isFullScreen(); },
|
||||
set: function (full) { this.setFullScreen(full); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'simpleFullScreen', {
|
||||
get: function () {
|
||||
return this.isSimpleFullScreen();
|
||||
},
|
||||
set: function (simple) {
|
||||
this.setSimpleFullScreen(simple);
|
||||
}
|
||||
get: function () { return this.isSimpleFullScreen(); },
|
||||
set: function (simple) { this.setSimpleFullScreen(simple); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'focusable', {
|
||||
get: function () {
|
||||
return this.isFocusable();
|
||||
},
|
||||
set: function (focusable) {
|
||||
this.setFocusable(focusable);
|
||||
}
|
||||
get: function () { return this.isFocusable(); },
|
||||
set: function (focusable) { this.setFocusable(focusable); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'kiosk', {
|
||||
get: function () {
|
||||
return this.isKiosk();
|
||||
},
|
||||
set: function (kiosk) {
|
||||
this.setKiosk(kiosk);
|
||||
}
|
||||
get: function () { return this.isKiosk(); },
|
||||
set: function (kiosk) { this.setKiosk(kiosk); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'documentEdited', {
|
||||
get: function () {
|
||||
return this.isDocumentEdited();
|
||||
},
|
||||
set: function (edited) {
|
||||
this.setDocumentEdited(edited);
|
||||
}
|
||||
get: function () { return this.isDocumentEdited(); },
|
||||
set: function (edited) { this.setDocumentEdited(edited); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'shadow', {
|
||||
get: function () {
|
||||
return this.hasShadow();
|
||||
},
|
||||
set: function (shadow) {
|
||||
this.setHasShadow(shadow);
|
||||
}
|
||||
get: function () { return this.hasShadow(); },
|
||||
set: function (shadow) { this.setHasShadow(shadow); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'representedFilename', {
|
||||
get: function () {
|
||||
return this.getRepresentedFilename();
|
||||
},
|
||||
set: function (filename) {
|
||||
this.setRepresentedFilename(filename);
|
||||
}
|
||||
get: function () { return this.getRepresentedFilename(); },
|
||||
set: function (filename) { this.setRepresentedFilename(filename); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'minimizable', {
|
||||
get: function () {
|
||||
return this.isMinimizable();
|
||||
},
|
||||
set: function (min) {
|
||||
this.setMinimizable(min);
|
||||
}
|
||||
get: function () { return this.isMinimizable(); },
|
||||
set: function (min) { this.setMinimizable(min); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'title', {
|
||||
get: function () {
|
||||
return this.getTitle();
|
||||
},
|
||||
set: function (title) {
|
||||
this.setTitle(title);
|
||||
}
|
||||
get: function () { return this.getTitle(); },
|
||||
set: function (title) { this.setTitle(title); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'maximizable', {
|
||||
get: function () {
|
||||
return this.isMaximizable();
|
||||
},
|
||||
set: function (max) {
|
||||
this.setMaximizable(max);
|
||||
}
|
||||
get: function () { return this.isMaximizable(); },
|
||||
set: function (max) { this.setMaximizable(max); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'resizable', {
|
||||
get: function () {
|
||||
return this.isResizable();
|
||||
},
|
||||
set: function (res) {
|
||||
this.setResizable(res);
|
||||
}
|
||||
get: function () { return this.isResizable(); },
|
||||
set: function (res) { this.setResizable(res); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'menuBarVisible', {
|
||||
get: function () {
|
||||
return this.isMenuBarVisible();
|
||||
},
|
||||
set: function (visible) {
|
||||
this.setMenuBarVisibility(visible);
|
||||
}
|
||||
get: function () { return this.isMenuBarVisible(); },
|
||||
set: function (visible) { this.setMenuBarVisibility(visible); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'fullScreenable', {
|
||||
get: function () {
|
||||
return this.isFullScreenable();
|
||||
},
|
||||
set: function (full) {
|
||||
this.setFullScreenable(full);
|
||||
}
|
||||
get: function () { return this.isFullScreenable(); },
|
||||
set: function (full) { this.setFullScreenable(full); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'closable', {
|
||||
get: function () {
|
||||
return this.isClosable();
|
||||
},
|
||||
set: function (close) {
|
||||
this.setClosable(close);
|
||||
}
|
||||
get: function () { return this.isClosable(); },
|
||||
set: function (close) { this.setClosable(close); }
|
||||
});
|
||||
|
||||
Object.defineProperty(BaseWindow.prototype, 'movable', {
|
||||
get: function () {
|
||||
return this.isMovable();
|
||||
},
|
||||
set: function (move) {
|
||||
this.setMovable(move);
|
||||
}
|
||||
get: function () { return this.isMovable(); },
|
||||
set: function (move) { this.setMovable(move); }
|
||||
});
|
||||
|
||||
BaseWindow.getFocusedWindow = () => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user