ci: derive the fresh-install version instead of hand-editing it, and document releasing - #321
Merged
Merged
Conversation
…document releasing `ci-fresh-install.yml` carried MCPP_PIN as a hardcoded literal that a maintainer had to bump on every release. It was never the same thing as the `.xlings.json` pin it was kept equal to: MCPP_PIN is the version UNDER TEST — always the newest published release — while `.xlings.json` is the version BOOTSTRAPPED FROM, which only has to be a released mcpp that can build the current tree. The workflow already computed the right answer. Its `wait-index` guard queries the releases API for the newest tag, waits for xim-pkgindex to track it — and then discards it, while the install jobs used the literal. That gap is exactly the #265 failure: the guard reported "index tracks 0.0.102" and the jobs installed 0.0.100 ten seconds later, meeting an index whose floor was 0.0.101. wait-index now exports the derived version and all four install jobs consume it. Both properties the literal was protecting hold, and one of them structurally: explicit version a derived string is as explicit as a literal, so a lagging runner index still fails loudly with `version not found` rather than silently testing an older binary one source the guard and the jobs cannot disagree about which version is under test, because there is only one value Deriving happens on every trigger, not just post-release — "the newest published release" is the version under test on cron and manual runs too. Only the WAIT stays conditional, since only a post-release run can legitimately race the index. A non-numeric or empty API result is refused, because `mcpp@` with an empty version degrades into bare `mcpp` — straight back to "newest in the runner's index copy". check_version_pins.sh loses the now-meaningless "both pin sites agree" invariant and gains a guard against a literal MCPP_PIN reappearing (probe-tested: it fails when the literal is restored, passes when it is not). Also adds docs/09-release.md (+ zh), which did not exist. The release process lived in commit messages and workflow comments only. It documents the two version groups, what the pipeline automates and what it does not, how to verify a release without trusting a sha256 sidecar, and the index's CDN propagation lag. It also corrects 3b1cb6b, which claimed "the index no longer serves .1" and made the bootstrap bump look mandatory. That diagnosis is wrong — 2026.7.29.1 installs fine from the current index, which retains all 105 published versions; the real cause was a stale local index copy. The bump is a useful check (a green round proves the new release can self-host), not a prerequisite. The one hard rule is direction: never pin a version that is not yet installable.
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.
起因
「为什么每次发版都要手改 CI 里那个版本号?」——查下来答案是:不必要,而且 workflow 自己早就算出了正确答案,只是把它扔掉了。
MCPP_PIN从来不是.xlings.json的同一样东西它俩被
check_version_pins.sh强制相等,但语义不同:MCPP_PIN.xlings.json把它俩绑在一起,就为一个 workflow 本可自行推导的值,强加了一次每发布必做的手工编辑。
workflow 早就在推导,然后扔掉
wait-index守卫查 releases API 拿最新 tag、等 xim-pkgindex 追上它 —— 然后丢弃,而安装 job 用的是写死的字面量。这个缝就是 #265:守卫报index tracks 0.0.102,10 秒后 job 装的是 0.0.100,撞上 floor 为 0.0.101 的索引。现在
wait-index把推导值导出,四个安装 job 全部消费它。写死字面量本来要保的两条性质都还在,其中一条变成了结构性的:version not found响亮失败,而不是悄悄测一个旧二进制然后报绿推导在每种触发下都做(cron / 手动同样是「测最新已发布版本」),只有等待保持条件化 —— 只有发布后那一刻索引才可能合理地落后。API 返回空或非数字会被拒绝:
mcpp@空版本会退化成裸mcpp,正好回到这个 job 要防的那件事。顺带
check_version_pins.sh去掉「两处 pin 必须相等」(已无第二处),加上「字面量MCPP_PIN不得回归」的守卫 —— 用探针实测过:退回硬编码会 FAIL,恢复后 OK。补了从未存在的发版文档
docs/09-release.md(含中文版)。这套流程此前只活在 commit message 和 workflow 注释里。内容:两组版本号、管线自动化了什么/没自动化什么、不信任 sha256 边车文件的验证方法、以及索引的 CDN 传播滞后(实测 ~5 分钟,记录上限 ~40 分钟)。并更正了
3b1cb6b—— 它写着「the index no longer serves .1」,让自举 bump 看起来是硬性前置。那个诊断是错的:2026.7.29.1在当前索引下装得上,索引保留全部 105 个已发布版本;真因是本地索引副本陈旧。bump 是一项有用的检查(一轮全绿直接证明新发布能自举),不是前置条件。唯一的硬规则是方向:绝不 pin 一个尚不可安装的版本。验证
check_version_pins.sh通过;退回硬编码时按预期 FAILenv.MCPP_PIN均指向needs.wait-index.outputs.version,needs齐备