Skip to content

ci: derive the fresh-install version instead of hand-editing it, and document releasing - #321

Merged
Sunrisepeak merged 1 commit into
mainfrom
ci/derive-fresh-install-pin
Jul 30, 2026
Merged

ci: derive the fresh-install version instead of hand-editing it, and document releasing#321
Sunrisepeak merged 1 commit into
mainfrom
ci/derive-fresh-install-pin

Conversation

@speak-agent

Copy link
Copy Markdown
Member

起因

「为什么每次发版都要手改 CI 里那个版本号?」——查下来答案是:不必要,而且 workflow 自己早就算出了正确答案,只是把它扔掉了。

MCPP_PIN 从来不是 .xlings.json 的同一样东西

它俩被 check_version_pins.sh 强制相等,但语义不同:

是什么 要求
MCPP_PIN 被测版本 永远是最新的已发布版本
.xlings.json 自举来源 任何能构建当前源码树的已发布 mcpp

把它俩绑在一起,就为一个 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 全部消费它。写死字面量本来要保的两条性质都还在,其中一条变成了结构性的:

  • 显式版本 —— 推导出的字符串和字面量一样显式,所以副本落后的 runner 仍会以 version not found 响亮失败,而不是悄悄测一个旧二进制然后报绿
  • 单一来源 —— 守卫与 job 不可能再对「哪个版本在被测」产生分歧,因为只有一个值

推导在每种触发下都做(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 通过;退回硬编码时按预期 FAIL
  • YAML 解析通过,四个 job 的 env.MCPP_PIN 均指向 needs.wait-index.outputs.versionneeds 齐备
  • 文档里的事实逐条复核:105 个版本条目、隔两版旧版实测可安装、交叉引用可解析

…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.
@Sunrisepeak
Sunrisepeak merged commit 0550fc7 into main Jul 30, 2026
15 checks passed
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.

2 participants