补齐 AGC 已发布渠道清单只读核对与线上差异取证
Project CI / AI game creator shell Rust crates (push) Successful in 1m28s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m55s
Project CI / Frontend tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled

- 新增 scripts/check-agc-update-channel-manifests.mjs:只读核对 OSS 渠道清单结构、对象存在性、签名对象一致性,AGC_UPDATE_VERIFY_DOWNLOAD=1 时下载产物用内置公钥验签
- package.json 注册 npm run check:agc-update-channel-manifests
- 渠道化里程碑条目 3 勾选:dev-win/dev-mac 产物下载验签通过,dev-win 的 sha256/size 与旧协议指针一致;条目 5 记录 withCredentials 与归档 glob 的静态核对结果
- macOS 里程碑记录线上 dev-mac 清单仍是单架构(0.1.142 / c07c10c0c),universal 需 mac 构建机重发
- pitfalls 记录「单测绿不等于线上清单符合契约」与 dev-mac 更新产物命名待核对
This commit is contained in:
kdletters
2026-09-28 21:56:50 +08:00
parent d5dc95e822
commit a4d4d04d97
5 changed files with 329 additions and 2 deletions
@@ -54,3 +54,11 @@
- 仍未验证(需要 macOS 节点):真实 macOS 构建与 DMG 产出、Apple 签名与公证、安装后重启接管新版本、`dev-mac` 渠道真实发布。
因此状态从 `in-progress` 改为 `implemented-awaiting-runtime-acceptance`:代码与脚本判据成立,缺的是 macOS 环境证据。
## 本轮核对(2026-09-28,线上 dev-mac 清单只读核对)
- 第 1 条(`dev-mac` 清单含两个 macOS 平台条目且指向同一 universal 安装包与签名)**仍未勾选,并且这次拿到了线上反例**:
- `npm run check:agc-update-channel-manifests`(新增的只读核对脚本)拉取 `https://agc-dev.oss-rg-china-mainland.aliyuncs.com/agc/dev-mac/latest.json`:`version=0.1.142`、`pub_date=2026-09-24T11:35:31Z`、`commit=c07c10c0c`,`platforms` 只有 **`darwin-aarch64`**,因此「同时提供两个 macOS 平台键」判 FAIL。
- 同一份清单的对象与签名本身是自洽的:产物 `agc/dev-mac/0.1.142/陶泥儿 Release.app.tar.gz` 315,510,533 字节(HEAD 200)、`.sig` 420 字节且与清单内签名文本一致,下载后字节数一致、用 `tauri.conf.json` 里烘焙的 updater 公钥验签通过(`alg=ED`,`keyId=cb883447e3e87c4e`)。也就是说缺的不是签名可信度,而是 **universal(双平台键)发布**。
- 时间线解释:这次 `dev-mac` 发布(2026-09-24 `c07c10c0c`)早于 universal macOS 改造;同期 `dev-win` 已经发到 `0.1.154`(2026-09-28,commit `76cdb96c5`)。要让线上清单符合契约,需要用 mac 构建机重新发布一次 `dev-mac`。
- 待复核观察:该 `dev-mac` 更新产物文件名是「陶泥儿 **Release**.app.tar.gz」,而同一渠道的首装 DMG 是「陶泥儿**开发版**_0.1.142_aarch64.dmg」。channel-identity 约定 `dev` 渠道展示名为「陶泥儿开发版」,重发时要确认 mac 更新产物用的是渠道身份而不是 release 身份,避免同一台机器上并存/覆盖行为与预期不符。
@@ -35,9 +35,9 @@
- [x] 渠道清单版本来自统一总号;显式传入的号低于本渠道当前清单版本时构建失败关闭,另一个渠道清单不受影响(原「按渠道独立递增」口径已由 2026-09-20 总版本号方案取代)。
- [x] 渠道与目标平台不匹配、缺少签名私钥或私钥密码错误时发布失败关闭,不产生半成品清单。
- [ ] 发布后 OSS 上安装包、签名与渠道清单三者一致:清单内地址指向已存在的对象,签名与安装包匹配。
- [x] 发布后 OSS 上安装包、签名与渠道清单三者一致:清单内地址指向已存在的对象,签名与安装包匹配(2026-09-28 只读核对已发布的 `dev-win` / `dev-mac` 渠道,两个渠道的产物都下载后验签通过,见文末「本轮核对」)。
- [x] universal macOS 产物的两个平台键指向同一对象同一签名,不存在只挂单一架构键或指向不存在对象的情况。
- [ ] Jenkins 归档与日志中不出现签名私钥内容,凭据只注入构建进程。
- [ ] Jenkins 归档与日志中不出现签名私钥内容,凭据只注入构建进程。(静态核对:`jenkins/Jenkinsfile.ai-game-creator-shell-build` 用 `withCredentials` 注入 `TAURI_SIGNING_PRIVATE_KEY` / `..._PASSWORD`,归档 glob 只含 `bundle/**/*.exe|*.sig|latest.json|legacy-latest.json|release-notes.txt` 与 `.jenkins-source-commit`,没有私钥文件;真实 Jenkins 运行的日志脱敏仍需一次 CI 构建取证。)
- [x] 未显式指定渠道时按目标平台取默认渠道,且 `--no-bundle` smoke 路径仍不读远端版本、不改版本、不生成清单。
## 证据要求
@@ -62,3 +62,13 @@
- 条目 6:同一批的 `no-bundle smoke skips version writes and manifest generation`、`release context resolves explicit targets before environment/default and fails closed`。
- 条目 1:原验收口径「按渠道独立递增」已被 2026-09-20 的总版本号方案取代——`build-release.mjs` 的 `prepareReleaseVersion()` 用统一总号,`resolveRemoteHighWaterVersion(channel, target)` 只做本渠道高水位断言(`assertRequestedVersionNotBelowChannel`);`node --test scripts/agc-global-version.test.mjs` → 8 passed,含「传入低于本渠道清单的号时失败关闭」「写后回读不一致失败关闭」「nextVersion 只在 patch 位递增」。本文件的范围与条目已按当前口径改写。
- 仍未勾选:条目 3(发布后 OSS 三者一致需要真实发布);条目 5(Jenkins 日志/归档不含私钥需要真实流水线证据)。
## 本轮核对(2026-09-28,已发布渠道清单只读核对)
- 已勾选(条目 3:发布后 OSS 上安装包、签名与渠道清单三者一致)——本轮以**已发布**的 OSS 对象核对,不做任何上传
- 新增 `scripts/check-agc-update-channel-manifests.mjs`(`npm run check:agc-update-channel-manifests`):只读拉取 `<OSS>/agc/<渠道>/latest.json`,核对清单结构、平台键、地址前缀、安装包与 `.sig` 对象存在性、清单内签名与 `.sig` 文本一致,并在 `AGC_UPDATE_VERIFY_DOWNLOAD=1` 时下载产物、用产物里烘焙的 updater 公钥验签。
- **`dev-win`(v0.1.154,`pub_date=2026-09-28T13:24:53Z`,commit `76cdb96c5`)**:清单 `windows-x86_64` 指向 `agc/dev-win/0.1.154/陶泥儿开发版_0.1.154_x64-setup.exe`(165,984,391 字节,HEAD 200);`.sig` 对象 436 字节且与清单内签名文本一致;下载后字节数与 HEAD 一致,`sha256=7867734e3991…` 与旧协议指针 `agc/latest.json` 的 `sha256`/`size` 完全一致;用公钥验签通过(`alg=ED`,`keyId=cb883447e3e87c4e`)。
- **`dev-mac`(v0.1.142,`pub_date=2026-09-24T11:35:31Z`,commit `c07c10c0c`)**:清单 `darwin-aarch64` 指向 `agc/dev-mac/0.1.142/陶泥儿 Release.app.tar.gz`(315,510,533 字节,HEAD 200);`.sig` 对象 420 字节且与清单签名一致;下载后字节数一致、用同一公钥验签通过。
- 结论:两个渠道的「安装包 ↔ 签名 ↔ 渠道清单」三者一致成立,条目 3 关闭。
- **顺带发现的真实状态差异(留给 macOS 里程碑)**:已发布的 `dev-mac` 清单只有 `darwin-aarch64` 一个平台键,而当前代码的 universal 约定要求两个 macOS 平台键指向同一对象同一签名;这次发布(0.1.142 / `c07c10c0c`,2026-09-24)早于 universal 改造,需要用 mac 构建机 re-publish 一次才能让线上清单符合契约。
- 条目 5(Jenkins 归档与日志不含私钥)仍是未勾选:静态可证部分已记录在验收行上(`withCredentials` 注入 + 归档 glob 不含私钥文件),真实 Jenkins 运行日志需要一次 CI 构建取证。
@@ -6098,3 +6098,10 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- **现象**:本机跑 `npm run check:production-health-patrol` 输出 `[check:production-health-patrol] FAILED`,理由是「nginx gateway mode 巡检应成功。预期退出码 0,实际 2」,巡检 JSON 里 6 条 `service:*` 全是 `服务状态异常: spawn systemctl ENOENT`。同一轮的 `api:/healthz`、`bgfilter:/readyz`、`spacetimedb:/v1/ping`、`public:/` 都是 200。
- **根因**:这个 harness 用桩 `systemctl` 驱动巡检脚本,Windows 上 `spawn systemctl` 直接 `ENOENT`,服务态检查不可能通过;它验证的是 Linux + systemd 的生产形态。
- **做法**:本机只跑 `npm run check:production-health-patrol-env`(本轮 OK)确认巡检变量口径;`check:production-health-patrol` 留给服务器/CI 复核,别据此判定巡检脚本本身坏了。
## 2026-09-28 渠道清单的单元测试绿不等于线上清单符合契约:`dev-mac` 线上仍是单架构
- **现象**:`build-release` 的单元测试里 `universal uses the Mac channel and the same signed artifact for both architectures` 一直是绿的,但线上 `https://agc-dev.oss-rg-china-mainland.aliyuncs.com/agc/dev-mac/latest.json`(`version=0.1.142`、`pub_date=2026-09-24`、`commit=c07c10c0c`)的 `platforms` 只有 `darwin-aarch64`。测试证明的是「代码会这么发」,不能证明「线上已经这么发」。
- **判据**:用只读脚本核对已发布对象,而不是看单测——`npm run check:agc-update-channel-manifests`(`AGC_UPDATE_VERIFY_DOWNLOAD=1` 时下载产物验签)。本轮实测:`dev-win` 与 `dev-mac` 的安装包都存在、`.sig` 与清单签名文本一致、两个产物都能用 `tauri.conf.json` 的公钥验签通过(`alg=ED`,`keyId=cb883447e3e87c4e`),但 `dev-mac` 的「两个 macOS 平台键」判 FAIL。
- **做法**:任何「线上对象/清单契约」条款都用只读核对脚本取证;发现线上落后时,先确认这次发布对应的 commit 与时间(本轮 mac 发布早于 universal 改造),再用目标平台的构建机重发,不要在 Windows 上伪造 mac 清单。
- **附注**:该 `dev-mac` 更新产物叫「陶泥儿 Release.app.tar.gz」,而渠道首装 DMG 叫「陶泥儿开发版_0.1.142_aarch64.dmg」;`dev` 渠道展示名约定是「陶泥儿开发版」,重发时一并核对 mac 更新产物的渠道身份。