chrome-release-verify
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.
DeepseekModel
Curated skill
Quality Excellent · 90
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=electron-electron-claude-skills-chrome-release-verify-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
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 . 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: git -C "$repo" log HEAD --since='1 year ago' -E --grep="\b${bug}\b" --format='%h %s' Fetch Change-Id from Gerrit, then git log HEAD --grep="^Change-Id: ${cid}$" 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>/ : 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 : { "patch_dir" : "src/electron/patches/<dir>" , "repo" : "src/third_party/<dir-or-nested-path>" } 5. Validate with e sync --3 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 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: # 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 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 — follow .github/PULL_REQUEST_TEMPLATE.md ( Description of Change / Checklist / Release Notes sections; PRs that don't follow it are auto-closed): #### Description of Change Backports the following changes: * [ `<shortCommit>` ]( <gerrit-CL-url> ) from < patchDir > — < subject > * ... #### Checklist - [x] I have filled out the PR description - [ x ] [ I have reviewed and verified the changes ]( https://github.com/electron/governance/blob/main/policy/ai.md ) #### Release Notes Notes: Backported fixes from upstream Chromium and V8. Keep the PR body low-key about security. The PR is public the moment it opens, while the fixes only protect users after a release ships — don't advertise the exploit map in between. Concretely: no CVE numbers, no crbug.com links, no "security"/"0-day"/severity wording anywhere in the title, body, or Notes: line. The security 🔒 label is fine (it's how releases track these). Upstream commit subjects stay verbatim even when they say "UAF" — rewriting them breaks traceability to the Gerrit CL. Adjust the Notes: wording to match what's actually in the set (e.g. drop "and V8" if no v8 patches). Keep the CVE↔CL mapping out of the PR entirely: leave it in the local notes file ( /tmp/cve_cls.txt ) and report it to the user in chat, including any dropped or skipped fixes with reasons. Restore e use <previous> when done.
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.