build(desktop): allow controlled unsigned v0.1.0 release
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled

This commit is contained in:
Cheng Zhou
2026-07-17 10:52:20 +08:00
parent fa26c84bd2
commit c23a5d6a22
16 changed files with 647 additions and 83 deletions
+54 -24
View File
@@ -87,7 +87,11 @@ npm run desktop:build:app
`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.
`REQUIRE_WINDOWS_SIGNING=true` on Windows. Formal native jobs also set
`REQUIRE_UPDATER_SIGNING=true`, `DESKTOP_RELEASE_PLATFORM`, and the
version-derived `DESKTOP_PLATFORM_SIGNING_MODE`. The exact-version policy in
`frontend/desktop-release-policy.json` is checked with
`npm run desktop:release-policy:check`.
`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
@@ -132,10 +136,10 @@ The release pipeline must:
1. build from the accepted release tag and commit;
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;
3. use Apple signing/notarization and Windows Authenticode/RFC 3161 signing by default, or use a checked-in exact-version exception that constrains macOS to ad-hoc signing and Windows to Authenticode-unsigned output;
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`;
5. generate `DESKTOP-RELEASE-PROVENANCE.json`, one combined `latest.json`, and a checksum manifest;
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 --require-provenance`;
7. upload immutable artifacts first;
8. atomically replace `latest.json` last.
@@ -143,22 +147,33 @@ 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 same feed must also contain `windows-x86_64`, pointing to the updater-signed
NSIS `.nsis.zip` package. The Windows `.exe` installer is distributed next to
the updater package but is not used as the updater URL. Tauri updater signing is
mandatory in both platform-signed and platform-signing-exception modes.
The signed release candidate workflow lives at
The formal 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.
Platform signing defaults to `signed`. An exception is allowed only when
`frontend/desktop-release-policy.json` names the exact product version and
records release-owner approval. The current v0.1.0 exception uses macOS ad-hoc
signing and unsigned Windows application/installer binaries. Its artifact names
and release directory contain `UNSIGNED-PLATFORM`; the directory must include
`UNSIGNED-PLATFORM-RELEASE.txt`, `DESKTOP-RELEASE-PROVENANCE.json`, and
`SHA256SUMS.txt`. This does not establish Apple or Microsoft publisher trust,
and Gatekeeper or SmartScreen warnings are expected. Later versions return to
the signed default unless separately approved.
## Windows Release and Internal Validation
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:
`vX.Y.Z` tag and SHA as Web and macOS. The default signed path must:
- import a Base64-encoded PFX from `WINDOWS_CERTIFICATE` using
`WINDOWS_CERTIFICATE_PASSWORD`;
@@ -170,6 +185,12 @@ run in `.github/workflows/desktop-release-candidate.yml` from the same exact
- publish the signed NSIS `.exe`, `.nsis.zip`, and `.nsis.zip.sig` into the
combined verified Desktop release directory.
For an approved exact-version unsigned-platform exception, the Windows job
must instead leave the application and installer Authenticode-unsigned, require
`Get-AuthenticodeSignature` to return `NotSigned`, append `_UNSIGNED` to the
installer and updater artifact names, and still create and verify the updater
`.sig`. A certificate secret and timestamp URL are not required in this mode.
Windows release validation also covers:
- WebView2 runtime prerequisite behavior;
@@ -186,19 +207,23 @@ only, runs on `windows-latest`, injects `VITE_BUILD_CHANNEL` and
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
only; it must not generate `latest.json`, update feeds, verified release
directories, or formal Windows release artifacts. A successful internal build
does not substitute for the signed tag-only release workflow.
does not substitute for the tag-only formal workflow, including when that
formal workflow uses an approved platform-signing exception.
The formal workflow requires these organization settings:
The formal workflow always requires these organization settings:
- secrets: `TAURI_SIGNING_PRIVATE_KEY`,
`TAURI_SIGNING_PRIVATE_KEY_PASSWORD`, `WINDOWS_CERTIFICATE`, and
`WINDOWS_CERTIFICATE_PASSWORD`;
- variable: `WINDOWS_TIMESTAMP_URL`;
- secrets: `TAURI_SIGNING_PRIVATE_KEY` and
`TAURI_SIGNING_PRIVATE_KEY_PASSWORD`;
- shared versioned HTTPS artifact prefix: `DESKTOP_UPDATE_BASE_URL` or the
manual workflow input.
The default signed path additionally requires `WINDOWS_CERTIFICATE`,
`WINDOWS_CERTIFICATE_PASSWORD`, and `WINDOWS_TIMESTAMP_URL`, plus the Apple
credentials documented by the release owner. The v0.1.0 exception does not
require those platform certificate settings.
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
@@ -224,16 +249,21 @@ 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
export REQUIRE_UPDATER_SIGNING=true
export DESKTOP_RELEASE_PLATFORM=macos
export DESKTOP_PLATFORM_SIGNING_MODE=unsigned-exception
export ALLOW_UNSIGNED_PLATFORM_RELEASE=true
npm run release:env:check
npm run desktop:release-readiness:check
npm run desktop:build:macos-release -- --ci
npm run desktop:build:macos-unsigned-release -- --ci
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
npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir> --require-platform windows-x86_64 --require-provenance
```
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.
The macOS and Windows builds run in their native CI jobs and always use the same
updater signing key. In the default path, macOS requires Apple
signing/notarization credentials and Windows requires the PFX/password and
timestamp URL. In the approved v0.1.0 exception, macOS must verify
`Signature=adhoc`, Windows must verify `NotSigned`, and both must carry explicit
platform-trust warnings. Native artifacts are aggregated only after both jobs
and the combined updater feed pass.