Contributing
August 24, 2026 ยท View on GitHub
Prerequisites
-
Flox - the dev environment (Rust 1.95 toolchain,
task,bun,infer) is defined in the flox manifest. Install flox, then runflox activatefrom the repo root. -
Linux system dependencies - on Debian/Ubuntu:
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \ libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-devSee the Tauri prerequisites guide for other platforms.
Running locally
flox activate
task install # bun install (first run only)
task dev
task dev rebuilds the React frontend into dist/ before launching Tauri. The frontend is not hot-reloaded - after editing frontend/, re-run task web (or relaunch).
The flox manifest doesn't include cargo or the Tauri CLI yet - add them once from the repo root with flox install cargo cargo-tauri.
Building
cargo tauri build
The bundled app goes to target/release/bundle/. task build runs a plain cargo build (debug); use cargo tauri build for the release bundle.
bundle.createUpdaterArtifacts is on, so cargo tauri build needs the updater signing key in TAURI_SIGNING_PRIVATE_KEY (see below). cargo tauri dev and cargo test do not.
Updater signing keys (maintainers)
Releases are signed with a minisign key pair that is independent of Apple/Windows code signing. It is generated once:
cargo tauri signer generate -w ~/.tauri/desktop.key
Then, in the repository settings:
TAURI_SIGNING_PRIVATE_KEY(secret) - contents of~/.tauri/desktop.key.TAURI_SIGNING_PRIVATE_KEY_PASSWORD(secret) - the password chosen above, if any.TAURI_SIGNING_PUBLIC_KEY(variable) - contents of~/.tauri/desktop.key.pub.
release.yml stamps the public key and the semantic-release version into tauri.conf.json before building, and fails early if either key is missing. Rotating the key means every already-installed app keeps trusting the old one, so a rotation needs a manual re-download.
macOS self-signed code-signing certificate (maintainers)
macOS ties Accessibility and Screen Recording grants (TCC) to the app's code-signing identity. Ad-hoc signing changes identity every build, so grants break on each update. Releases are therefore signed with a long-lived self-signed certificate - created by the project itself, not issued by Apple, no Apple Developer account or fee involved. It gives the app a stable identity that keeps permission grants across updates. (A paid Apple Developer ID certificate with notarization would additionally remove the Gatekeeper first-open warning; the self-signed certificate does not.)
Generated once, in Keychain Access: Certificate Assistant > Create a Certificate, name Inference Gateway Desktop Signing, identity type Self-Signed Root, certificate type Code Signing, validity 3650 days. Export it as a .p12 with a password, then in the repository settings:
APPLE_CERTIFICATE(secret) -base64 -i cert.p12output. The name is Tauri's required env var; despite the name, it holds the self-signed certificate above, nothing from Apple.APPLE_CERTIFICATE_PASSWORD(secret) - the export password.
When these secrets are set, release.yml stamps signingIdentity into tauri.conf.json, adds the self-signed certificate to the runner's trust store (codesign refuses untrusted identities), and imports it into a keychain on the runner. The workflow does the import itself because Tauri's own APPLE_CERTIFICATE handling only recognizes Apple-issued certificates (it matches names like "Developer ID Application:"); with the env vars unset, the bundler signs through the configured signingIdentity instead, which works with any certificate in the keychain. Without the secrets, builds fall back to ad-hoc signing. Rotating the certificate invalidates every user's permission grants once.
Project guide
See AGENTS.md for coding style, commit conventions, PR conventions, git hooks, and agent workflows.