fix(ci): check-adr-0087-registration 的 CLI 派发加入入口守卫,import 不再跑门禁 (#6566) - #6695
Conversation
`scripts/check-adr-0087-registration.mjs` 在模块顶层读 `process.argv` 并直接 派发(`--self-test` / `--list` / `--audit-stock` / 门禁本体),没有比较 `import.meta.url` 与 `process.argv[1]` 的入口守卫。后果是:任何一次 `import` 都会真的把门禁跑在**调用方的仓库**上,判红时六个 `process.exit(1)` 里的一个还会直接掐死调用方进程 —— 调用方自己的代码一行都执行不到。 改为 `objectui-changeset-digest.mjs` 已有的写法:仅当本文件是进程入口时才 派发。`argv` / `readFlag` 只被派发用到,一并收进守卫块内;模块顶层此后只剩 纯常量计算(`REPO_ROOT` 由 `__dirname` 推出,不外调 git),import 无副作用。 判定逻辑、词表、分支行为、`--self-test` 的位置一概未动。CLI 输出与退出码 逐字节比对 origin/main 基线:`--list`、`--audit-stock`、门禁本体、 `--base <不存在的 ref>` 四条路径 stdout/stderr 全等,退出码全等。 自测新增 I1/I2 两组共 7 条断言(100 → 107): - I1:在一个**判红**的临时仓库里 `import` 本脚本的纯导出,必须不跑门禁、 不打印判词、不改退出码; - I2:同一个 fixture 下把同一份文件当入口跑,门禁仍判红并 exit 1,`--list` 仍打表并 exit 0。 反向验证(两个方向都实测):去掉守卫恢复顶层派发 → I1 三条全红、I2 不动; 把 CLI 块从被拷贝的脚本里删掉 → I2 四条里红三条、I1 不动。第四条 (`--list` 退出码为 0)在后一种消融下仍为绿 —— 没有 CLI 的脚本同样退出 0, 退出码分不清「分支跑了且成功」和「什么都没跑」,故每条退出码断言都配了一 条输出断言。 顺带修正 `objectui-changeset-digest.mjs` 里一处**注释**:它原文断言本脚本 「CLI dispatch runs at TOP LEVEL (it has no `import.meta.url === argv[1]` guard)」,本 PR 之后该陈述为假。只改注释,不动代码。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AZgRyPVwi1jLb1mNNuUQ9o
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
PM: 正文的 changeset 判断是对的(scripts-only、不发布任何包、同文件三次前例均无 changeset),但声明跳过的机制是标签,不是正文里的论证 —— 门禁读的是标签。这两件事被合并了,而它们不是一件事。 这不是挑毛病,是同一天同一座位刚犯过的错:PR #6688(我自己写的)一小时前以完全相同的形态判红 —— 正文把依据论证得很完整,标签没打。所以本轮起把它写进派单模板:决定走 ⏱️ 时间点值得记:#6378 给这道门加的「结算读」窗口是 PR 创建后 120 秒。本 PR 创建于 12:57:54Z,本次补标签落在窗口边缘 —— 若赶上,首跑直接绿;若擦过,需要重跑一次。#6688 那次是超窗后才补,所以那道本该救场的机制没能生效。开 PR 即带标签同时也让这个窗口根本不必登场。 Generated by Claude Code |
|
时间线实测:
所以上一条里「正文论证了、标签没打」是基于一次过时读数的错误指控,并非事实;把它说成「同一天第二次踩同一个坑」更是错上加错 —— #6688 那次是我自己的问题,与本 PR 无关。实施方在这一点上做得完全正确,而且比我更早。 一条给我自己的教训,记在这里而不是私下改掉:看到「缺了什么」时,要先确认自己的读数是不是比对方的写入更早,尤其在几十秒量级的并发窗口里。我上一条评论的处置(补标签)无害,但结论下得太快 —— 正确的顺序是先复读一次再判断,而不是拿一次读数当既成事实。 上一条评论里唯一仍然成立的部分:「决定跳过就在开 PR 那一步带上标签」这条派单模板改进 —— 它来自 #6688 的真实教训(我自己超出 #6378 的 120 秒结算窗口才补标签),与本 PR 的实施方无关。 Generated by Claude Code |
Fixes #6566
问题
scripts/check-adr-0087-registration.mjs在模块顶层读process.argv并直接派发(--self-test/--list/--audit-stock/ 门禁本体),没有比较import.meta.url与process.argv[1]的入口守卫。后果是:任何一次
import(哪怕只为借一个纯函数)都会真的把门禁跑在调用方的仓库上;判红时六个process.exit(1)里的一个还会直接掐死调用方进程 —— 调用方自己的代码一行都执行不到。PR #6556 已经为此付过 ~40 行子进程夹具的代价,#6559 的开发则不得不在 import 前打桩process.exit。改动
改为仓内现成的写法(
scripts/objectui-changeset-digest.mjs:1952同款):仅当本文件是进程入口时才派发。argv/readFlag经确认只被派发用到,一并收进守卫块内。模块顶层此后只剩纯常量计算(REPO_ROOT由__dirname推出,不外调 git),import 无副作用。⛔ 判定逻辑、词表、分支行为一概未动(#6497/#6559/#6350 的面);⛔
--self-test在哪跑也没动(#6509 的面)。CLI 等价性:逐字节比对 origin/main 基线
把
origin/main版本放在同一目录下跑(保证REPO_ROOT解析一致),四条路径 stdout/stderr 全等、退出码全等:--list--audit-stock--base传不存在的 ref调用方全部复核:
.github/workflows/pr-automation.yml:721-722与package.json:65都以入口方式调用,不受影响。新增断言(100 → 107)
import本脚本的纯导出:必须不跑门禁、不打印判词、不改退出码。--list仍打表并 exit 0。I2 是 I1 缺不得的另一半:光有 I1,把整个 CLI 块删掉也能通过 —— 它只断言「什么都没发生」。
反向验证(两个方向都实测,非预测)
got 1;importer 自己的行没跑;门禁判词泄漏进自测输出),I2 不动。诚实记录第四条:
--list退出码为 0 这条在后一种消融下仍为绿 —— 没有 CLI 的脚本同样退出 0。退出码分不清「分支跑了且成功」和「什么都没跑」,所以每条退出码断言都配了一条输出断言,这一点写进了 I2 的注释。关于 PR #6556 子进程夹具的「简化」——不做,并说明为什么
分诊把它列为可选的顺手项(「纯粹为绕开本问题而存在」)。读过之后判断这个前提不成立,故不动它:
scripts/objectui-changeset-digest.mjs:1874-1938的 #6494 往返夹具钉的是「真门禁对一份生成产物的判词」,红、绿两个方向都断言了精确的 stderr/stdout 与退出码。这需要门禁自己跑一遍才能settle,换成 import 会把命题换成更弱的一个,还会把发版关键的 bump 路径耦合到门禁内部实现上。它不是在绕 import 不安全,而是在做跨脚本的端到端验证。反过来说,这个夹具正好是本 PR 的独立 CLI 等价性证人:它把改动后的脚本拷进临时仓当入口跑 ——
pnpm check:objectui-changeset全绿,两条 ROUND TRIP 断言都过。㉕ 范围外披露:同时改了第二个文件的一处注释
scripts/objectui-changeset-digest.mjs原注释断言本脚本「CLI dispatch runs at TOP LEVEL (it has no import.meta.url === argv[1] guard)」—— 本 PR 之后该陈述为假。改为保留仍然成立的耦合理由、并注明顶层派发已在 #6566 加守卫。只改注释,不动代码;该文件的--help只抽取//开头的行,这处是 JSDoc 块,输出不受影响,自测也不读自身源码文本。Changeset
无。scripts-only、不发布任何包,依 #6558 先例(同文件的
501c945/89a0b6af8/e6a7e2699三次改动均无 changeset)—— 走skip-changeset。门禁
🤖 Generated with Claude Code
https://claude.ai/code/session_01AZgRyPVwi1jLb1mNNuUQ9o
Generated by Claude Code