ci(workflows): objectui-pin-freshness 补 merge_group 触发器,队列世代走 advisory 车道 (#6121) - #6252
Merged
Merged
Conversation
…y 车道 (#6121) 该 workflow 的注释明文邀请维护者把 `Console Pin Freshness` 加进 main 的 required 集,而它只订阅 pull_request + workflow_dispatch。合并队列在 gh-readonly-queue/** 世代上重新求值 required checks,一个在队列世代上不产生 check run 的 required context 会让每个世代永久等待(#3622 原型)。本仓队列是 活的(event=merge_group 共 2745 次运行,最近一批在今天 12:00 前后)。 三处改动,全部在同一文件内: 1. on: 增加裸键 merge_group:(与 ci.yml / lint.yml / spec-liveness-check.yml 同族写法)。 2. 邀请注释改写为带前置条件的邀请:加入 required 集之所以安全,正是因为 merge_group 触发器现在存在;后来的编辑者在保留/加入 required 前必须确认 该触发器仍在。 3. 车道判据由 `[ "$EVENT" != "pull_request" ]` 改为按事件显式分类。这一处是 加触发器的必要组成:该否定式在 on: 只有两项的年代等价于 workflow_dispatch, 加入 merge_group 后会把每个队列世代扫进 BLOCKING 车道,而脚本在 enforcing 模式下只要 pin != objectui main HEAD 就 exit 1 —— 即本文件自述的"两次 pin bump 之间的常态"。只加触发器会得到一个系统性飘红的队列检查,设为 required 后每个 PR 都被踢出队列,等于把 pending 死锁换成红色死锁,issue 想要的 "之后加 required 才安全"并不成立。新判据落实的是文件里已写下的既有政策 (blocks only on the release lane),不是新政策。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
hotlong
marked this pull request as ready for review
August 7, 2026 12:29
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6121
问题
.github/workflows/objectui-pin-freshness.yml的注释明文邀请维护者把Console Pin Freshness加进main的分支保护 required 集,而该 workflow 只订阅pull_request+workflow_dispatch,没有merge_group:。合并队列会在gh-readonly-queue/**世代上重新求值 required checks;一个在队列世代上根本不产生 check run 的 required context,会让每个队列世代永久停在 "Expected — waiting for status"(#3622 是这个死锁的原型)。同一文件自述『a required context that reports nothing leaves every PR stuck』——它写对了 PR 那一半,漏掉了队列那一半,然后据此发出了邀请。
风险窗口是活的,不是纸面推演。 按
event=merge_group查本仓 Actions:共 2745 次运行,最近几批是今天(2026-08-07)12:00 前后的gh-readonly-queue/main/pr-6240-…/pr-6210-…/pr-6233-…(CI、Lint & Type Check、Spec Liveness Check 三个 workflow)。队列每天都在跑,只差有人照注释做。前提复核(
origin/main@01faeb1):22 个 workflow 中订阅merge_group触发器的是ci.yml、lint.yml、spec-liveness-check.yml三个,本文件不在其列 —— issue 的前提成立。改法(单文件三处)
on:增加裸键merge_group:—— 与ci.yml/lint.yml/spec-liveness-check.yml的同族写法一致(裸键,附注释指向 ci.yml 的完整说明),不是types: [checks_requested]。⛔ 按分诊钉死:没有把
Console Pin Freshness加进任何 required 集(设置面归维护者,#5617),也没有碰任何其他文件。注释前后对照(第 34-39 行那段邀请)
改前(只说「维护者必须去加」,不说前提):
改后:保留上面全部原文(那段观察本身是对的),追加前提与验证义务 ——
即:把它原本正确的那半句观察,接上了它漏掉的队列那半句。
为什么第 3 处必须一起改(测量,不是猜测)
步骤里的车道判据原文是:
在
on:只有两个条目的年代,!= pull_request就等于「workflow_dispatch」。加merge_group:恰好是这个代理失效的时刻:merge_group事件下该否定式为真 ⇒ 队列世代走 BLOCKING 车道(不带--advisory直接跑脚本)。而脚本在 enforcing 模式下的语义(
scripts/check-objectui-pin-fresh.mjs,已读):git ls-remote单独决定判决,.objectui-sha!= objectuimainHEAD 即stale⇒ exit 1。这正是本文件自述的「两次 pin bump 之间的常态」(WHERE IT BLOCKS 段:『Between pin bumps an ordinary code PR sits behind objectui almost always — that is the normal state of the repo, not a defect, and failing every PR over it would train everyone to ignore this check』)。结论:只加触发器,会造出一个系统性飘红的队列检查;维护者一旦照邀请把它设为 required,红检查会把每个 PR 踢出队列 —— 那是把「永久 pending 死锁」换成「永久红死锁」,issue 要的「之后再加 required 才是安全的」并不成立。所以判据按文件既有的、已写死在注释里的政策显式化:
workflow_dispatchmerge_grouppull_requestrun 把关,release.yml 还在发布路径上再跑一次同一脚本(无 override input)pull_request这不是新政策,是把文件里已经写下的政策补齐到新事件上。反过来说,若维护者认为队列世代应当 blocking,改法只是把
merge_group挪进判据 —— 但那等于接受「pin 落后即全队飘红」,与该文件的设计自述冲突。队列世代实际会做什么(逐条)
Self-test the gate(离线,零依赖)+node scripts/check-objectui-pin-fresh.mjs --advisory。git ls-remote https://github.com/objectstack-ai/objectui.git main定判决;仅在已判定 stale 时才发 3 个 GitHub API 调用去列举滞后内容(fresh 时零 API 调用)。unreadable;unreadable在 advisory 模式下打::warning::并 return 0,只有 enforcing 模式才 exit 1。所以队列世代里的网络抖动/限流不会把 PR 踢出队列。这正是第 3 处改动买到的东西。pull_requestrun 判定之后、到它在队列里落地之间,若 objectuimain前进,队列世代不会再次拦截(它是 advisory)。兜底在release.yml的发布路径步骤Console pin is fresh (#3340 — enforcing on the publish path)—— 那里直接跑脚本且刻意没有 override input。也就是说漏网窗口只在「发布 PR 排队的几分钟」,且被发布路径这道无法绕过的闸门覆盖。concurrency.group为${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }};merge_group下pull_request为空,回落到github.ref(每个队列世代唯一的gh-readonly-queue/main/pr-N-SHA),世代之间不会互相取消。与 ci.yml 同一模式,无需改动。验证
1. 车道映射 —— 直接执行文件里 shipped 的那段 shell(把两处
node scripts/...换成 lane 标记,其余是原文):改后(本 PR):
反向验证(预测在先:用
origin/main的原判据 —— 即「只加触发器」会 ship 的那个版本 —— 队列世代必然落到 blocking):唯一变化的格子就是
merge_group:blocking → advisory,四个既有车道逐字未变。2. 门禁(worktree,pnpm install 后):
3. YAML 与名字稳定性(
python3 yaml.safe_load):4. workflow 首步与真实 advisory 跑通:
(顺带一条现场事实:此刻 pin 恰好等于 objectui
mainHEAD7dfbeb70,所以今天即便走 blocking 车道也是绿的 —— 系统性飘红要等 objectui 下一次 merge。这恰恰说明只加触发器的做法会绿着上线、几小时后才开始咬人,更值得现在就把车道钉死。)未做(刻意)
skip-changeset。Console Pin Freshness(重命名会静默脱钩 required 检查,chore(ci): cut PR wall-clock ~9.5min → ~5-6min — dedupe dogfood, shard it, cache lint's build #3622)。Generated by Claude Code