关于 chrome-release-verify
这项 skill 面向 Electron 维护者,将 Chrome 发布中的修复对应到分支,并在本地验证补丁后准备 PR。继续处理拟议的回移补丁前,需先取得用户确认。
主要功能
- 01将 CVE 对应到修复
- 02根据分支历史检查修复
- 03准备本地回移补丁
- 04解决补丁冲突
- 05检查并重新导出补丁
- 06创建回移 PR
适用场景
- 01评估 Chrome 修复是否适用于 Electron 发布分支
- 02回移适用的安全修复
- 03推送前验证补丁
- 04准备经过验证的回移 PR
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ electron/ electron --skill chrome-release-verify安装后在 Claude Code 中输入/chrome-release-verify确认已加载。
详细介绍
Chrome 发布版本 → 通过验证的回移植 PR
输入:$ARGUMENTS = <release-branch> <chrome-releases-blog-url>(例如 41-x-y https://chromereleases.googleblog.com/2026/04/stable-channel-update-for-desktop_15.html)。如果缺少任一项,请询问用户。
整个流程以本地优先:只有当所有补丁都能通过 e sync --3 应用并通过 lint --patches 后,才会推送任何内容。
1. 将 CVE 映射到 bug → 修复 CL
运行 /chrome-release-cls <blog-url>(或执行其内联步骤),生成 /tmp/cve_bugs.txt(CVE|bug|severity|desc),并为每个 bug 找出权威修复 CL。对每个 CL,也记录 repo(src/ 下的路径:.、v8、third_party/{skia,angle,pdfium,dawn}、third_party/libaom/source/libaom)和 gerrit-host。
优先选择目标里程碑的合并 CL(例如在 41-x-y 上约等于 M146,优先选择 [M146] cherry-pick,而不是主 CL)——它已经完成 rebase,冲突的可能性小得多。可通过 Change-Id 在 git log --all --grep 中查找,或在 Gerrit 上查询 ?q=bug:<n>。如果 Chrome 没有将修复合并到目标里程碑,这本身并不是跳过的理由——Chrome 的合并窗口比 Electron 的支持窗口短。改用主 CL(或邻近里程碑的 rebase,见第 5 步),并让第 3 步判断易受攻击的代码是否存在于该分支上。
2. 准备已同步的工作树
如果 e show configs 中存在 bp-<NN>,则复用它;否则运行 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
如果同步失败并报错 NotADirectoryError: '<root>/src/.git/objects/info/alternates',请从 bp 配置的 env 中移除 GIT_CACHE_PATH,然后重试。
3. 验证代码树内状态还是需要回移植
针对每个 bug,在已同步的仓库中执行以下三项检查:
git -C "$repo" log HEAD --since='1 year ago' -E --grep="\b${bug}\b" --format='%h %s'- 从 Gerrit 获取 Change-Id,然后运行
git log HEAD --grep="^Change-Id: ${cid}$" grep -rlE "(\b${bug}\b|${cid})" <root>/src/electron/patches/
任一项命中 ⇒ 代码树内。全部为空 ⇒ 需要回移植。
第 1 步(或你收到的上游分流报告)中标记为 RESTRICTED / no public CL 的条目,不视为已继承——请在此处重新解析后再分类。运行 git -C "$repo" fetch origin 和 git -C "$repo" log --all --remotes -E --grep="(Bug|Fixed):.*\b${bug}\b" --format='%h %s',对 chromium/src、v8 和组件仓库的 refs/heads/main 及 branch-heads refs 使用 chrome-release-cls 技能的 gitiles_grep,并重新查询 Gerrit ?q=bug:<id> / ?q=message:<id>。Gerrit 变更记录往往受限,但修复提交可能已公开在 git 中,而且限制可能在运行过程中解除,因此先前的 RESTRICTED 结论只是线索,并非最终结果。只有所有查询均无结果时,条目才保持 RESTRICTED;绝不能因遗漏而将其视为代码树内——请在报告中单独列出,以便人工跟进。
对于每个需要回移植的 CL,还要获取其文件列表(/changes/<proj>~<cl>/revisions/current/files);如果所有文件都位于 chrome/browser/、chrome/android/、ios/ 或 components/**/android/ 下,则跳过——Electron 不会编译这些文件。
现在报告表格(CVE | Sev | Bug | Component | Verdict | CL)和拟回移植的条目;继续之前须取得用户确认。
4. 在本地编写补丁(暂不推送)
对于每个需要回移植的 CL,获取原始补丁并将其写入 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"
对于 e cherry-pick 不支持的 Gerrit 主机上的仓库(例如 aomedia 上的 libaom),请改为在已同步子仓库的 HEAD 上执行 git cherry-pick,应用上游提交,然后对结果运行 git format-patch。
对于任何新建的 patches/<dir>/,将其追加到 patches/config.json,保留每行一条记录的紧凑格式:
{ "patch_dir": "src/electron/patches/<dir>", "repo": "src/third_party/<dir-or-nested-path>" }
5. 使用 e sync --3 验证
e sync --3 2>&1 | tee /tmp/bp_sync3.log
遇到 Patch failed at NNNN <subject> 时:
- 进入失败的仓库,检查
git diff中的冲突标记。 - 仅测试文件(例如
web_tests/VirtualTestSuites、上下文漂移的*_unittest.cc):如果与安全相关的代码块已干净合并,则采用 ours(git checkout --ours -- <file>)。 - 实质性代码冲突:不能以冲突为由丢弃。按以下顺序处理:
- 目标里程碑上相同 Change-Id 的合并提交(使用
git log --all --grep搜索 Change-Id,或使用 Gerrit?q=change:<Change-Id>)——改用该提交。 - 相邻里程碑上相同 Change-Id 的提交(作者的变基版本,例如目标为 M150 时的
[M152]CL——状态为 NEW 也可以),以及修复所依赖的任何前置 CL(引入修复所涉及的辅助函数或签名的重构)。选择能让修复原样应用的提交;在报告中列出前置项。 - 否则,在分支代码上手动移植修复的语义,直接修改 pick 的补丁文件:在目标仓库中解决代码块冲突,将修改折叠进 pick 的提交(使用
git commit --fixup和 autosquash rebase),然后重新导出。保留上游提交头原样不动,并在补丁头中追加一段Electron adaptation notes (<branch>),描述每一处适配(成员重命名、签名变更、内联辅助函数等)。只进行机械性、结构性适配——绝不改变修复检查或保护的内容,也不添加上游差异中不存在的语义。将该行标记为BACKPORTED (adapted),并在报告和 PR 正文中标出,提醒审核者注意。适配后的 pick 与其他 pick 遵循相同标准:e sync --3、lint --patches,以及调用方要求的任何构建门禁。
- 目标里程碑上相同 Change-Id 的合并提交(使用
- DROPPED 仅适用于以下两种情况:(a)分支上不存在易受攻击的代码(文件、函数或功能不存在);或(b)子系统重写,修复没有可应用的对应代码。每个 DROPPED 行都必须说明具体是哪种情况,并提供证据。彻底移除已丢弃的补丁(删除文件,并从
.patches和config.json中移除)。 - 解决后:运行
git add <files> && git -c commit.gpgsign=false am --continue,然后运行e patches <repo>导出已解决的补丁,再重新运行e sync --3。重复以上步骤,直到无冲突为止。
6. 导出 → lint → 重新应用循环
e patches all
node script/lint.js --patches # must exit 0
如果 lint 报告了问题(通常是 + 内容行末尾有空格),修复这些问题会改变补丁写入的字节,导致 e patches 生成的 index <old>..<new> blob 哈希失效。手动编辑 .patch 并原样提交,虽然能在本地通过 lint,却会在 CI 的 Apply Patches 重新导出检查中因一行 index 哈希差异而失败。
因此,每当 lint(或你)在导出后修改任何 .patch 文件时,都要再进行一次往返处理:
# 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"; }
重复上述步骤,直到 lint --patches 以 0 退出,并且最后一次运行 e patches all 后,git diff -- patches/ 为空。只有到这时,补丁集才对 CI 稳定。
7. 提交、推送、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 正文格式——遵循 .github/PULL_REQUEST_TEMPLATE.md(Description of Change / Checklist / Release Notes 部分;不遵循此格式的 PR 会被自动关闭):
#### Description of Change
Backports the following changes:
* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject>
* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject> (adapted for <branch>; see patch header)
* ...
#### 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.
PR 正文中不要大肆宣扬安全问题。 PR 一旦开启就会公开,而修复只有在版本发布后才会保护用户——不要在此期间公开漏洞利用图谱。具体来说:标题、正文或 Notes: 行中都不得出现 CVE 编号、crbug.com 链接或“security”/“0-day”/严重程度相关措辞。security 🔒 标签可以使用(发布流程会通过它进行跟踪)。即使上游提交主题中写有 “UAF”,也必须原样保留——改写会破坏与 Gerrit CL 的可追溯性。调整 Notes: 的措辞,使其符合实际补丁集内容(例如,没有 v8 补丁时就删除 “and V8”)。
不要在 PR 中提及 CVE↔CL 对应关系:将其保留在本地备注文件(/tmp/cve_cls.txt)中,并在聊天中告知用户,包括任何经过调整、删除或跳过的修复及其原因。
完成后恢复 e use <previous>。