build(release): 加固 v0.1.0 桌面发布链路 (#3)
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

This commit is contained in:
chengchengzhou7
2026-07-17 09:36:16 +08:00
committed by GitHub
parent 1837ceff58
commit 4863ade45b
16 changed files with 895 additions and 323 deletions
@@ -1,8 +1,8 @@
# CTMS Desktop Release Stabilization Checklist
状态: `active`
适用范围: WebmacOS Desktop 统一客户端发布
最后更新: `2026-07-14`
适用范围: WebmacOS Desktop 与 Windows x64 Desktop 统一客户端发布
最后更新: `2026-07-17`
本清单用于第一、二阶段桌面端能力完成后的准发布稳定化。当前允许按 `docs/desktop-local-cache-plan.md` 引入在线辅助本地缓存,但不引入离线登录、离线写入、本地业务权威数据、内嵌后端服务或离线同步。
@@ -30,10 +30,12 @@ npm run desktop:build:app
- [ ] `VITE_BUILD_CHANNEL=release``VITE_BUILD_COMMIT=<release tag commit>` 由 CI 注入,且 `npm run release:env:check` 通过。
- [ ] 在正式 release tag 和签名环境中执行 `npm run desktop:release-readiness:check`,确认 tag、构建元数据、签名/公证变量、updater 私钥和生产 artifact HTTPS 基址齐备。
- [ ] macOS app 已签名和公证。
- [ ] Windows 应用和 NSIS 安装器已使用组织证书签名并带有效 RFC 3161 时间戳,`Get-AuthenticodeSignature` 对应用和安装器均返回 `Valid`
- [ ] updater `.sig` 使用组织 CI secret 或密钥库中的私钥生成,私钥未进入仓库。
- [ ] 设置 `TAURI_SIGNING_PRIVATE_KEY``TAURI_SIGNING_PRIVATE_KEY_PASSWORD` 和 Apple 签名/公证变量后,以 `REQUIRE_DESKTOP_SIGNING=true` 再次执行 `npm run release:env:check`,随后执行 `npm run desktop:build:macos-release -- --ci`
- [ ] 正式 updater feed 先执行 `npm run desktop:update-feed:create -- --artifact <CTMS.app.tar.gz> --base-url <versioned-https-artifact-prefix> --output-dir <release-dir>` 生成 `latest.json``SHA256SUMS.txt`
- [ ] 正式 updater feed 执行 `npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir>`,并确认 checksum manifest、updater artifact、`.sig``latest.json` 均通过校验
- [ ] 设置 Windows PFX、密码、`WINDOWS_TIMESTAMP_URL` 和 updater 私钥后,以 `REQUIRE_WINDOWS_SIGNING=true` 执行 readiness,再执行 `npm run desktop:build:windows-release -- --ci`
- [ ] 正式 updater feed 使用 `--artifact <CTMS.app.tar.gz>``--platform-artifact windows-x86_64=<CTMS.nsis.zip>` 汇总生成同一个 `latest.json``SHA256SUMS.txt`
- [ ] 正式 updater feed 执行 `npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir> --require-platform windows-x86_64`,并确认两个平台的 updater artifact、`.sig`、安装包、checksum manifest 和 `latest.json` 均通过校验。
- [ ] 不可变制品先上传,`latest.json` 最后原子替换;若 feed 校验未通过,不替换线上 `latest.json`
- [ ] Web 与 Desktop 制品记录同一产品版本、Git 标签和完整提交 SHA。
@@ -68,7 +70,7 @@ npm run desktop:build:app
- [ ] updater capability 不直接暴露给 WebView,自动更新只走受控 Tauri command。
- [ ] 更新弹窗 release notes 过滤 URL、token 查询参数和 Authorization/Bearer 形态文本。
- [ ] CI release 候选 workflow 包含 version/runtime/desktop/ui/type/unit/build/desktop app smoke 门禁。
- [ ] signed macOS release candidate workflow 只允许从 `vX.Y.Z` tag 运行,并包含签名环境检查、Universal macOS 构建、update feed 生成、checksum 校验和 verified release directory 上传
- [ ] signed Desktop release candidate workflow 只允许从 `vX.Y.Z` tag 运行macOS 和 Windows 原生 job 分别完成签名验证,再由聚合 job 生成包含 `darwin-aarch64``darwin-x86_64``windows-x86_64` feed、checksum 清单和 verified release directory。
人工复审还必须确认:
@@ -261,3 +263,19 @@ npm run desktop:build:app
真实 `.app` 仍需人工验证:红色按钮真正关闭主窗口后 Dock 重建、菜单顺序、个人中心自身关闭按钮、编辑菜单文本输入行为、自定义快捷键即时同步,以及系统明暗模式切换时的标题栏一致性。
本轮未引入以下条件性 Swift 能力:Quick Look 需先确认附件审阅频率和 Windows 降级语义;Touch ID 会改变现有 30 天会话恢复体验,需先确定凭据访问控制策略;通知点击回跳需先定义固定、无敏感信息的动作和目标页面。三项均不是当前发布前置条件。
## 12. 2026-07-17 Windows 正式发布链路记录
经发布负责人明确批准,Windows x64 NSIS 从内部兼容性验证目标提升为正式桌面发布目标。本轮完成:
- 正式 Desktop candidate workflow 拆分为 macOS 签名/公证、Windows 代码签名和跨平台聚合三个 job;两端都只接受与客户端版本一致的 `vX.Y.Z` tag。
- Windows job 从组织 secret 导入 Base64 PFX,动态配置证书指纹、SHA-256、RFC 3161 时间戳,构建 NSIS installer/updater,并校验应用与安装器的 Authenticode signer 和 timestamp certificate。
- 聚合 job 只在两个原生 job 均通过后生成统一 `latest.json`,同时包含 Universal macOS 的两个平台键和 `windows-x86_64`,并校验所有制品、`.sig` 与 checksum。
- 无签名 `.github/workflows/desktop-windows-internal.yml` 继续保持 branch-only 内部验证语义,不生成正式 updater feed。
- npm 依赖锁文件已升级至当前安全修复版本,生产和完整依赖审计均为 0 个已知漏洞;Axios 新 header 类型通过受控字符串归一化适配并新增单元测试。
创建正式 tag 前仍必须由发布负责人确认:
- GitHub Actions 已配置 updater、Apple 与 Windows 签名 secrets,以及 versioned artifact base URL 和 Windows timestamp URL。
- 组织 Windows 证书允许 PFX 导入 CI;若为硬件或云托管密钥,先将 workflow 切换为经审计的 Tauri `signCommand` provider。
- macOS/Windows 原生 candidate job、联合 feed 校验、真实安装/升级和生产下载源上传全部通过。
+4 -4
View File
@@ -106,8 +106,7 @@ npm run desktop:build:app
npm run desktop:build:app
```
正式桌面发布构建必须设置 updater 签名私钥 Apple 签名/公证变量后,先执行
`npm run desktop:release-readiness:check`,再执行 `npm run desktop:build:macos-release -- --ci`
正式桌面发布构建必须从同一正式 tag 分别在 macOS 和 Windows 原生 CI job 执行。两端都必须设置 updater 签名私钥macOS 设置 Apple 签名/公证变量并以 `REQUIRE_DESKTOP_SIGNING=true` 执行 readiness 与 Universal 构建,Windows 设置 PFX 证书、密码和 RFC 3161 时间戳变量并以 `REQUIRE_WINDOWS_SIGNING=true` 执行 readiness、签名 NSIS 构建和 Authenticode 校验。两个平台通过后才能汇总正式 updater feed。
后端改动应补充执行受影响模块的后端测试、迁移检查和接口回归。
@@ -207,6 +206,7 @@ dev -> main
- 前后端测试通过
- 网页端构建通过
- macOS 桌面端构建通过
- Windows x64 NSIS 兼容性构建通过;正式发布时签名和时间戳验证通过
- 数据库迁移经过验证
- 已知风险和回滚方式已记录
@@ -281,7 +281,7 @@ main -> release
- 回归测试通过
- 数据库迁移和回滚方案确认
- 网页端生产构建通过
- 桌面端生产构建通过
- macOS 与 Windows 桌面端生产构建均从候选 tag 通过
- 发布说明完成
- 生产配置和密钥不在仓库中
- 正式版本号已经统一
@@ -295,7 +295,7 @@ git tag -a v1.2.0 -m "CTMS v1.2.0"
git push origin v1.2.0
```
网页端桌面端必须从同一个 `v1.2.0` 标签构建。不得从不同分支、不同提交或本地未提交状态构建正式制品。
网页端、macOS 和 Windows 桌面端必须从同一个 `v1.2.0` 标签构建。不得从不同分支、不同提交或本地未提交状态构建正式制品。macOS 签名/公证、Windows 代码签名/RFC 3161 时间戳以及两个平台的 updater 签名制品必须全部验证通过后,才能分发安装包并最后原子替换生产 `latest.json`
发布记录至少包含:
+56 -24
View File
@@ -66,8 +66,8 @@ Manual edits that leave these files inconsistent fail CI.
## Stabilization Gates
Client builds require Node.js 22.13.0 or newer. The development frontend container,
Web CI, macOS release candidates, Windows internal validation, and the production
Web image use the same Node 22.13 baseline.
Web CI, macOS and Windows release candidates, Windows internal validation, and the
production Web image use the same Node 22.13 baseline.
Client release candidates must pass the shared Web checks and the Desktop
release/security gate before promotion:
@@ -85,8 +85,9 @@ npm run build
npm run desktop:build:app
```
`release:env:check` verifies build channel and commit metadata, and can be
made strict for signed Desktop builds with `REQUIRE_DESKTOP_SIGNING=true`.
`release:env:check` verifies build channel and commit metadata, and becomes
platform-strict with `REQUIRE_DESKTOP_SIGNING=true` on macOS or
`REQUIRE_WINDOWS_SIGNING=true` on Windows.
`desktop:release:check` statically verifies the Tauri bundle, updater public
key, CSP, capability scopes, command allowlist, query-token ban, generic system
notification boundary, CI gate coverage, and secure session token boundary. The
@@ -96,7 +97,7 @@ full manual release, security, regression, and Desktop UX checklist lives in
## Promotion
1. Merge feature branches into `dev`.
2. Require the shared client/Web and macOS Desktop CI jobs to pass.
2. Require the shared client/Web and macOS/Windows Desktop CI jobs to pass.
3. Promote the accepted scope from `dev` to `main`.
4. Set the release version and complete regression testing on `main`.
5. Promote `main` to `release`.
@@ -130,11 +131,11 @@ for `localhost`, `127.0.0.1`, or `::1`.
The release pipeline must:
1. build from the accepted release tag and commit;
2. build macOS Universal desktop artifacts;
3. sign and notarize the macOS app;
4. produce updater artifacts and `.sig` files with the updater private key;
5. generate `latest.json` and a checksum manifest with `npm run desktop:update-feed:create`;
6. verify the feed with `npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir>`;
2. build the Universal macOS app/DMG and Windows x64 NSIS installer from that tag;
3. sign and notarize macOS, and Authenticode-sign Windows with an RFC 3161 timestamp;
4. produce macOS `.app.tar.gz` and Windows `.nsis.zip` updater artifacts plus their `.sig` files with the shared updater private key;
5. generate one combined `latest.json` and checksum manifest with `npm run desktop:update-feed:create`;
6. verify all macOS and Windows entries with `npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir> --require-platform windows-x86_64`;
7. upload immutable artifacts first;
8. atomically replace `latest.json` last.
@@ -142,6 +143,10 @@ For Universal macOS artifacts, `latest.json` must provide both
`darwin-aarch64` and `darwin-x86_64` entries pointing at the same Universal
update package.
The same feed must also contain `windows-x86_64`, pointing to the signed NSIS
`.nsis.zip` updater package. The Windows `.exe` installer is distributed next
to the updater package but is not used as the updater URL.
The signed release candidate workflow lives at
`.github/workflows/desktop-release-candidate.yml`. It must be run from a
matching `vX.Y.Z` tag and produces a verified release directory as a GitHub
@@ -149,21 +154,30 @@ artifact. That artifact is still only a release candidate; the release owner
must upload immutable files to the production download origin and replace
`latest.json` atomically after validation.
## Windows Build Readiness
## Windows Release and Internal Validation
Second-phase Windows work is limited to CI compatibility validation. A
`windows-latest` x64 NSIS build may be produced for verification, but it is not
a formal deliverable until Windows code signing and release support are
approved.
Windows x64 NSIS is an approved formal Desktop target. Formal Windows builds
run in `.github/workflows/desktop-release-candidate.yml` from the same exact
`vX.Y.Z` tag and SHA as Web and macOS. They must:
Windows validation must cover:
- import a Base64-encoded PFX from `WINDOWS_CERTIFICATE` using
`WINDOWS_CERTIFICATE_PASSWORD`;
- configure the imported certificate thumbprint, SHA-256 digest,
`WINDOWS_TIMESTAMP_URL`, and RFC 3161 timestamp mode dynamically in CI;
- set `REQUIRE_WINDOWS_SIGNING=true` and use the updater signing secrets;
- verify the application and installer with `Get-AuthenticodeSignature`,
including signer and timestamp certificates;
- publish the signed NSIS `.exe`, `.nsis.zip`, and `.nsis.zip.sig` into the
combined verified Desktop release directory.
Windows release validation also covers:
- WebView2 runtime prerequisite behavior;
- user-level installer assumptions;
- Windows Credential Manager session storage;
- path handling and temporary file cleanup;
- notification and updater compilation;
- future code-signing requirements.
- code-signing trust, timestamp validity, and updater signature verification.
The manual internal Windows validation workflow lives at
`.github/workflows/desktop-windows-internal.yml`. It is `workflow_dispatch`
@@ -173,7 +187,24 @@ and Desktop safety gates, builds an unsigned NSIS installer with updater
artifacts disabled, and uploads the `.exe` plus `SHA256SUMS.txt` as a GitHub
Actions artifact. This workflow is for internal compatibility verification
only; it must not generate `latest.json`, update feeds, signed release
directories, or formal Windows release artifacts.
directories, or formal Windows release artifacts. A successful internal build
does not substitute for the signed tag-only release workflow.
The formal workflow requires these organization settings:
- secrets: `TAURI_SIGNING_PRIVATE_KEY`,
`TAURI_SIGNING_PRIVATE_KEY_PASSWORD`, `WINDOWS_CERTIFICATE`, and
`WINDOWS_CERTIFICATE_PASSWORD`;
- variable: `WINDOWS_TIMESTAMP_URL`;
- shared versioned HTTPS artifact prefix: `DESKTOP_UPDATE_BASE_URL` or the
manual workflow input.
The checked-in workflow implements the exportable PFX path. Confirm that the
organization's certificate policy permits an exportable CI certificate before
provisioning it. If the selected CA provides only hardware- or cloud-backed
keys, replace the PFX import with a reviewed Tauri `signCommand` integration
(for example, the organization's Azure signing provider) while retaining the
same Authenticode and timestamp verification gates.
## Required Checks
@@ -197,11 +228,12 @@ export REQUIRE_DESKTOP_SIGNING=true
npm run release:env:check
npm run desktop:release-readiness:check
npm run desktop:build:macos-release -- --ci
npm run desktop:update-feed:create -- --artifact <CTMS.app.tar.gz> --base-url <versioned-https-artifact-prefix> --output-dir <release-dir>
npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir>
npm run desktop:update-feed:create -- --artifact <CTMS.app.tar.gz> --platform-artifact windows-x86_64=<CTMS.nsis.zip> --include <CTMS.dmg> --include <CTMS-installer.exe> --base-url <versioned-https-artifact-prefix> --output-dir <release-dir>
npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir> --require-platform windows-x86_64
```
The Desktop build must run on macOS for the current first-phase target. A signed
or notarized public release additionally requires the Apple credentials defined
by the release owner. A formal second-phase desktop release also requires the
updater signing key; unsigned internal builds are not formal distributions.
The macOS and Windows signed builds run in their native CI jobs. macOS requires
the Apple signing/notarization credentials defined by the release owner;
Windows requires the PFX certificate/password and timestamp URL above. Both use
the same updater signing key and are aggregated only after both native jobs
pass. Unsigned internal builds are not formal distributions.