fix(release): config.yaml 从 RP 的 extra-files 摘掉,并给每条自动位加"真能命中"的闸 - #123
Merged
Merged
Conversation
#121 把 5 处版本位挂进 release-please-config.json 后,RP 立刻刷新了 #120。真 PR 上的 diff 证明 `type: yaml` 不是"改一个字段":它 parse 完再 dump,把 config.yaml 的 232 行 改成 160 增 / 160 删,注释全灭(model_source_mode 选型说明、SSL 怎么打开、 vram_safety_margin_gb 的算式),连 "127.0.0.1" 的引号也被规范化。同一批里 json/toml 四条都是干净的 1 行 —— 破坏性只属于 yaml 写入器。 - release-please-config.json:删掉 config.yaml 那条(回到手工同步) - tests/test_version_consistency.py: * _RP_MANAGED 去掉 config.yaml,注释里留下这次实测的账 * 新增 test_extra_files_entries_are_all_actionable:类型只允许 json|toml|generic, 并逐条走 jsonpath 确认"当前值就是 canonical 版本号"(配错 key / 文件搬家 / 字段改名 都当场红,而不是发版当天发现 RP 静默少抬一处),generic 则要求行内标记在场 * 新增 test_bundled_changelog_describes_its_own_version:RP 只抬 version.json 的 $.version,不抬 changelog/release_date,而壳的 updater.rs 会读它展示给用户 —— 拦住"自称 2.2.4、说明写着 2.2.3"的包 - docs/release-governance.md:§1 改成"自动位 5 条 + 手工位 4 类"并写清为什么 yaml 不能用; 手工发版步骤补上"发完把 manifest 抬到刚发的版本"(否则两边在版本号上互踩); 把两处已经过时的"release-please.yml 是结构性空转"改掉 - docs/agents/GOTCHAS.md #147:教训是"能不能命中 ≠ 副作用大小",新配 extra-files 必须等一条真 release PR 看 diff 行数 门禁:test_version_consistency 8 passed(含 3 次变异复验——加回 yaml 条目 / 把 jsonpath 写成 $.package.versions / 只抬 version.json 的版本号,每次都红在对应的闸上); test_release_robustness + test_integrity_selfcheck_packaging 合计 24 passed; ruff check 通过;check_spec_refs.py 退出码 0。 Signed-off-by: ReSerendipity <zengyangc@outlook.com>
CI 矩阵里 3.10 三个平台全红,签名是同一条:
desktop/src-tauri/Cargo.toml:jsonpath $.package.version 走不到
(__unread__:py<3.11 无 tomllib(该文件已由 _site_versions 的读取器覆盖))
我把"这个解释器没有 TOML 解析器"和"jsonpath 走不到 key"塞进了同一个 `__unread__` 前缀,
于是缺解析器被当成配置错误。注释写着"已由站点读取器覆盖",但代码走的是 pending.append,
兜底根本没跑 —— 本地只有 3.12,所以这条只在 CI 上暴露。
改法:单独一个 _NO_PARSER 哨兵;命中它就不再报"走不到",交给 test_all_version_sites_agree
(它对 Cargo.toml 有正则读取器);只有连站点读取器都没覆盖这一位时才红。
两向都验(把 sys.modules["tomllib"] 设成 None 来模拟 3.10):
基线 3.10 模拟 4 条全 PASS / 3.12 全绿
Cargo.toml=2.2.9 3.10 模拟:test_all_version_sites_agree FAIL(兜底真在跑,不是空过)
3.12:parity + installer 命名 + actionable 三条 FAIL
还原 8 passed
Signed-off-by: ReSerendipity <zengyangc@outlook.com>
ReSerendipity
added a commit
that referenced
this pull request
Sep 22, 2026
docs(release): release PR 上没有 CI 检查这件事必须写下来(并纠正我在 #123 里的假设)
This was referenced Sep 22, 2026
ReSerendipity
added a commit
that referenced
this pull request
Sep 23, 2026
RP 的 `extra-files` 只覆盖 5 处自动位(`pyproject.toml` + `version.json` 的 `$.version` + `desktop/package.json` + `tauri.conf.json` + `Cargo.toml`)。剩下这些必须人补,见 `docs/release-governance.md` §1 第 1 条的账: - `config.yaml` 顶层 `version` —— 曾挂过 `type: yaml`,实测它会把整份文件重排并洗掉注释 (232 行 → 160 增/160 删、注释 96 → 0),所以在 #123 摘了,归手工。 - `desktop/src-tauri/Cargo.lock` 里自身包 `tts-multimodel-desktop` 的 version —— 归 cargo 生成。 - `scripts/installer/setup.nsi` 的 `OutFile` / `APP_VERSION` / `VIProductVersion` 三处 —— NSIS 注释符是 `;`,用不了 `generic` 要求的 `# x-release-please-version` 行内标记。 - `deploy/kubernetes/deployment.yaml` 两处 `image:` 的 tag(init 容器 + 主容器)。 - `version.json` 的 `release_date` 与 `changelog` —— **RP 只抬 `$.version`**,而壳的 `updater.rs` 会把 changelog 直接显示给用户,只抬版本号就会发出"自称 2.2.6、说明还写着 2.2.5"的包。 这条由 `test_bundled_changelog_describes_its_own_version` 拦。 - `docs/release-governance.md` §1 开头那句"已发布最新 = v2.2.6(2026-09-23)" —— 散文位, RP 不碰,v2.2.5 那次真漂过(版本号已经发出去、这行还停在上一版),所以被当版本位钉进 `test_all_version_sites_agree`。 `changelog` 写的是这一版真正修的东西:清单镜像名 `tts-multimodel` → 真实推的 `tts_multimodel`、 `imagePullSecrets` 与 README 的建法、docker-publish 的并发组、回滚 SOP 去掉 `v` 前缀; 并明确写上"真机侧的验收没重跑:这一版不含运行时代码改动"。 复算(发版判据,工作树 = RP 的 release 分支 + 本提交): `scripts/check_release_readiness.py --root .` → **rc=0**,10 处版本位全 = 2.2.6, 9 条判据全 PASS;`pytest tests/test_version_consistency.py tests/test_release_readiness_gate.py tests/test_image_name_consistency.py` → 通过。 `ruff` 不涉及(本次只动配置/清单/文档)。 Signed-off-by: ReSerendipity <zengyangc@outlook.com>
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.
为什么要改
#121 把 5 处版本位挂进
release-please-config.json的extra-files,合进 main 后 release-please立刻刷新了 #120(2.2.4)。这就是它第一次在真 PR 上被验,结论是有一条不能留:
type: yaml+jsonpath: $.version名义上只改第 1 行,实际是 160 增 / 160 删(整份 232 行重写)。注释行从 96 行变成 0 行(
git show origin/main:config.yaml | grep -c '#'= 96,git show pr-120:config.yaml | grep -c '#'= 0)。被洗掉的包括:models.model_source_mode上面那段 portable / shared 选型说明(6 行)server.ssl怎么打开 HTTPS 的 3 行说明vram_safety_margin_gb: 1.5的行内算式注释"127.0.0.1"/""的引号被规范化掉同一条 PR 上另外 4 条(
json× 3 +toml× 1)都是干净的 1 行改动 —— 破坏性是yaml写入器特有的:它 parse 完再 dump,不做原位替换;
generic才是行内正则替换(读了 release-please 的src/updaters/generic.ts确认:标记与版本号必须同一行,替换的是那一行里第一个 x.y.z)。改了什么
release-please-config.json:删掉config.yaml那条 → 它回到手工同步(与 Cargo.lock /setup.nsi / k8s 镜像 tag 同一类)。
tests/test_version_consistency.py:_RP_MANAGED去掉config.yaml,账写在它上方的注释里;test_extra_files_entries_are_all_actionable:类型只允许json|toml|generic,并逐条走 jsonpath 确认"当前取到的值就是 canonical 版本号" —— 配错 key、文件搬家、
字段改名都当场红,而不是发版当天发现 RP 静默少抬了一处;
generic则要求行内标记在场;test_bundled_changelog_describes_its_own_version:RP 只抬version.json的$.version,不抬同文件的changelog/release_date,而desktop/src-tauri/src/updater.rs会读本地
version.json的 changelog 展示给用户 → 拦住"自称 2.2.4、说明写着 2.2.3"的壳。docs/release-governance.md:§1 重写成"自动 5 处 / 手工 4 类"并写明 yaml 为什么不能用;手工发版流程补第 4 步(发完把
.release-please-manifest.json抬到刚发的版本,否则两边在版本号上互踩);把两处已经过时的"
release-please.yml是结构性空转"改掉 —— 它现在真的会开 PR。验收(每条闸都做了变异复验,不是"跑过了")
test_version_consistency.py8 passed{"type":"yaml","path":"config.yaml"}加回去test_extra_files_entries_are_all_actionable+ 标注一致性Cargo.toml的 jsonpath 写成$.package.versions..._are_all_actionable(走不到 key)version.json的version抬到 2.2.4(RP 的真实行为)git status只剩本次改动test_release_robustness+test_integrity_selfcheck_packaging+ 本文件 = 24 passedruff check通过;scripts/check_spec_refs.py退出码 0;pre-commit 钩子无 Failed追加:这条 PR 自己写错了一次,红在 CI 的 3.10 上(不是我改之前就有)
test_extra_files_entries_are_all_actionable在Test (pytest) (3.10, {ubuntu,windows,macos})三条全红,签名是同一条:
我把"这个解释器没有 TOML 解析器"和"jsonpath 走不到 key"塞进了同一个
__unread__前缀,于是缺解析器被当成配置错误。更糟的是注释写着"已由站点读取器覆盖",代码却走
pending.append—— 兜底那句根本没跑。我本地只有 3.12(
.venv是 3.12.10),所以这条只有 CI 能暴露。第二个 commit(
7289969)改成独立的_NO_PARSER哨兵:命中它就交给test_all_version_sites_agree(对 Cargo.toml 有正则读取器),只有连站点表都没覆盖这一位才红。两向都按上面的老办法验(把
sys.modules["tomllib"] = None模拟 3.10):Cargo.toml的 package version 改成 2.2.9test_all_version_sites_agreeFAIL(证明兜底在真跑,不是静默跳过)合并之后会发生什么(不是"预计",是会被复看的两件事)
config.yaml那 320 行从 PR 里消失;若还在,说明它没重算而是沿用旧 release 分支 —— 那就手工关掉 chore(main): release 2.2.4 #120 让它重开。
setup.nsi / k8s tag / version.json 的 changelog+release_date 是手工位。这是 §1 写明的预期行为,
补一个 commit 即可。发版本身(tag + Release)仍按约定停在 owner 手上。
没覆盖到的
generic类型(本 PR 没有新增 generic 条目,只写了它的命中检查逻辑)。第一次真用它的那条 PR 需要照例看 diff 行数。
desktop/package-lock.json与scripts/installer/version.json都在.gitignore里,不在任何闸的覆盖范围内 —— 它们是装配期产物,只能在真装/真打包那一步核对(仍等 owner 点头)。