feat(client): Tauri updater for the Linux Flatpak #228

Open
opened 2026-06-21 18:23:10 +00:00 by james · 0 comments
Owner

Context

#188 (PR #222) ships the Linux Flatpak via a Tauri 2 shell wrapping the Expo Web bundle. Tauri 2 has a built-in updater plugin (tauri-plugin-updater) that can fetch and apply signed updates from a manifest URL — currently unwired.

Without it, a self-hoster's Carol Flatpak install stays on whatever version they flatpak install'd. They'd need to manually pull a new .flatpak from each Forgejo release. Tauri's updater closes that loop: check the Forgejo release feed on launch, prompt to install on next quit / restart.

Out of scope on #188's first cut because the updater needs signing keys + a release-manifest endpoint, and the value's deferrable.

Source

Follow-up flagged in #222.

Scope

  • Add tauri-plugin-updater to apps/client/src-tauri/Cargo.toml and wire it in src-tauri/src/main.rs (or wherever the Tauri app builder lives).
  • Generate signing keys via cargo tauri signer generate and store the private key in CI secrets (TAURI_UPDATER_PRIVATE_KEY, TAURI_UPDATER_KEY_PASSWORD). Public key lives in tauri.conf.json under plugins.updater.pubkey and ships with every release.
  • Extend release-flatpak.yml to sign the built artifact and produce a latest.json Tauri manifest with the version, signature, and download URL. Attach latest.json alongside the .flatpak on the Forgejo release.
  • Add a small in-app UX: on launch (or on demand from the Account screen) check for an update via the Tauri plugin; if available, surface a non-blocking toast — "A new version of Carol is ready. Restart to update?" — with a Restart action that calls the plugin's install + restart helpers.
  • Document the key-rotation flow in docs/ci.md or a follow-up section to ADR-0014.

Acceptance criteria

  • An installed Flatpak built from tag vX.Y.Z detects a newer tag vX.Y.Z+1 released after install.
  • Accepting the update prompt downloads + verifies the new artifact and prompts the user to restart.
  • CI secrets are documented; without them the release workflow falls through to an unsigned artifact (no latest.json) so the API release pipeline still succeeds.
  • Loss of the signing key means installed Flatpaks can no longer auto-update — runbook in docs/ci.md covers what to do (cut a latest.json from a fresh keypair, ship a Forgejo release note pinning users to a one-time manual upgrade).

Out of scope

  • Background download / install while Carol is running.
  • Per-channel feeds (stable vs. beta) — single channel for now.
  • Auto-updating the Android APK / AAB — they install via package manager (or sideload), Tauri updater doesn't apply.

Composes with

  • #188 — Linux Flatpak.
  • #220 — Android keystore rotation runbook (similar key-rotation muscle).
  • ADR-0014 — release pipeline.

Part of

#176

## Context [#188](https://forge.wynning.tech/james/carol/issues/188) (PR [#222](https://forge.wynning.tech/james/carol/pulls/222)) ships the Linux Flatpak via a Tauri 2 shell wrapping the Expo Web bundle. Tauri 2 has a built-in updater plugin (`tauri-plugin-updater`) that can fetch and apply signed updates from a manifest URL — currently unwired. Without it, a self-hoster's Carol Flatpak install stays on whatever version they `flatpak install`'d. They'd need to manually pull a new `.flatpak` from each Forgejo release. Tauri's updater closes that loop: check the Forgejo release feed on launch, prompt to install on next quit / restart. Out of scope on #188's first cut because the updater needs signing keys + a release-manifest endpoint, and the value's deferrable. ## Source Follow-up flagged in [#222](https://forge.wynning.tech/james/carol/pulls/222). ## Scope - Add `tauri-plugin-updater` to `apps/client/src-tauri/Cargo.toml` and wire it in `src-tauri/src/main.rs` (or wherever the Tauri app builder lives). - Generate signing keys via `cargo tauri signer generate` and store the **private key in CI secrets** (`TAURI_UPDATER_PRIVATE_KEY`, `TAURI_UPDATER_KEY_PASSWORD`). Public key lives in `tauri.conf.json` under `plugins.updater.pubkey` and ships with every release. - Extend `release-flatpak.yml` to sign the built artifact and produce a `latest.json` Tauri manifest with the version, signature, and download URL. Attach `latest.json` alongside the `.flatpak` on the Forgejo release. - Add a small in-app UX: on launch (or on demand from the Account screen) check for an update via the Tauri plugin; if available, surface a non-blocking toast — "A new version of Carol is ready. Restart to update?" — with a Restart action that calls the plugin's install + restart helpers. - Document the key-rotation flow in `docs/ci.md` or a follow-up section to [ADR-0014](docs/adr/0014-release-pipeline.md). ## Acceptance criteria - [ ] An installed Flatpak built from tag `vX.Y.Z` detects a newer tag `vX.Y.Z+1` released after install. - [ ] Accepting the update prompt downloads + verifies the new artifact and prompts the user to restart. - [ ] CI secrets are documented; without them the release workflow falls through to an unsigned artifact (no `latest.json`) so the API release pipeline still succeeds. - [ ] Loss of the signing key means installed Flatpaks can no longer auto-update — runbook in `docs/ci.md` covers what to do (cut a `latest.json` from a fresh keypair, ship a Forgejo release note pinning users to a one-time manual upgrade). ## Out of scope - Background download / install while Carol is running. - Per-channel feeds (stable vs. beta) — single channel for now. - Auto-updating the Android APK / AAB — they install via package manager (or sideload), Tauri updater doesn't apply. ## Composes with - [#188](https://forge.wynning.tech/james/carol/issues/188) — Linux Flatpak. - [#220](https://forge.wynning.tech/james/carol/issues/220) — Android keystore rotation runbook (similar key-rotation muscle). - [ADR-0014](docs/adr/0014-release-pipeline.md) — release pipeline. ## Part of [#176](https://forge.wynning.tech/james/carol/issues/176)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#228
No description provided.