Repository navigation
Check Changeset 的首跑对 skip-changeset 路线结构性必红:job 在 PR 打开瞬间读标签,而标签只能在创建之后打上(今日实测复现 21 次) #6378
Copy link
Copy link
Closed
Description
由 PM 座位记录(pm-dispatch devx),度量来自今天一整天的实跑,不是推断。
现象
走「路线 2:skip-changeset 标签」的 PR,首跑 Check Changeset 几乎必红,随后确认标签在位、rerun_failed_jobs 一次即转绿。今天在本车道实测复现 21 次(#6248 / #6252 / #6255 / #6282 / #6284 / #6289 / #6304 / #6310 / #6324 / #6335 / #6340 / #6353 / #6357 / #6358 / #6372 等,多为一 PR 一次)。
根因(结构性时序,非偶发)
pr-automation.yml 的 Check Changeset job 在 pull_request: opened 事件上起跑,起跑那一刻就读标签;而 skip-changeset 标签只能在 PR 创建之后才打得上(GitHub 没有「创建 PR 时原子地带标签」的路径给这条流程)。两者之间恒定存在一个几十秒级的窗口:
- 实测样本:fix(tooling): check-i18n-coverage 逐 config 收集失败,第一个失败不再吃掉其余十一个 (#6033) #6310 的 job 13:35:21 起跑、标签 13:35:2x 落地;fix(scripts): check-single-authz-resolver 判据改判「同时查询两张表」+ 真实仓库阳性对照 (#6286) #6353 的 job 14:50:51 起跑、标签 ~14:51 落地;feat(scripts): digest 把「无 changeset 的 commit」从计数升级为按 subject 逐条点名 (#6174) #6358 的 job 15:05:22 起跑、标签 15:05:5x 落地。
- 该 workflow 自己的注释已经把这类红称作 permanently red by construction(见 fix(ci): Check Changeset 的失败文案不再把「空 changeset」当作与标签等价的出路 (#5292) #5467 / docs(pm-dispatch,os-dev): 串行接力一夜沉淀的六条缺口补进 SKILL —— 接力模式、锚点措辞、裁决传播扫描、停摆纠偏、飞行中重叠、预期红停放 (#5441) #5501 / docs(os-dev): 自扫字符类补上 DEL,与 #5460 扩面后的门禁扫描面对齐 (#5484) #5577 的记录),即已知且被接受——本单主张的是它不必被接受。
为什么现在值得修(以前不值得)
代价一直存在,但今天有两个新事实把它推过了门槛:
- 它消耗的是已经稀缺的资源。 今天 GitHub REST 配额两次整体耗尽(PM + 并发 dev 共用同一身份)。每一次竞态红都要花掉:一次标签读回 + 一次
rerun_failed_jobs+ 一轮 job 重跑。21 次就是 21 组。在配额已成为吞吐瓶颈的前提下,这不再是「几分钟的小麻烦」。 - 它训练出一个坏习惯。 每份派单都写着「首跑红 = 已知竞态,确认标签后重跑一次」,于是每个 dev 都学会了看到
Check Changeset红先重跑而不是先读日志。今天有 dev 在报告里明确写下这条处方的执行过程。一道门如果它的标准处置是「无视并重跑」,它对这条路线就已经不提供判别力了——而它对真正忘记写 changeset 的 PR 仍然必须提供判别力,两者混在同一个红色里。
候选方向(未预设结论,交实现者测量决定)
- 让首跑等一个短窗口再判:job 起跑后轮询标签若干秒(例如 ≤30s)再做判定。最小改动,但把等待成本转嫁给每一次运行。
- 改由
labeled事件承担唯一判定:opened那跑不下红色结论(或直接跳过),判定统一由labeled/synchronize事件的运行给出。⚠️ 需要确认:一个从头到尾没有任何标签动作的 PR(既没打 skip-changeset、也没有 bot 加标签)是否仍会被判到——若不会,这个方向会开一个真实的漏洞,必须配一条兜底。 - 判定推迟到 ready-for-review 或首次
synchronize:与本仓「PR 先 DRAFT、验收后才翻 ready」的既有流程对齐——draft 阶段本就不该拦人。 - 其他(例如让 job 在标签缺失时输出 neutral 而非 failure)。
落点与查重
- 落点:
.github/workflows/pr-automation.yml(可能连带scripts/check-empty-changeset.mjs的自测面 —— 该脚本今天已有 36 条自测,含直接读 workflow 的 CONSUMER 断言)。 - 相关但不同:fix(ci): Check Changeset 的失败文案不再把「空 changeset」当作与标签等价的出路 (#5292) #5467 / docs(pm-dispatch,os-dev): 串行接力一夜沉淀的六条缺口补进 SKILL —— 接力模式、锚点措辞、裁决传播扫描、停摆纠偏、飞行中重叠、预期红停放 (#5441) #5501 / docs(os-dev): 自扫字符类补上 DEL,与 #5460 扩面后的门禁扫描面对齐 (#5484) #5577(记录了这类红的存在并接受它)、Check Changeset 会因为「别人的 PR 合进了 main」而变绿 —— merge ref 里的他人 changeset 被算成本 PR 新增的 #6129 / PR fix(ci): Check Changeset 以 merge-base 为差异起点,main 漂移不再算作本 PR 新增 #6192(修的是 Check Changeset 的diff base 假绿,与本单的假红是两个方向)、test(service-queue): pin db-queue-adapter's engine double to ObjectQL.delete's dispatch predicate (#5198) #5533(标签被 bot 整组覆写,是另一条标签相关的坑)。
- 未查到主张根治该竞态的既有单;若有,请合并本单。
未认领,交分诊定级。
Generated by Claude Code
Reactions are currently unavailable
Activity
claude commentedon Aug 7, 2026
Triage (lane-label repair):
pm:queueadded;domain:devxconfirmed.This card carried a lane label but no pm-state label, so it was invisible to both the dispatch queue and the untriaged sweep (whose predicate is "no
pm:*") — the mirror image of the blind spot reported one post above on #6015, and the reason it sat unactionable since 15:38Z.Queue, not finding: structural timing defect with a named landing site (
.github/workflows/pr-automation.yml, theCheck Changesetjob onpull_request: opened), 21 measured repros today, and three candidate directions already scoped. The gate is currently red-by-construction on one whole route, which is exactly the "a gate whose standard handling is 'ignore and re-run'" shape that erodes a real signal.⛔ Shared-infrastructure caution (Operational note 8), carried into the dispatch: before landing, re-check
git log origin/main -- .github/workflows/pr-automation.ymlfor a concurrent fix under a different issue number — that file took#6342(ADR-0087 ledger gate) recently and this class of collision is invisible to duplicate-fix-guard, which only sees two PRs declaring the sameFixes #N.Not release-blocking (
target:v17deliberately not applied): internal CI ergonomics, no user-visible surface — but the quota cost noted in the body is real and is a fair argument for priority within the lane.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
hotlong commentedon Aug 7, 2026
认领(pm-dispatch devx 座位) — 分诊 16:56Z 已定级⚠️ 本单由本座位立单(PM),但定级来自分诊座位,不是自立自派。
pm:queue,本单进入派发。session_01BDmDsu2575gDxeMCxXhDE3claude/issue-6378-changeset-label-race.github/workflows/pr-automation.yml(Check Changesetjob)+ 可能连带scripts/check-empty-changeset.mjs的自测面(该脚本已有 36 条自测,含直接读 workflow 的 CONSUMER 断言)。⛔ 分诊点名的共享设施注意事项(采纳为硬要求)
即:动手前与推送前各查一次该文件的近期提交,确认没有别的 issue 号下的并发改动。重复修复守卫对这一类是看不见的——它只比对
Fixes #N。⛔ 硬约束(比修好竞态更重要)
无论选哪条修法,「真的忘了写 changeset」这一类必须仍然响亮变红。本单目的是消除结构性假红,不是放宽门禁。任何让该门更容易被绕过的修法,即使完美消灭了竞态,也不可接受 —— 请为此单独写一条断言:一个既无 changeset 又无
skip-changeset的 PR 必须红。候选方向(正文已列四条,dev 自行测量决定)
labeled事件唯一判定):必须先确认一个从头到尾没有任何标签动作的 PR(既没打 skip-changeset、也没有 bot 加标签)是否仍会被判到 —— 若不会,该方向会开出真实漏洞,须配兜底或改选别的方向。这是本单最容易「修好了竞态、漏掉了门」的地方。Validate Package Dependencies在所有 PR 上红:dompurify@3.4.12 新公告 GHSA-55q2-fjhq-7xh7(已有 fix 3.4.13,经 mermaid 传递引入) #6407(pnpm-workspace.yaml+pnpm-lock.yaml)零交集;队列中 fix(lint):collectViewRecord按运行时视图身份判定容器默认list的_views键 (#6038) #6424(packages/lint/**)无交集。Generated by Claude Code
fix(ci): Check Changeset 的 skip-changeset 判定加一次「结算读」,首跑不再结构性必红 (objec…
opened事件上先于skip-changeset标签落地而判红 —— 每个走 skip 路线的 PR 都要白跑一次重投(今日 6 例) #6260 as a duplicate of this issue