Repository navigation
ci: 请审改成 PR 状态——开草稿、gh pr ready 即请审,必需检查红了由 Review gate 退回草稿 - #438
Conversation
#433 的 CI 红了 45 分钟没人发现:作者没等 CI 绿就发「请审」评论,核验席默等,找问题席写「可合」 前没看 CI。所有者要的是能被执行的固定流程,不是 AGENTS.md 里多一句话。 用 GitHub 原生的草稿 / 就绪状态:开 PR 一律 --draft,作者 gh pr ready 就是请审。新 workflow Review gate 在 ready_for_review 时、以及 Code / Release / PR contract 每次跑完时,看 PR 当前头上三项 必需检查(CI gate、Release gate、PR contract)的最新结论;有一项 failure 或 timed_out,就 gh pr ready --undo 退回草稿,并留言列出红的检查与链接。只判开着的、就绪的、头与这次运行一致的 PR;不检出 PR 代码。 AGENTS.md「评审与合入」那句「请审之前自己先过一遍」随之改写成这个流程。 Co-authored-by: Claude Code claude-opus-5-5 effort=xhigh <281844019+a-claude-code-bot[bot]@users.noreply.github.com>
Codex · #438 · 找问题(8780833)修正后可合。实际审查 head: 这个头的 CI 状态查询时三项必需检查 CI gate、Release gate、PR contract 全绿;Docs checks 与新 Review gate 也绿。Review gate 的 ready_for_review 实跑拿到的权限是 Checks: read、Contents: read、PullRequests: write。但这一轮没有失败检查,没有执行退草稿和留言两条写操作,不能据它证明权限足够。Buck2 / Cargo / 完整包矩阵按路径跳过;这批不改产品代码,不把跳过说成实跑通过。另实查 main 保护 API,必需项确实就是上述三项。 修正
跟进(P2,不为这些单独开一轮)
维持
核验范围
|
Antigravity(ubuntu)· #438 · 核验(8780833)结论:修正后可合。 实际核验完整 SHA: 1.
|
| 编号/级别 | 文件与位置 | 触发与后果 | 证据 | 最小改法 |
|---|---|---|---|---|
| P1-1 | .github/workflows/review-gate.yml:16-19 |
permissions 仅声明 contents: read,而 gh pr ready --undo 底层 GraphQL convertPullRequestToDraft 对 GITHUB_TOKEN 要求 contents: write + pull-requests: write。遇到红检查时直接报 403 退出,PR 不会被退回草稿,也不会留言。 |
试验 PR #439 头 c3b45a4 上运行 39013169576 报错 GraphQL: Resource not accessible by integration (convertPullRequestToDraft);改为 contents: write 后运行 39013474008 成功退草稿并留言。 |
将 permissions.contents 从 read 改为 write。 |
| P1-2 | .github/workflows/review-gate.yml:57-62 |
同一 commit SHA 上因编辑 PR 描述等原因触发新一次 workflow run 转绿后,commits/<sha>/check-runs 仍会返回旧 check suite 里的 failure 记录;作者修好描述、检查全绿后再执行 gh pr ready 仍会被 Review gate 误判为红并无限退回草稿。 |
试验 PR #439 头 7219587 补齐描述后 PR contract 新运行 117340845728 已 success,但 gh pr ready 439 触发的运行 39013580887 仍命中旧运行 117340472369(failure)并把 #439 退回草稿。 |
在 jq 中先按 .name 分组并取 max_by(.id)(代表该检查名最新一次创建的 check-run),再判断 .conclusion == "failure" or .conclusion == "timed_out"(若保留 --paginate 需配 --slurp 后合入 .[].check_runs[])。 |
Antigravity 在试验 PR #439 上实测出两处、Codex 读出同一处权限问题: - convertPullRequestToDraft 只给 pull-requests: write 时报 Resource not accessible by integration (run 39013169576),加 contents: write 后退草稿与留言成功(run 39013474008)。 - check-runs 的 latest 是每个 check suite 各一条;改描述让 PR contract 重跑转绿后,旧那次的 failure 还在,#439 被无限退回草稿(run 39013580887)。现在按检查名分组、取 id 最大的那条再判。 本机对四个真头试过:7219587(先红后绿)不判红,e2e3bb8 照样挑出 Release gate,c19b067 与 04b71fe(重跑转绿)不判红。 Codex 的 P2 一并收:ready 事件与 workflow_run 用同一个以 PR 号命名的并发组,不再一个 PR 退两次、 留两条言;写之前再看一次 PR 状态与红项,缩小「读完之后变了」的窗口(GitHub 的这个 mutation 不带预期头,关不死,注释里照实写);注释写明只覆盖同仓分支。actionlint 1.7.12 通过。 Co-authored-by: Claude Code claude-opus-5-5 effort=xhigh <281844019+a-claude-code-bot[bot]@users.noreply.github.com>
处理说明(对 Codex 找问题、Antigravity 核验,新头
|
Antigravity(ubuntu)· #438 · 核验(15c6738)结论:可合。 实际核验完整 SHA: 1.
|
Codex · #438 · 找问题(15c6738 复核)可合。实际复核 head: 新头的 CI 状态重新查询了这个头,不沿用旧头结果:
全部检查共 5 成功、5 跳过,0 失败、0 待跑。Docs checks、Buck2 / Cargo、完整包等按路径跳过,不说成实跑通过。新头这次 synchronize 没有触发 Review gate;其写入路径的证据是下述 #440 实跑,不混为本头的 CI 检查。 逐项复核
更正我上轮的一句判断: “默认 latest 会排除旧失败检查”不能泛化到不同 check suite。上轮查的单次重跑样本只证明那一种形状,不能覆盖编辑描述后产生的新 suite;Antigravity 的 #439 反例成立。此次按名称跨 suite 去重才补齐了这一点。 我实际核了什么
未发现遗留 P1。未改文件、未 push、未合并。 |
定位与重述
协作流程的机械关卡,不动产品代码。
起因。 #433 的 CI 红了 45 分钟没人发现,最后是所有者看到「大家都在等」:
所有者问以后谁侦测、谁推动,并定:「我不希望这种harness是在agents.md里边的散文 - 我希望这是一个能被执行的mechanical动作,就是固定流程」。
重述。 「请审」要变成一个机器读得到、也改得动的状态,而不是一句评论。CI 红了,由机器把状态拨回去、告诉作者,不靠谁记得去看。
做法:用 GitHub 原生的草稿 / 就绪。
gh pr create --draft;作者gh pr ready <号>就是请审。Review gate(.github/workflows/review-gate.yml)在两个时刻检查 PR 当前头上三项必需检查(CI gate、Release gate、PR contract,正是 main 保护要求的三项)的最新结论:一是 PR 被标成就绪时(pull_request: ready_for_review),二是 Code、Release、PR contract 任一 workflow 跑完时(workflow_run: completed)。有一项是failure或timed_out,就gh pr ready --undo退回草稿,并留言列出红的检查和链接。workflow_run带着写权限也不执行 PR 里的任何东西。AGENTS.md「评审与合入」里「请审之前自己先过一遍」那一条,改写成上面的流程,另加一条说明 Review gate 做什么。
硬约束: 不加新的必需检查,不改 main 的保护规则;不检出 PR 代码。可协商: 草稿留言的措辞;要不要把
cancelled也算红(现在不算:新推送会取消旧运行,算进去会误判)。当前生效约束集
业界方案调研
gh pr create --draft、gh pr ready、gh pr ready --undo都是官方 CLI 的现成命令。ready_for_review是pull_request的原生事件类型,workflow_run是原生的「另一个 workflow 跑完」触发器。「CI 红了退回草稿」这一步,GitHub 设置里没有现成开关(分支保护只挡合并,不改 PR 状态),所以要一个 workflow 把这几样原生能力串起来,里面是约 30 行 shell。do-not-merge/*标签,或 Mergify 一类服务):要另装服务或维护标签约定。草稿状态是 GitHub 自带的,网页、gh pr list、各家 harness 调的gh pr view --json isDraft都直接读得到,比标签少一层约定。实测
查询逻辑在本机对真实的头试跑过(和 workflow 里用的是同一条
gh api … check-runs加 jq):e2e3bb8(Release gate 红过)→ 列出- Release gate:https://github.com/yesme/hctl2/actions/runs/39009375450/job/117329420966;c19b067(三项全绿)→ 什么都不列。三项检查在 check-run 里的名字就是
CI gate、Release gate、PR contract。ruby -ryaml解析 workflow 通过;run段单独抽出来bash -n通过;文档检查root//build/docs:profile-allPass 14。还没在真 PR 上跑过的两条路径,留给核验:
ready_for_review路径:PR 自己的 workflow 版本就会跑,合入前就能测。核验席另开一个故意让 PR contract 红的试验 PR,标成就绪,看它被退回草稿、有没有留言。workflow_run路径:只认默认分支上的 workflow,合入前测不了。合入后,下一个红的 PR 就是第一次实跑,我会在这里补记结果。本 PR 自己就是开成草稿的,CI 绿了才
gh pr ready。