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

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions