The TAMIAS desktop app self-updates. On launch (and every 6 hours after) it checks https://github.com/ArioMoniri/semikap/releases/latest/download/latest.json. When a newer signed bundle is published, the in-app toast offers a one-click "Install update" that downloads, verifies, and relaunches.
This is the same pattern Sparkle popularised on macOS, implemented via Tauri's official updater plugin so it works identically on macOS, Windows, and Linux.
flowchart LR
App[π₯οΈ installed app<br/>Tauri WebView] -- /releases/latest/<br/>download/latest.json --> Releases[π¦ GitHub Releases]
Releases -- TAMIAS_x64.dmg.sig<br/>TAMIAS_x64.msi.sig<br/>tamias_amd64.AppImage.sig<br/>latest.json (signed) --> App
App -- verify Ed25519 sig<br/>install + relaunch --> Done[β
on the new version]
Tag[git push --tags<br/>v0.3.0] --> Action[π€ tauri-release.yml]
Action -- build + sign + publish --> Releases
If you've only ever interacted with the repo through the GitHub web UI and have nothing on disk yet, this is the full sequence. Run every command in your local terminal, not in the browser.
| Tool | Why | macOS install | Windows install | Linux install |
|---|---|---|---|---|
| Git | clone the repo | brew install git |
git-scm.com | sudo apt install git |
| Node 20+ | run scripts, build app | brew install node@20 |
nodejs.org LTS | nvm install 20 |
| gh (optional) | CLI for adding GitHub secrets | brew install gh |
winget install GitHub.cli |
sudo apt install gh |
Verify:
git --version # 2.x
node --version # v20.x or newer
npm --version # 10.xPick a directory you want the code to live in (e.g. ~/code):
mkdir -p ~/code && cd ~/code
git clone https://github.com/ArioMoniri/semikap.git
cd semikapYou should now see the project files (package.json, src/, docs/, etc.) when you run ls.
npm ci(Takes a minute or two on first run.)
node scripts/init-updater.mjsThe script will:
- Prompt you for a password (use a strong one, store it in a password manager).
- Write
tauri-signing.keyto the current directory (this is.gitignore-d β it must NEVER be committed). - Patch
src-tauri/tauri.conf.jsonwith the matching public key. - Print the two GitHub secret names you'll add in the next step.
You need to add the secrets the workflow uses to sign each release. Two options:
Option A β via the web UI (no extra CLI needed):
- Open
https://github.com/ArioMoniri/semikap/settings/secrets/actionsin your browser. - Click New repository secret.
- Name:
TAURI_SIGNING_PRIVATE_KEY. Value: paste the entire contents oftauri-signing.key(open it in a text editor, copy everything). - Click Add secret.
- Click New repository secret again. Name:
TAURI_SIGNING_PRIVATE_KEY_PASSWORD. Value: the password you set in Step 3. - Click Add secret.
Option B β via gh CLI (faster):
gh auth login # if not already
gh secret set TAURI_SIGNING_PRIVATE_KEY < tauri-signing.key
gh secret set TAURI_SIGNING_PRIVATE_KEY_PASSWORD # paste password when promptedThe public key was written into src-tauri/tauri.conf.json in Step 3 β that's safe to commit.
git add src-tauri/tauri.conf.json
git commit -m "chore: embed updater public key"
git pushmv tauri-signing.key ~/.tamias-signing.key # or anywhere outside the repoYou don't need it on disk anymore for normal releases β CI uses the GitHub secret. Keep a backup in a password manager / vault in case you ever need to re-publish a release manually.
node scripts/release.mjs minor # bumps 0.2.0 β 0.3.0, commits, tags v0.3.0, pushesWatch the Actions tab on GitHub: https://github.com/ArioMoniri/semikap/actions. You'll see two workflows kick off:
- CI β typecheck / lint / build (fast, ~2 min)
- Desktop release β builds + signs installers for macOS / Windows / Linux (~20β40 min)
When the Desktop release workflow finishes, a draft release appears at https://github.com/ArioMoniri/semikap/releases. Open it, edit the description if you like, and click Publish release.
That's it. The download buttons in the README now serve real installers, and every existing desktop install will pick the update up within 6 hours.
Just one command, from the repo root:
node scripts/release.mjs patch # 0.3.0 β 0.3.1
# or:
node scripts/release.mjs minor # 0.3.0 β 0.4.0
# or:
node scripts/release.mjs major # 0.3.0 β 1.0.0Then promote the resulting draft release in the GitHub UI.
node scripts/init-updater.mjsThis generates an Ed25519 keypair via Tauri's official signer generate, writes the public key into src-tauri/tauri.conf.json (commit it β public keys are safe to publish), and leaves the private key in tauri-signing.key (which is .gitignore-d).
Then add two GitHub Actions secrets to the repo:
| Secret | Value |
|---|---|
TAURI_SIGNING_PRIVATE_KEY |
Contents of tauri-signing.key |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD |
The password you set during generation |
Commit the public-key change and push. Done.
node scripts/release.mjs minor # 0.2.0 β 0.3.0; commits, tags v0.3.0, pushes
node scripts/release.mjs patch # 0.2.0 β 0.2.1
node scripts/release.mjs 1.0.0 # explicit versionThe script:
- Refuses to run if the working tree is dirty or if you're not on
main(override with--any-branch). - Bumps the semver in
package.json,src-tauri/Cargo.toml,src-tauri/tauri.conf.json. - Commits
chore(release): vX.Y.Z. - Tags
vX.Y.Z. - Pushes (override with
--no-push).
The tag push triggers tauri-release.yml, which:
- Builds installers for macOS-arm64, macOS-x64, Linux-x64, Windows-x64.
- Signs each bundle with the private key from the GitHub secret.
- Publishes a draft GitHub Release with the installers +
latest.json(the updater manifest).
Promote the draft to "Latest" in the GitHub UI when you're ready and every existing install picks the update up automatically the next time it launches (or within 6 hours).
Re-run node scripts/init-updater.mjs after deleting tauri-signing.key. Existing installs trust only the old public key, so rotating means existing users must do a manual re-install once. Avoid rotating unless the private key has been compromised.
- The private key never leaves CI; it's mounted into the action only at sign time.
- Each installer includes a sidecar
*.sigfile; the in-app updater rejects any download whose signature doesn't verify against the embedded public key. - The updater itself only follows the GitHub Releases URL configured in
src-tauri/tauri.conf.json. Change the endpoint there if you want to host the manifest somewhere else (your own server, S3, etc.). - Update checks are HTTPS-only.
The in-browser PWA uses the standard service-worker update mechanism (no signing β the source is the host you deployed on). When a new build is detected, the same toast offers a one-click reload. Background update polling: 60 minutes.