ci(release): M164 arm64 判定权交回编译器 + 发布名单守卫(不翻牌)
根因(拿到的真实证据,不是猜的):v0.2.2(run 42322062879 / job 128248713926)与 v0.2.3 (run 42429017002 / job 128573547829)两份 check-run 注解逐字一致 —— 失败步骤是第 6 步 `Windows ARM64 工具链体检`,第 7 步 `cargo build` 状态 skipped。也就是说 v0.2.1~v0.2.3 五轮 全红都红在一个**编译前的启发式探针**上,真正的编译器/链接器一次都没说话。该探针的结论还与它 自己打印的快照矛盾:`SDK Lib 版本→um 架构: 10.0.22621.0→um:[arm,arm64,x64,x86,]` 明明在,却 同时报 `kernel32=缺失`(同一个 `find -path` 模式在本地合成目录树上命中)。runner 实况是 Windows 11 Arm64 + Visual Studio 2026 镜像,`VC.Tools.ARM64` 与 `Windows11SDK.22621/26100` 都装好了,M142 的 `setup.exe modify` 反倒返回非 0。 改: - release-build.yml:探针降级为「只取证」——vswhere 组件查询 + 各目录 `.lib` 计数 + arm64 `link.exe` 候选,一条 `::error::` 都不写、永不 exit 1;不再自动补装 VS。红绿只由 cargo/链接/静态 CRT 导入表门禁决定。cargo build 步给 arm64 显式备齐工具链: `rustup target add aarch64-pc-windows-msvc`、`vcvarsall.bat arm64` 取 `LIB`/`INCLUDE`、 vswhere 定位 arm64 `link.exe` 后导出 `CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER` (顺序不能反:只给链接器不给 LIB ⇒ LNK1181 kernel32.lib)。 - 新增 packaging/check_publish_slots.py(344 行,零依赖):名单 ⇄ 产物**两个方向**。 声明了缺 GUI/CLI ⇒ `::error::` + exit 1;有产物没声明 ⇒ `::warning::` 明说未发布(M142 之后 这个方向是静默的,裁剪步只 echo 一行 drop:)。另有源码级断言(名单每项必须存在且 mode=ci、 运行期名单必须等于文件里那行)与 8 条 `--self-test` 注入回归。 - release-publish.yml:裁剪前插一步跑那个守卫,原来内联的齐全性循环搬进脚本(一套判据一处实现); 重算 SHA256SUMS 的步骤只负责重算。 - release-guard.yml:PR 阶段跑守卫自测 + 源码级断言。 - 文档同步:release.yml / release-publish.yml / release-build.yml 头注释、packaging/README §12、 §1 矩阵、§3 构建与发布、§9 支持矩阵、§7.5 arm64 取证、release-notes.md、README/README.zh-CN 的产物矩阵与说明。口径统一为「arm64 构建取证中、未发布」,不写成已支持。 没做的(按 tower 裁决「方案乙」):`PUBLISH_SLOTS` 本轮**不加回** arm64。arm64 从未产出过 PE、 本机也证不了,写进名单就等于拿 x64 的发布去赌它(M142 移出名单正是为避免这个事故)。下一 tag 的 CI 真出包后翻一行即可,守卫与 SHA256SUMS 自动跟着扩。 验证:workflow YAML 全部可被 PyYAML 解析;所有 `run:` 块过 `bash -n`;探针步在本机(无 VS/SDK) 实跑 exit 0 并打出实况注解;守卫 `--self-test` 8 条全绿、正反两个方向都在合成 dist 上实测过; check_release_semantics.py(含 --self-mutation)/ release_marker / make_manifest 自检全绿; cargo metadata 正常。**arm64 产物从未被构建过、也从未在真机跑过**——本机 `rustc --target aarch64-pc-windows-msvc` 直接撞上没有 MSVC 链接器(git-bash 的 GNU `link` 被当成 link.exe), `cargo check --workspace --target aarch64-pc-windows-msvc` 也死在 aws-lc-sys 的 cc-rs 阶段 (GNU host 上没有该 target 的 C 编译器)。真实结论只能等下一 tag 的 CI。
This commit is contained in:
1 parent
15a19bb375
commit
e858664fca
13 files changed
+577
-120
No files matched your search
@@ -50,17 +50,29 @@ python packaging/make_artifacts.py --slot windows-arm64 \
|
||||
`-C target-feature=+crt-static`、产物都在 `target/release`,标 `mode: ci`(默认编);
|
||||
`ubuntu-22.04`(glibc 2.35 地板)/ `ubuntu-22.04-arm`(原生 ARM64,同地板)/ `macos-latest` /
|
||||
`macos-15-intel` 标 `mode: probe`——**未验证,默认一个都不编**,只有 `all_slots=true` 才进矩阵。
|
||||
- 每个槽位 `cargo build --release --locked`(**不传 `--target`**:每槽原生编译,交叉槽位与 `rustup
|
||||
target add` 一并没了)。arm64 槽位多一步编译前体检:查 VC 的 `lib/arm64/libcmt.lib`(`+crt-static`
|
||||
靠它)与 SDK 的 `um/arm64/kernel32.lib`,缺了就 fail;**注解里固定打 4 行实况**(探测根 / SDK Lib 版本→um
|
||||
架构 / MSVC lib 架构 / 两个关键库)。M142 修的正是「诊断自己先死」:`set -uo pipefail` 关不掉 runner 注入的
|
||||
`-e`,`find` 扫不存在的根被 pipefail 判非零就当场退出 → 现在 `set +e` + 处处 `|| true`,清单先打完再定红绿。
|
||||
- 每个槽位 `cargo build --release --locked`(**不传 `--target`**:每槽原生编译,交叉槽位没了)。arm64 槽位在编译前
|
||||
**把工具链显式备齐**(M164):`rustup target add aarch64-pc-windows-msvc`、用微软自己的 `vcvarsall.bat arm64` 取
|
||||
`LIB`/`INCLUDE`(写进本步环境与 `$GITHUB_ENV`)、用 vswhere 定位 arm64 `link.exe` 后显式导出
|
||||
`CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER`(Hostarm64 原生优先)。顺序不能反:只覆盖链接器而不给 `LIB`,
|
||||
撞上的就是 `LNK1181: cannot open input file 'kernel32.lib'`。
|
||||
- **编译前体检已降级为「只取证」**(M164):M141/M142 的版本用 `find` 猜 `um/arm64/kernel32.lib` 在不在、猜缺就
|
||||
`exit 1` —— v0.2.1~v0.2.3 五轮全红在**那一步**,`cargo build` 一次都没跑过(永远 skipped),而它跟自己打的快照
|
||||
自相矛盾(`um/arm64` 明明在)。现在那一步只打印 vswhere 组件查询、各目录 `.lib` **计数**与 `link.exe` 候选,
|
||||
永不 `exit 1`;**红绿只由编译器 / 链接器 / 静态 CRT 导入表门禁决定**。runner 实况:`windows-11-arm` 自 2026-09
|
||||
是 Windows 11 Arm64 + **Visual Studio 2026** 镜像,`VC.Tools.ARM64` 与 `Windows11SDK.22621/26100` 都已装好。
|
||||
- **发布白名单(`PUBLISH_SLOTS`,唯一开关)**:只有白名单里的槽位进 Release 与 `SHA256SUMS.txt`。**M142 起只有
|
||||
`windows-x64`**:arm64 连试四轮未走通,而齐全性检查是「名单内少一档就 fail」,挂着它就等于 x64 编成功也发不出去;
|
||||
它仍留在矩阵里照跑取证、红了不挡发布。**可逆**:arm64 修好后把键加回 `release.yml` 那一行,再同步 §1/§9 与
|
||||
`release-notes.md`。四档未验证的(默认连构建都不跑)依旧不推给用户。
|
||||
- `release` job:下载全部 artifact → **按白名单裁剪** → 重算 `SHA256SUMS.txt` → 用 `packaging/release-notes.md`
|
||||
模板渲染支持矩阵 → 生成更新清单 `manifest.json` → `gh release create`(**push tag 默认建稳定版**:不带任何标记)。
|
||||
`windows-x64`**:齐全性检查是「名单内少一档就 fail」,挂着没验证过的 arm64 就等于 x64 编成功也发不出去。
|
||||
(M164)arm64 那五轮红其实全红在误判的体检步(上一条),门禁拆掉后「arm64 能不能出 PE」只能由**下一 tag 的 CI**
|
||||
证明,所以名单这轮仍只列 x64 —— 不拿 x64 的发布去赌(tower M164 裁决)。**可逆且只是一行**:那次 CI 真出包后把
|
||||
键加回 `release-publish.yml` 那一行,再同步 §1/§9 与 `release-notes.md`。四档未验证的(默认连构建都不跑)依旧不推给用户。
|
||||
- **名单 ⇄ 产物两个方向都有守卫(M164)**:`packaging/check_publish_slots.py`,同一份代码两处跑 —— PR 阶段
|
||||
(`.github/workflows/release-guard.yml`)断言「名单非空 / 每项都是槽位表里 `mode: ci` 的档」;发布侧
|
||||
(`release-publish.yml` 的 `--dist` 模式,跑在**裁剪前**的全量集上)断言「声明了就得有 GUI 与 CLI 两个产物,
|
||||
缺一个就红」,并把「有产物但名单没声明」打成 `::warning::` 明说未发布 —— M142 之后那个方向是静的(裁剪步只
|
||||
`echo drop:`),一个真编出来的 arm64 会被就地删掉而没人知道。`--self-test` 注入 8 条回归,本地一条命令可跑。
|
||||
- `release` job:下载全部 artifact → **发布名单守卫**(断言 + 未发布提示)→ 按白名单裁剪 → 重算 `SHA256SUMS.txt` →
|
||||
用 `packaging/release-notes.md` 模板渲染支持矩阵 → 生成更新清单 `manifest.json` → `gh release create`
|
||||
(**push tag 默认建稳定版**:不带任何标记)。
|
||||
- **同一 tag 重跑幂等**:`gh release view` 命中已存在的 Release 时改走 `gh release upload --clobber`
|
||||
+ `gh release edit`,覆盖资产与说明而不是再 `create`(`create` 遇已存在会失败,把流水线最后一步染红)。
|
||||
- **预发布标记的语义表(M163,唯一真相源 `packaging/release_marker.py`)**:
|
||||
@@ -87,8 +99,10 @@ python packaging/make_artifacts.py --slot windows-arm64 \
|
||||
`.github/workflows/release-build.yml`(`workflow_call`,四个矩阵键换成同名 `inputs.*`),`release` job 的 6 步
|
||||
逐字搬进 `.github/workflows/release-publish.yml`(同 `workflow_call`,`secrets.GITHUB_TOKEN` 改为调用方显式透传
|
||||
的 secret)。触发(`on`)、`env`、顶层 `permissions`、`concurrency` 与 `plan` 的槽位表在 M145 搬家时**一字未动**;
|
||||
后来只有 M163 动过 `on` 里 `prerelease` 的默认值(`true` → `false`,见上面那张语义表)。改槽位仍只改
|
||||
`release.yml` 那一处(`PUBLISH_SLOTS` 白名单在 `release-publish.yml`,两个 arm64 修复时要改的仍是那两行)。
|
||||
后来只有 M163 动过 `on` 里 `prerelease` 的默认值(`true` → `false`,见上面那张语义表),M164 改过
|
||||
`release-build.yml` 的 arm64 体检步与 `cargo build` 步、并在 `release-publish.yml` 裁剪前插了「发布名单守卫」
|
||||
(于是它现在是 7 步)。改槽位仍只改 `release.yml` 那一处(`PUBLISH_SLOTS` 白名单在 `release-publish.yml`,
|
||||
翻牌时要改的仍是那两处)。
|
||||
- **M149 微软登录 id 的烘焙**:`release-build.yml` 的 `cargo build` 步带 `env.ULL_MSA_CLIENT_ID`(值
|
||||
`${{ secrets.ULL_MSA_CLIENT_ID }}`),`option_env!` 把它烘进二进制,于是发布产物装完即可登录。id **不进
|
||||
git 文件**:真值放仓库 Secret,由 `release.yml` 的 `build` job 按名显式透传(可复用工作流拿不到未显式传入的
|
||||
|
||||
Reference in new issue
Block a user