Repository navigation
fix(release): 发版准备工作流可重入——已有 PR 不动分支,只覆盖机器产出 - #473
Conversation
两次在真实 main 上跑 v0.9.1 的 Release Prep,八步里前七步都成功,
每次都卡在最后一步,但原因不同:
1. 第一次(run 39123249758)gh pr create 被拒:
GraphQL: GitHub Actions is not permitted to create or approve pull requests。
工作流 job 里的 pull-requests: write 只是声明式权限,总开关在仓库
Settings → Actions → General;组织默认关闭时仓库层改不动(gh api PUT 返回 409)。
代码这边能做的只有把失败说清楚,报错要点名去哪个页面、开哪个开关。
2. 第二次(run 39126751114)更早就挂:release-prep/0.9.1 已存在,
push 被 fetch first 拒——这条工作流原本不可重入。
不可重入的代价不是重跑失败这么轻:人会以为流程坏了,转去手工发版,
整套自动化就此被绕开。
修法:推分支前加三档守卫——
· 分支上有进行中的 PR:什么都不动、静默退出(分支上可能已有人补条目)
· 没有 PR 且顶端是上次机器产出:按重跑处理,用 --force-with-lease 覆盖
(不是 --force:远端在 fetch 之后被推过就拒)
· 其余:停下,要人先确认那条分支是谁的
回归锁加在 test/workflow-guards.test.js 两条,五处变异验证全部变红。
其中报错文案那条第一版是 GREEN——对全文 grep 会被注释里解释这件事的
文字骗过,改用 codeOnly() 剥注释后才真正锁住;同理,判定那条断言的是
if 本身而不是变量名,否则变量名留在 case 里、判定删掉照样绿。
车道内 npm test: 2173 tests / 2172 pass / 0 fail / 1 skip
check-sync: 72 个文件一致
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 16 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
[0.9.1] 节此前只有 #466–#473 的文档、安全与发版条目共 11 条, 而 v0.9.0 的 tag(94d855e)之后共有 65 笔非合并提交,扣掉 13 笔 纯徽章同步,还有 52 笔实质提交从没进过任何 CHANGELOG 节 —— 直接发出去等于把一个完整的 M.O. 运行时悄悄发布到 npm。 补四节: - 🆕 新增 8 条:M.O. 写侧(执行窗口 + 运行账 + 归属候选)、会话事件 翻成观察、P1/P2/P3 三级、步骤 assert 与 optional、R1/R2 提议、 沉淀链草稿挖掘、人格定义页 v1.2 - 🐛 修复 6 条:#460 检查更新把成功报成失败、#450 向量写入回执与行级 模型出处、#458 账本 ids 跨块引用被 catch 吞、candidates.js 双 CR 行尾、 peer 范围、effective 键计数锁 - 🎨 面板 1 条:#448 三轮 UX 复检 - 📚 文档 2 条:#466 门面、#467 SECURITY.md - 🧪 内部与测试 2 条:注释裸行号改符号名 + 零消费者代码清理 节序按功能面重排(新增 / 修复 / 面板 / 文档 / 安全 / 发版与文档 / 仓库结构 / 内部与测试),[Unreleased] 仍留空。 同时补上三处人写内容: - 根 README 的 News 表中英各两行(M.O. 写侧、人格页 v1.2) - 根 README 路线图 v0.9 行状态改成「已发布(至 v0.9.1)」并补写侧主题 - 子 README 版本历史 v0.9.1 行填上主题 验证:npm test 2173 tests / 2172 pass / 0 fail / 1 skip;check-sync 72 文件一致;security-doc + release-notes + release-docs + changelog-prep + workflow-guards 共 49 条全过;Release 正文渲染 39752 字符,默认可见 38 行 / 10334 字符(v0.9.0 是 60 行 / 29921 字符)。
* chore: v0.9.1 发布准备(版本号 + 测试徽章 + CHANGELOG/版本表占位行) 机械部分已由 scripts/release-prep.mjs 完成。合并前还需要人来写: - [ ] dsh-mneme/CHANGELOG.md 新节里的条目(现在只有一条「- (待填)」) - [ ] 两个 README 里新占位行的主题描述 - [ ] 根 README 的「📰 最近更新」/「📰 Recent updates」表各加一行头条 - [ ] 跨 minor 时确认 README 路线图上新 minor 行的主题(占位行只写了「(待填)」) - [ ] 跨 minor 时把 SECURITY.md 中英两张支持版本表挪一格(活跃开发 / 尽力维护 / 不支持三段一起挪,含停止维护那段通知) * chore(release): v0.9.1 补上 tag 之后 52 笔提交的功能条目 [0.9.1] 节此前只有 #466–#473 的文档、安全与发版条目共 11 条, 而 v0.9.0 的 tag(94d855e)之后共有 65 笔非合并提交,扣掉 13 笔 纯徽章同步,还有 52 笔实质提交从没进过任何 CHANGELOG 节 —— 直接发出去等于把一个完整的 M.O. 运行时悄悄发布到 npm。 补四节: - 🆕 新增 8 条:M.O. 写侧(执行窗口 + 运行账 + 归属候选)、会话事件 翻成观察、P1/P2/P3 三级、步骤 assert 与 optional、R1/R2 提议、 沉淀链草稿挖掘、人格定义页 v1.2 - 🐛 修复 6 条:#460 检查更新把成功报成失败、#450 向量写入回执与行级 模型出处、#458 账本 ids 跨块引用被 catch 吞、candidates.js 双 CR 行尾、 peer 范围、effective 键计数锁 - 🎨 面板 1 条:#448 三轮 UX 复检 - 📚 文档 2 条:#466 门面、#467 SECURITY.md - 🧪 内部与测试 2 条:注释裸行号改符号名 + 零消费者代码清理 节序按功能面重排(新增 / 修复 / 面板 / 文档 / 安全 / 发版与文档 / 仓库结构 / 内部与测试),[Unreleased] 仍留空。 同时补上三处人写内容: - 根 README 的 News 表中英各两行(M.O. 写侧、人格页 v1.2) - 根 README 路线图 v0.9 行状态改成「已发布(至 v0.9.1)」并补写侧主题 - 子 README 版本历史 v0.9.1 行填上主题 验证:npm test 2173 tests / 2172 pass / 0 fail / 1 skip;check-sync 72 文件一致;security-doc + release-notes + release-docs + changelog-prep + workflow-guards 共 49 条全过;Release 正文渲染 39752 字符,默认可见 38 行 / 10334 字符(v0.9.0 是 60 行 / 29921 字符)。 * docs(readme): 路线图状态格退回 v0.9.0,别在打 tag 之前宣布 v0.9.1 已发布 CodeRabbit 指出中英文路线图的 v0.9 行写成了「已发布(至 v0.9.1)」,而本 PR 只是发版准备,tag 要等合并之后才打。这条与 scripts/release-docs.mjs 里既有的 取舍一致:脚本刻意不改写「已发布(v0.9.0)」,因为它在打 tag 之前跑,改了就等于 提前宣布一个还没发出去的版本,PR 若被放弃那行立刻变成谎话。手写时违反了这条。 只退状态格,v0.9 行的主题描述(本次新补的写侧面)保持不动。 --------- Co-authored-by: modusensus <[email protected]>
起因
为发 v0.9.1,在真实 main 上跑了两遍新版 Release Prep 工作流。八步里前七步全 success,两次都只卡在最后一步——但原因完全不同,是两条独立的缺陷。
真因一:开 PR 被组织策略拒(run 39123249758)
工作流 job 里写着
pull-requests: write,但那只是声明式权限,不是总开关。实测:我用
gh api -X PUT想打开它,返回 409 Conflict:The organization does not allow GitHub Actions to create or approve pull requests——开关在组织层,仓库层改不动。这条只能人去开,代码侧能做的是把失败说清楚。真因二:工作流不可重入(run 39126751114)
第一次运行已经把分支推上去了,第二次就撞。不可重入的代价不是「重跑失败」这么轻:人会以为流程坏了,转去手工发版——而那正是这套自动化想避免的结果。
改法:推分支前三档守卫
::warning::说明并exit 0。分支上可能已有人补了 CHANGELOG 条目——那正是留给人的那部分工作,覆盖掉比不能重跑更糟modusensus、标题chore: v<V> 发布准备)--force-with-lease=refs/heads/<分支>:<fetch 到的 SHA>覆盖::error::停下,要人先确认那条分支是谁的用
--force-with-lease而不是--force:远端在我们 fetch 之后被推过就拒绝,宁可失败也不悄悄覆盖。开 PR 失败时给可行动的报错(去哪个页面、开叫什么名字的开关、然后重跑——此时还没有 PR,守卫会覆盖机器产出,不会丢任何人的改动)。
回归锁
test/workflow-guards.test.js5 → 7 条:--state open的查询排在git push之前、用了--force-with-lease而非--force、且if [ "$MACHINE_TAIL" != "yes" ]这个 if 本身在(不是只查变量名——变量名留在 case 里、判定被删掉照样绿)。codeOnly()剥掉注释后再断言三条文案串。变异验证(五处全部变红)
--force退回无条件后两条第一次是 GREEN 未捕获——对全文 grep 会被注释里解释这件事的文字骗过;判定那条同理。两处断言加严后才真正锁住。
验证
npm test:2173 tests / 2172 pass / 0 fail / 1 skipnode scripts/check-sync.js:✓ 72 个文件一致run:块bash -n语法通过合并后还需要人做一件事
组织 Settings → Actions → General → 打开 Allow GitHub Actions to create and approve pull requests。不开的话,Release Prep 会一直停在最后一步(但报错现在会告诉你去哪开)。