Skip to content

docs(release): 自动发版路径的三条边界(手工位/DCO/不吃镜像)+ 第 10 处版本位入闸 - #136

Merged
ReSerendipity merged 2 commits into
mainfrom
docs/release-playbook-225
Sep 22, 2026
Merged

ReSerendipity merged 2 commits into
mainfrom
docs/release-playbook-225

Conversation

@ReSerendipity

@ReSerendipity ReSerendipity commented Sep 22, 2026

Copy link
Copy Markdown
Owner

为什么

v2.2.5 是本仓第一条由 release-please 自己发出去的版本(tag 9125a3e,Release + 4 个资产由 build-release 挂上)。这条路径以前只写过"应该能用",现在是"今天真的走通了",但走通的过程里踩到的事都不写下来的话,下次还是靠人记。

A. RP 的自动位 / 手工位分界

  1. RP 只抬自动位(pyproject.toml + 3 个 json),5 类手工位要人在 release 分支上补一条提交。而且补完必须紧接着合 —— 任何一次 main push 都会让 RP 重写那条分支、把补齐提交冲掉(今天真冲掉过一次 1c2597a)。
  2. DCO 曾经让 release PR 结构上不可合:RP 的提交作者是 github-actions[bot],签不出与自己邮箱匹配的 Signed-off-byfix(ci): DCO 按提交作者豁免自动化 —— 否则自动发版路径结构上不可用 #135 已按提交作者豁免。
  3. release PR 拿不到 CI(GitHub 规定 GITHUB_TOKEN 产生的提交不再级联触发 workflow)。ci(release): 加发布条件闸(release PR 拿不到 CI,合并前需要机器判据) #134release-gate commit status 补了可见信号;但合并前判据仍要在本地跑 scripts/check_release_readiness.py

B. 同一条不级联规则还吃掉了"发镜像"这一步(本 PR 新发现,代价最大的一条)

核对 v2.2.5 的下游触发时量出来的对照:

tag docker-publish.ymlev=push br=vX.Y.Z gpg-signed-release.ymlev=release
v2.2.2 有(success)
v2.2.3 有(success)
v2.2.4 有(success)
v2.2.5(RP 自己打的 tag) 0 条 0 条

因为 RP 的 tag 和 Release 都是 bot 用 GITHUB_TOKEN 建的,GitHub 不为它们级联 workflow —— 和 #128 记的"release PR 没有 CI"是同一条规则的另一面。

现在的仓库状态是自相矛盾的deploy/kubernetes/deployment.yaml:40,61 已手工同步到 ghcr.io/reserendipity/tts-multimodel:2.2.5,而 ghcr 上没有这个标签(清单自称能上线,实际拉不到镜像)。而且不能靠把镜像 tag 退回 2.2.4 消红 —— test_all_version_sites_agree 会把版本位一致性一起判红。唯一自洽的修法是补跑一次:

gh workflow run docker-publish.yml --ref v2.2.5

metadata-actiontype=semver 在 tag ref 上就能产出 :2.2.5工作流不用改。这一步是往共享 registry 推标签,按"Release 侧动作交回 owner"的约定没有执行,留给所有者点头(见下面的"没做什么")。

GPG 那一格今天不痛:GPG_PRIVATE_KEY 未配,作业进 skip 分支只出 ::notice::(2.2.2–2.2.4 那三条"success"其实是空转)。但密钥配上之后,RP 发的每个版本都要把这条一起手工补跑 —— 也写进 §1 了。

C. 第 10 处版本位入闸

§1 开头那句 已发布最新 = v<X.Y.Z> 是散文,RP 不碰它,所以 v2.2.5 发完之后它一直停在 v2.2.4 —— 文档在自称"最新已发布的是上一个版本"。现在 test_all_version_sites_agree 把它当第 10 处版本位一起核对。

改了什么

  • docs/release-governance.md §1:把 A 的三条 + B 的"不发镜像/不签名"落成可操作判据(补完即合、合并前本地跑脚本、DCO 已豁免、合完立刻 gh workflow run --ref)。
  • docs/release-governance.md §1 末:修掉一句已经过期的话 —— 原文还在说"要变成机器闸就得自己配一个报 commit status 的作业,那是权限决策、不在现状里",而 ci(release): 加发布条件闸(release PR 拿不到 CI,合并前需要机器判据) #134 已经建出来了(报 release-gate,不拦截)。
  • docs/release-governance.md §2 第 5 步:加"自动路径要自己踩镜像这一步"+ 复算命令。
  • 测试口径:test_all_version_sites_agree 钉第 10 处版本位;test_release_readiness_gate.py_CARRIERS fixture 同步搬这个文件(否则它在新站点上以"取不到版本号"崩掉,而不是判出漂移)。

