Skip to content

Check Changeset 会因为「别人的 PR 合进了 main」而变绿 —— merge ref 里的他人 changeset 被算成本 PR 新增的 #6129

Description

@qq9340100

pr-automation.ymlCheck Changeset 门禁,在本 PR 一个 changeset 都没加的情况下会转绿,条件只是「本 PR 的 base.sha 被记下之后,main 又合进了带 changeset 的别人的 PR」。本仓一天合 ~18 个 PR,所以任何一个在飞久一点的 PR 都能白拿这张免检票。

发现于 PR #6117(#6095 的实现单)。不是猜的,是同一个 PR 上前后两跑的实测对照。

机制

.github/workflows/pr-automation.yml 的计数步骤:

ADDED=$(git diff --name-only --diff-filter=A "$BASE_SHA" HEAD -- '.changeset/*.md' | grep -v '/README\.md$' | wc -l)

两个输入各自都合理,合在一起就漏:

  1. BASE_SHA = github.event.pull_request.base.sha,它在 PR 创建时被钉住,后续 synchronize 不跟着 main 往前走。
  2. HEADactions/checkout@v7pull_request 事件上默认签出的 merge ref(refs/pull/N/merge),也就是「本 PR head 与当前 main tip 的合并」—— 它含有 main 上最新的一切。

于是 BASE_SHA 与 merge ref 之间的 main 漂移,整段都被 --diff-filter=A 记成「本 PR 新增的文件」。别人 PR 带进 main 的 .changeset/*.md,在本 PR 眼里就是本 PR 加的 changeset。

实测对照(PR #6117,同一个 PR,同一份 diff,零 changeset)

PR #6117 只改 pnpm-workspace.yaml + pnpm-lock.yaml,零 package.json 改动,.changeset/ 一个文件都没加。它本该一直红到有人打 skip-changeset

head 时间 Check for a changeset added by this PR 说明
1 bb4b42623 02:22Z failure 那一刻 base.sha(6513c1749)恰好就是 main tip,漂移为 0 → ADDED=0 → 正确判红
2 680617108 02:39Z success 17 分钟里 main 合进了 2 个带 changeset 的 PR → merge ref 里多出 2 个文件 → ADDED=2假绿

第二跑之后 Reject an empty-frontmatter changesetGuard against accidental major bumps 两步也跟着跑绿(job step 列表可见),即整条链都被这张假票放行。

冒名顶替的两个文件,本地可复现(6513c1749 是 PR #6117base.sha):

$ git diff --name-only --diff-filter=A 6513c1749 origin/main -- '.changeset/*.md'
.changeset/last-admin-guard-permission-set-row.md
.changeset/seed-autonumber-read-outage.md

两个都不是 PR #6117 写的,一个字都不是。

危害

可能的修法(未实现,留给裁决)

  • merge-base 代替钉死的 base.sha:git merge-base origin/$BASE_REF HEAD,只数这个 PR 自己那侧引入的文件。
  • 或让 checkout 取 PR head ref(ref: ${{ github.event.pull_request.head.sha }})再对 merge-base 求差 —— 但这会改变本 job 其它步骤看到的树,需要一并核对 check-empty-changeset.mjs --basecheck-changeset-no-major.mjs(两者也吃同一个 BASE_SHA,大概率有同款偏差)。
  • 这两条选项都会改变门禁的判定面,且 check-empty-changeset.mjs 有自己的 --self-test,应当在同一单里补上「main 漂移不得影响计数」这条双向断言;⛔ 不要只改 workflow 而不动 self-test,否则这个漏洞下次会以另一种形状回来。

参考


本单由 #6095 的实现 agent 在跑 CI 时旁落发现,按 Prime Directive #10 单开、不认领、不在原 PR 里顺手修。

Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions