Skip to content

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.

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.

Terminal window
git tag v0.6.0
git push origin v0.6.0

The 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.

  1. 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.

  2. 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 externalBin binaries itself, and an unsigned binary inside the bundle would fail notarization). Windows installers are Authenticode- signed once the signing configuration is present.

  3. 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.

  4. 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 → published

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.

A completed release attaches one bundle set per platform:

PlatformArtifacts
macOS (arm64).dmg, .app.tar.gz (+ updater signature)
macOS (x64).dmg, .app.tar.gz (+ updater signature)
Linux.AppImage, .deb, .rpm (+ updater signatures)
WindowsNSIS -setup.exe, .msi (+ updater signatures)

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.