Releasing
How a version gets from a git tag to users, and the one-time setup it needs.
How it works
- Push a tag
vX.Y.Z. The Release workflow builds the MSI and the setup.exe, signs them for the updater, writeslatest.json, and attaches everything to a draft release. - Review the draft on GitHub and publish it. Nothing reaches users before this step.
- Publishing runs the Website workflow. It rebuilds the site with the new download links
and copies the release's
latest.jsontohttps://keeprun.app/latest.json. - Desktop apps find the update on their next check (within 6 hours, or at the next start).
To stop a rollout, delete the release or mark it as a pre-release, then run the Website workflow by hand. The site falls back to the previous published release.
Version number
The version lives in one place: version under [workspace.package] in the root Cargo.toml.
The agent, the CLI and the desktop app all read it. Bump it, commit, then tag:
git tag v0.2.0
git push origin v0.2.0
The tag must match the version, or the manifest points at files that do not exist.
One-time setup
Update signing key
The desktop app only installs updates signed with the key whose public half is in
apps/desktop/src-tauri/tauri.conf.json (plugins.updater.pubkey). This is separate from
Windows code signing and costs nothing.
The private key is at %USERPROFILE%\.tauri\keeprun-updater.key on the machine where it was
generated. Add it to the repository secrets:
| Secret | Value |
|---|---|
TAURI_SIGNING_PRIVATE_KEY |
Contents of the key file |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD |
Empty, unless you generated a key with a password |
Keep a backup in your password manager. If the key is lost, installed copies cannot verify any new version, and every user has to install the next version by hand. To rotate the key, ship one release signed with the old key that contains the new public key.
Local builds sign too when the variable is set:
$env:TAURI_SIGNING_PRIVATE_KEY = "$env:USERPROFILE\.tauri\keeprun-updater.key"
npm run build
Code signing (optional, recommended)
Unsigned installers trigger SmartScreen warnings. Set KEEPRUN_SIGN_COMMAND (and the Azure
secrets for Trusted Signing) as described in deployment.md.
Website and domain
- In the repository, open Settings > Pages and set Source to GitHub Actions.
- Under Custom domain, enter
keeprun.appand save. Turn on Enforce HTTPS once the certificate is issued. - At the DNS provider, point the apex domain at GitHub Pages:
Arecords:185.199.108.153,185.199.109.153,185.199.110.153,185.199.111.153AAAArecords:2606:50c0:8000::153,2606:50c0:8001::153,2606:50c0:8002::153,2606:50c0:8003::153- Optional
CNAMEforwww:<owner>.github.io
- Verify the domain for your account or organization under Settings > Pages > Verified domains, so no other repository can claim it.
- Run the Website workflow once by hand.
The site is built from site/ (landing page) and docs/ (rendered to /docs/*.html). Build it
locally with:
npm install --no-save marked@15
node scripts/build-site.mjs # output in _site/
Using another domain
The domain appears in three places. Change all of them:
apps/desktop/src-tauri/tauri.conf.json:plugins.updater.endpointsdocs/deployment.mdand this file- The custom domain in Settings > Pages
Installed copies keep checking the old URL until they update, so keep the old domain serving
latest.json for a while after a change.