Skip to content

fix(release): config.yaml 从 RP 的 extra-files 摘掉,并给每条自动位加"真能命中"的闸 - #123

Merged
ReSerendipity merged 2 commits into
mainfrom
fix/rp-extra-files-no-yaml
Sep 22, 2026
Merged

ReSerendipity merged 2 commits into
mainfrom
fix/rp-extra-files-no-yaml

Conversation

@ReSerendipity

@ReSerendipity ReSerendipity commented Sep 22, 2026

Copy link
Copy Markdown
Owner

为什么要改

#121 把 5 处版本位挂进 release-please-config.jsonextra-files,合进 main 后 release-please
立刻刷新了 #120(2.2.4)。这就是它第一次在真 PR 上被验,结论是有一条不能留:

$ git diff origin/main...pr-120 -- config.yaml | diffstat
 config.yaml | 320 +++++++++++++++++++-------------------

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.py 8 passed
{"type":"yaml","path":"config.yaml"} 加回去 test_extra_files_entries_are_all_actionable + 标注一致性
Cargo.toml 的 jsonpath 写成 $.package.versions ..._are_all_actionable(走不到 key)
只把 version.jsonversion 抬到 2.2.4(RP 的真实行为) 3 条:版本位互相矛盾 / actionable / changelog 与自身版本不符
还原 8 passed,git status 只剩本次改动
相邻回归 test_release_robustness + test_integrity_selfcheck_packaging + 本文件 = 24 passed
其他门禁 ruff check 通过;scripts/check_spec_refs.py 退出码 0;pre-commit 钩子无 Failed

追加:这条 PR 自己写错了一次,红在 CI 的 3.10 上(不是我改之前就有)

test_extra_files_entries_are_all_actionableTest (pytest) (3.10, {ubuntu,windows,macos})
三条全红,签名是同一条:

desktop/src-tauri/Cargo.toml:jsonpath $.package.version 走不到
  (__unread__:py<3.11 无 tomllib(该文件已由 _site_versions 的读取器覆盖))

我把"这个解释器没有 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):

情形 3.10 模拟 3.12
基线 4 条目标函数全 PASS 8 passed
Cargo.toml 的 package version 改成 2.2.9 test_all_version_sites_agree FAIL(证明兜底在真跑,不是静默跳过) parity + installer 命名 + actionable 三条 FAIL
还原 8 passed

合并之后会发生什么(不是"预计",是会被复看的两件事)

  1. RP 会在 main push 后重新刷新 chore(main): release 2.2.4 #120。预期它 config.yaml 那 320 行从 PR 里消失
    若还在,说明它没重算而是沿用旧 release 分支 —— 那就手工关掉 chore(main): release 2.2.4 #120 让它重开。
  2. chore(main): release 2.2.4 #120故意红在版本位一致性测试上:RP 抬了 5 处自动位,config.yaml / Cargo.lock /
    setup.nsi / k8s tag / version.json 的 changelog+release_date 是手工位。这是 §1 写明的预期行为,
    补一个 commit 即可。发版本身(tag + Release)仍按约定停在 owner 手上。

没覆盖到的

  • 没在真 runner 上验证 generic 类型(本 PR 没有新增 generic 条目,只写了它的命中检查逻辑)。
    第一次真用它的那条 PR 需要照例看 diff 行数。
  • desktop/package-lock.jsonscripts/installer/version.json 都在 .gitignore 里,
    不在任何闸的覆盖范围内 —— 它们是装配期产物,只能在真装/真打包那一步核对(仍等 owner 点头)。

#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
ReSerendipity merged commit 33769b5 into main Sep 22, 2026
30 checks passed
ReSerendipity added a commit that referenced this pull request Sep 22, 2026
docs(release): release PR 上没有 CI 检查这件事必须写下来(并纠正我在 #123 里的假设)
@ReSerendipity
ReSerendipity deleted the fix/rp-extra-files-no-yaml branch September 23, 2026 07:15
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>
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