Releasing
Trove ships through GitHub Releases plus an auto-update channel. The whole pipeline is tag-driven: cut a tag, and CI does the rest.
The trigger
Section titled “The trigger”Pushing a tag of the form v* (for example v0.6.0) triggers the release
workflow. There is nothing else to run by hand for a normal release.
git tag v0.6.0git push origin v0.6.0The committed version numbers in tauri.conf.json and Cargo.toml are just
the dev baseline — the release version is stamped from the tag in CI, so
the binary’s version always matches the tag it was built from.
What CI does
Section titled “What CI does”-
Build every platform in parallel. The workflow builds the Tauri app on four legs — macOS arm64, macOS x64, Linux x64, and Windows x64 — and uploads the bundles to a draft release.
-
Sign during the build. macOS bundles are Developer ID-signed, and the Go collector sidecar is codesigned before the Tauri build (Tauri doesn’t sign
externalBinbinaries itself, and an unsigned binary inside the bundle would fail notarization). Windows installers are Authenticode- signed once the signing configuration is present. -
Notarize macOS out of band. Notarization is decoupled from the build so the expensive macOS runners never sit waiting on Apple’s queue. The build submits the bundle and exits; a lightweight poll waits for Apple to accept it.
-
Finalize once accepted. When notarization is Accepted, a reusable finalize workflow staples the macOS artifacts, assembles the updater manifest covering every platform, publishes it to the update channel, and promotes the draft release to published.
git tag v0.6.0 ──▶ release.yml ├─ build-tauri (×4 legs, parallel) │ ├─ stamp version from the tag │ ├─ build sidecar → codesign it (macOS) │ ├─ build + sign the app (no notarize yet) │ └─ submit for notarization, then exit ├─ notarize-wait (Accepted → finalize now) └─ finalize (reusable) ├─ staple the macOS artifacts ├─ attach the merged latest.json to the release └─ promote the draft → publishedThe auto-updater channel
Section titled “The auto-updater channel”The GitHub release is the update channel. Trove polls
releases/latest/download/latest.json,
a platform-keyed manifest attached to each release whose download URLs point
back at that same release’s assets — so the endpoint the app checks and the
place CI publishes to are the same thing by construction, with nothing to keep
in sync.
Because releases/latest only ever resolves to a published, non-prerelease
release, the draft is promoted last — after the manifest is attached — so
an in-flight release is never visible to the updater.
Each artifact is signed for the updater, and the manifest assembly fails loudly if any expected artifact or signature file is missing, so a partial release can’t be promoted.
Release artifacts
Section titled “Release artifacts”A completed release attaches one bundle set per platform:
| Platform | Artifacts |
|---|---|
| macOS (arm64) | .dmg, .app.tar.gz (+ updater signature) |
| macOS (x64) | .dmg, .app.tar.gz (+ updater signature) |
| Linux | .AppImage, .deb, .rpm (+ updater signatures) |
| Windows | NSIS -setup.exe, .msi (+ updater signatures) |
Verifying a release
Section titled “Verifying a release”After a release publishes, a short verification pass confirms the artifacts are trustworthy:
- macOS — Gatekeeper assessment (
spctl --assess) reports a notarized Developer ID, and the notarization ticket is stapled (xcrun stapler validate, which works offline). - Windows — the downloaded installer’s digital signature chain validates.
- Auto-updater — installing the previous release and checking for updates in-app offers the new version and installs it on restart; on the latest version the app reports it’s up to date.