Files
ctms/docs/guides/client-release.md
T
Cheng Zhou ab59476d10
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
feat(桌面与监控): 完善工作台导航和登录活动定位
- 优化桌面标签、上下文标题、前进后退、导航栏隐藏和原生菜单体验

- 补充登录会话 IP 采集、地理位置回退、管理端展示及数据库迁移

- 更新桌面发布检查、运维文档和前后端测试覆盖
2026-07-13 16:03:20 +08:00

204 lines
7.3 KiB
Markdown

# CTMS Web and Desktop Release Guide
## Release Unit
CTMS uses one repository, one promotion path, and one product version. Web and
Desktop are build targets from the same source commit, not separately versioned
products.
The release identity consists of:
- semantic version, for example `1.8.0`
- Git tag, for example `v1.8.0`
- full Git commit SHA
- build channel: `dev`, `main`, or `release`
- client type: `web` or `desktop`
## Runtime Boundary
Shared Vue business code lives under `frontend/src/`. Platform decisions are
exposed through `frontend/src/runtime/index.ts`.
The runtime contract currently provides:
- API base URL resolution
- Web, macOS, Windows, and Linux runtime identification
- app version, source commit, build channel, and client type metadata
- explicit capability flags
- Desktop server address configuration
- secure session storage
- file picker/save/open adapters
- desktop system notification adapters
- desktop updater adapters
- native desktop application menu and shortcut synchronization
- desktop window lifecycle and system appearance synchronization
Business modules must use this public runtime entry point. They must not inspect
Tauri globals or import Tauri packages directly. Native files, notifications,
secure session storage, and automatic updates must remain behind
`frontend/src/runtime/` and explicit capability flags.
Desktop menu accelerators and window appearance are synchronized through narrow
Tauri commands owned by `frontend/src/runtime/`. macOS close/reopen behavior is
handled by the Tauri event loop so a genuinely closed main window can be rebuilt from the Dock;
these concerns must not move into Vue business modules.
## Version Change
Update every client manifest with one command:
```bash
cd frontend
npm run version:set -- 1.8.0
npm run version:check
```
This synchronizes:
- `frontend/package.json`
- `frontend/package-lock.json`
- `frontend/src-tauri/tauri.conf.json`
- `frontend/src-tauri/Cargo.toml`
- `frontend/src-tauri/Cargo.lock`
Manual edits that leave these files inconsistent fail CI.
## Stabilization Gates
Client release candidates must pass the shared Web checks and the Desktop
release/security gate before promotion:
```bash
cd frontend
npm run version:check
npm run release:env:check
npm run runtime:check
npm run desktop:release:check
npm run ui:contract
npm run type-check
npm run test:unit
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`.
`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
full manual release, security, regression, and Desktop UX checklist lives in
`docs/audits/desktop-release-stabilization-checklist.md`.
## Promotion
1. Merge feature branches into `dev`.
2. Require the shared client/Web and macOS 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`.
6. Create the matching `vX.Y.Z` tag on the accepted `release` commit.
7. Build both Web and Desktop artifacts from that exact tag.
Build metadata is injected by CI:
```bash
VITE_BUILD_CHANNEL=release
VITE_BUILD_COMMIT="$(git rev-parse HEAD)"
```
These values support diagnostics but do not replace the semantic version.
## Desktop Updater
Formal Desktop release builds must use Tauri updater signatures. The application
embeds the updater public key in `frontend/src-tauri/tauri.conf.json`; the
private key must live only in the organization key vault or CI secret store.
Runtime update checks derive the feed from the currently configured CTMS origin:
```text
/desktop-updates/stable/latest.json
```
Production update feeds must use HTTPS. Local update testing may use HTTP only
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>`;
7. upload immutable artifacts first;
8. atomically replace `latest.json` last.
For Universal macOS artifacts, `latest.json` must provide both
`darwin-aarch64` and `darwin-x86_64` entries pointing at the same Universal
update package.
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
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
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 validation must cover:
- 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.
The manual internal Windows validation workflow lives at
`.github/workflows/desktop-windows-internal.yml`. It is `workflow_dispatch`
only, runs on `windows-latest`, injects `VITE_BUILD_CHANNEL` and
`VITE_BUILD_COMMIT` from the selected branch context, executes the shared client
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.
## Required Checks
```bash
cd frontend
npm ci
npm run version:check
export VITE_BUILD_CHANNEL=release
export VITE_BUILD_COMMIT="$(git rev-parse HEAD)"
npm run release:env:check
npm run runtime:check
npm run desktop:release:check
npm run ui:contract
npm run type-check
npm run test:unit
npm run build
npm run desktop:build:app
export TAURI_SIGNING_PRIVATE_KEY="$UPDATER_PRIVATE_KEY"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="$UPDATER_PRIVATE_KEY_PASSWORD"
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>
```
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.