验证

  • 上表是量出来的,不是推断:gh run list --workflow docker-publish.yml --limit 60gh run list --workflow gpg-signed-release.yml,两条查询各自给出 3 条历史 tag run、0 条 v2.2.5。
  • 变异复验:把文档 已发布最新 那行手工改回 v2.2.4test_all_version_sites_agree ;改回 v2.2.5 → 8 passed。
  • pytest tests/test_version_consistency.py tests/test_release_readiness_gate.py tests/test_docker_cache_budget.py → 14 passed。

没做什么

  • 没有推镜像:gh workflow run docker-publish.yml --ref v2.2.5 待 owner 点头。在那之前 deployment.yaml 指的 :2.2.5 在 ghcr 上确实不存在 —— 这一点写进文档,不当已解决。
  • 不动版本号、不产 release。纯文档 + 一处测试口径。
  • 没给 release PR 配真 CI(不级联这条改不了,能做的只是 release-gate 那种旁路信号)。

v2.2.5 是本仓第一条由 release-please 自己发出去的版本(tag 9125a3e、Release + 4 个资产由
build-release 挂上)。这轮踩到的三件事都写进 §1,否则下次还是靠人记:

1. RP 只抬 5+1 处自动位,5 类手工位要人在 release 分支上补一条提交 —— 而且**补完必须紧接着合**:
   任何一次 main push 都会让 RP 重写那条分支,把补齐提交冲掉(今天真冲掉过一次 1c2597a)。
2. DCO 曾让 release PR 结构上不可合(RP 的提交作者是 github-actions[bot],签不出 Signed-off-by),
   #135 已按提交作者豁免。
3. release PR 拿不到 CI(#134 的 release-gate 补了可见信号;合并前判据仍要本地跑
   scripts/check_release_readiness.py)。

同时把一句散文纳入闸:§1 开头的"已发布最新 = v<X.Y.Z>"。它 RP 不碰,于是 v2.2.5 发完后
这里还停在 v2.2.4 —— 现在 test_all_version_sites_agree 把它当第 10 处版本位核对。
变异复验:把该行改回 v2.2.4 → 那条闸红;改回来 → 8 passed。
test_release_readiness_gate 的 fixture 同步搬这个文件(否则它会以"取不到版本号"失败而不是判出漂移)。

16 passed(版本位 8 + 发布条件闸 4 + DCO 豁免 4);ruff check / format --check 通过。

Signed-off-by: ReSerendipity <zengyangc@outlook.com>
v2.2.5 发完之后核对下游:`gh run list --workflow docker-publish.yml` 上 v2.2.2 / v2.2.3 /
v2.2.4 各有一条 `ev=push br=vX.Y.Z`,**v2.2.5 一条都没有**;`gpg-signed-release.yml` 同理
(三条 `ev=release`,2.2.5 缺席)。原因是同一条 GitHub 固定行为 —— bot 用 `GITHUB_TOKEN`
产生的事件不级联,而 RP 打的 tag 和建的 Release 正是它产的。#128 只写过"release PR 拿不到 CI"
这一面,没写它会连带吃掉 tag/release 两个下游触发,于是本次实测才发现。

后果是具体的:`deploy/kubernetes/deployment.yaml:40,61` 手工同步到了
`ghcr.io/reserendipity/tts-multimodel:2.2.5`,而 ghcr 上今天没有这个标签。两处都不能退回
2.2.4 消红(`test_all_version_sites_agree` 会把版本位一致性判红),所以唯一的自洽修法是补跑
`gh workflow run docker-publish.yml --ref v2.2.5` —— `metadata-action` 的 `type=semver`
在 tag ref 上就能出 `:2.2.5`,工作流不用改。这一步按"Release 侧动作交回 owner"的约定留给所有者点头。

顺带修一处已经过期的话:§1 末尾那段还在说"要把它变成机器闸就得配一个能报 commit status 的作业 ——
那是权限决策,不在现状里",而 #134 已经把它建出来了(报 `release-gate`、不拦截)。

GPG 那一格现在不痛(`GPG_PRIVATE_KEY` 未配 → 作业进 skip 分支只出 notice),但密钥配上之后
RP 发的每个版本都要手工补跑,这条也写进 §1 第 4 条,免得下次又当成"自动路径会替我做"。

验证:`pytest tests/test_version_consistency.py tests/test_release_readiness_gate.py
tests/test_docker_cache_budget.py` → 14 passed(basetemp 换掉才跑起来:
`pytest-of-Doro/pytest-current` 有残留目录导致 WinError 5,与本改动无关)。
`已发布最新 = v2.2.5` 一行未动,第 10 处版本位仍与 9 处代码位一致。

Signed-off-by: ReSerendipity <zengyangc@outlook.com>
@ReSerendipity ReSerendipity changed the title docs(release): 把自动发版路径首次走通落成可复用判据,并钉住第 10 处版本位 docs(release): 自动发版路径的三条边界(手工位/DCO/不吃镜像)+ 第 10 处版本位入闸 Sep 22, 2026
@ReSerendipity
ReSerendipity merged commit d2d538a into main Sep 22, 2026
30 checks passed
@ReSerendipity
ReSerendipity deleted the docs/release-playbook-225 branch September 23, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant