npm installnpm run tauri dev
This runs the frontend dev server and Tauri app in developer mode.
Command:
npm run tauri:build:mac
Optional signing and notarization environment variables:
APPLE_SIGNING_IDENTITY(for example:Developer ID Application: Your Name (TEAMID))APPLE_IDAPPLE_PASSWORD(app-specific password)APPLE_TEAM_IDAPPLE_CERTIFICATE(base64-encoded.p12)APPLE_CERTIFICATE_PASSWORD
Notes:
bundle.macOS.signingIdentityis set to"-"in config. IfAPPLE_SIGNING_IDENTITYis not set, the build remains ad-hoc/unsigned for local testing.- If Apple notarization variables are set (
APPLE_ID,APPLE_PASSWORD,APPLE_TEAM_ID), Tauri bundler will attempt notarization automatically. - Do not commit certificates, team IDs, or passwords.
Command:
npm run tauri:build:win
Optional code-signing environment variables:
WINDOWS_CERTIFICATE(base64-encoded.p12)WINDOWS_CERTIFICATE_PASSWORD
Notes:
- If Windows certificate variables are not set, NSIS artifacts are generated unsigned.
TAURI_SIGNING_PRIVATE_KEYandTAURI_SIGNING_PRIVATE_KEY_PASSWORDare for updater signatures, not Windows code signing.
Build outputs are written under:
src-tauri/target/release/bundle/macos/src-tauri/target/release/bundle/dmg/src-tauri/target/release/bundle/nsis/src-tauri/target/release/bundle/msi/
If Gatekeeper rejects the app:
spctl -a -t exec -vv <appname>.app
If notarization fails, inspect notarization logs:
xcrun notarytool log <submission-id> --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_PASSWORD"
Pull request and main branch validation are handled by .github/workflows/ci.yml.
That workflow runs install/build checks plus Rust formatting, clippy, and tests on Ubuntu.
It intentionally does not run full Tauri packaging (tauri build) to keep PR CI fast and lower-cost.
Release packaging/signing is handled by .github/workflows/release.yml.
To cut a release, create and push a SemVer tag:
git tag v0.4.0 && git push --tags
This triggers the release workflow for macOS (Apple Silicon + Intel) and Windows.
You can also run it manually from GitHub Actions using workflow_dispatch.
Required repository secrets (GitHub: Settings -> Secrets and variables -> Actions):
APPLE_SIGNING_IDENTITYAPPLE_IDAPPLE_PASSWORDAPPLE_TEAM_IDAPPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORDWINDOWS_CERTIFICATEWINDOWS_CERTIFICATE_PASSWORDTAURI_SIGNING_PRIVATE_KEYTAURI_SIGNING_PRIVATE_KEY_PASSWORD
Notes:
- macOS cert import uses
APPLE_CERTIFICATEandAPPLE_CERTIFICATE_PASSWORDwhen present. - Tauri updater signature files (
*.sig) are only generated whenTAURI_SIGNING_PRIVATE_KEYis set. - Unsigned development release artifacts are still produced if you leave all signing/notarization secrets unset.
- Never commit signing certificates, private keys, or credential values into the repository.
Generate an updater signing keypair (Tauri v2 CLI):
npx tauri signer generate -w ~/.tauri/otm-updater.key
This writes a private key (~/.tauri/otm-updater.key) and public key (~/.tauri/otm-updater.key.pub).
In src-tauri/tauri.conf.json, under plugins.updater: replace "PUBKEY_PLACEHOLDER" with the contents of the public key file, and set "active": true. The updater ships with "active": false on purpose — a placeholder public key can never verify an update signature, so the feature stays disabled until a real keypair is wired up.
Set GitHub Actions secrets for release signing:
TAURI_SIGNING_PRIVATE_KEY= contents of~/.tauri/otm-updater.keyTAURI_SIGNING_PRIVATE_KEY_PASSWORD= key password (if one was set)
Never commit the private key file or private key contents into this repository.
TODO: latest.json at releases/latest/download/latest.json must be authored manually or generated by a follow-up CI step; that manifest generation is out of scope for this PR.