Development
Deployments
Release workflows, binary assets, desktop notarization, and Homebrew tap automation.
Deployments
Tagged releases run through .github/workflows/ci.yml.
Release checks
Pull requests, pushes to main, and release tags run RustSec audits of both Cargo.lock and desktop/src-tauri/Cargo.lock, plus pnpm audit --audit-level low for the desktop lockfile. The audits include development dependencies and use current advisory data. Rust vulnerabilities and frontend advisories at any severity fail CI; advisory service failures also fail the check. RustSec maintenance and unsoundness warnings remain visible for review, including upstream GTK and font dependencies, and are not silently ignored.
Every release must pass the root formatting, compilation, Clippy, and test checks and the desktop frontend/shell checks on Linux, macOS, and Windows. Run the local equivalents in AGENTS.md, including all three audits, then confirm the final commit’s CI results before tagging. Every release build depends on both audit jobs, so a failed audit prevents publication.
The tag version must match all four package/config versions and have a non-empty docs/releases/<version>.md. GitHub Releases use that file’s first heading as the release title and its contents as the release notes. After publication, check the assets and updater manifest along with the Homebrew, WinGet, and website dispatch jobs.
Release Assets
The release workflow builds and uploads these TUI binaries:
| Platform | Asset |
|---|---|
| Linux AMD64 | tokenuse-linux-amd64 |
| Linux ARM64 | tokenuse-linux-arm64 |
| macOS Intel | tokenuse-darwin-amd64 |
| macOS Apple Silicon | tokenuse-darwin-arm64 |
| Windows AMD64 | tokenuse-windows-amd64.exe |
Each asset has a matching .sha256 checksum file.
Desktop Apps
Tagged releases also build desktop app bundles:
| Platform | Assets |
|---|---|
| macOS ARM64 | tokenuse-desktop-macos-arm64.dmg |
| Windows AMD64 | tokenuse-desktop-windows-amd64-setup.exe, tokenuse-desktop-windows-amd64-setup.exe.sig, tokenuse-desktop-windows-amd64.msi |
| Linux AMD64 | tokenuse-desktop-linux-amd64.AppImage, tokenuse-desktop-linux-amd64.AppImage.sig, tokenuse-desktop-linux-amd64.deb, tokenuse-desktop-linux-amd64.rpm |
| Linux ARM64 | tokenuse-desktop-linux-arm64.AppImage, tokenuse-desktop-linux-arm64.AppImage.sig, tokenuse-desktop-linux-arm64.deb, tokenuse-desktop-linux-arm64.rpm |
Each asset has a matching .sha256 checksum file.
The release also uploads latest.json, the static manifest consumed by the Windows/Linux Tauri updater. The manifest points Windows to the normalized NSIS setup installer and Linux to the normalized AppImage assets. .deb and .rpm packages remain manual GitHub Release installs. The desktop builds tauri-plugin-updater without its default zip feature, so it only installs raw NSIS and AppImage artifacts (createUpdaterArtifacts: true); switching back to v1-compatible zip or tar.gz updater bundles would need that feature, and its zip dependency, again.
The macOS desktop release job builds the Apple Silicon DMG, signs it with a Developer ID Application certificate, notarizes through App Store Connect, verifies the mounted DMG, and uploads the normalized artifact to the GitHub Release. Windows release binaries (the TUI’s tokenuse-windows-amd64.exe, the NSIS and MSI installers, and the app executable and uninstaller inside them) are Authenticode-signed with a Certum code-signing certificate when the CERTUM_* secrets are set; see Windows Code Signing. Linux desktop assets are not OS code-signed and should be verified with their checksum files before installing. The .sig files are Tauri updater signatures, not Authenticode or Linux package signatures.
Required Secrets
The macOS desktop release job requires:
| Secret | Purpose |
|---|---|
APPLE_CERTIFICATE |
Base64-encoded Developer ID Application .p12 certificate |
APPLE_CERTIFICATE_PASSWORD |
Password for the exported certificate |
KEYCHAIN_PASSWORD |
Temporary CI keychain password |
APPLE_API_ISSUER |
App Store Connect issuer ID |
APPLE_API_KEY |
App Store Connect key ID |
APPLE_API_PRIVATE_KEY |
App Store Connect .p8 private key contents |
TAURI_SIGNING_PRIVATE_KEY |
Tauri updater private key content for Windows/Linux update artifacts |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD |
Optional Tauri updater private key password |
HOMEBREW_TAP_TOKEN |
Token with push access to russmckendrick/homebrew-tap |
WINGET_CREATE_GITHUB_TOKEN |
Classic PAT with public_repo and workflow scopes and push access to the russmckendrick/winget-pkgs fork |
The Windows release jobs also read these optional secrets; when all are set they turn on Authenticode signing:
| Secret | Purpose |
|---|---|
CERTUM_USERNAME |
The Certum SimplySign account email |
CERTUM_OTP_URI |
The complete otpauth://totp/... URI behind the SimplySign mobile app’s QR code. As sensitive as the signing key |
CERTUM_CERT_SHA1 |
SHA-1 thumbprint of the Certum code-signing certificate, hex without colons. Not secret |
Use a Developer ID Application certificate for direct-download DMGs. Apple Distribution is for App Store distribution, and Developer ID Installer is for .pkg installers.
Windows Code Signing
The certificate is a Certum Open Source Code Signing certificate held in Certum’s cloud HSM, the same account azdocs signs with. .github/scripts/Connect-SimplySign.ps1 installs a pinned, hash-checked SimplySign Desktop on the runner, logs in with a TOTP code generated from CERTUM_OTP_URI, and waits for the certificate to appear in Cert:\CurrentUser\My; signtool then finds it by thumbprint.
desktop-build-windowsmerges abundle.windowssigning config intotauri build, so Tauri signs the app executable, the NSIS uninstaller,setup.exeand the MSI as it bundles. The updater.sigis generated from the signedsetup.exe. A verify step unpacks both installers and runssigntool verify /paon every executable inside.- The
buildmatrix’s Windows leg signs and verifiestokenuse.exebefore renaming it.
A TOTP code is single-use, so two SimplySign logins must never overlap: the later one reads “invalid user name or token”, and repeated failures lock the account. desktop-build-windows and the manual signing check share the certum-simplysign concurrency group, and the build matrix is ordered after desktop-build-windows (a concurrency group would cancel queued matrix legs). Concurrency groups are per repository, so avoid tagging a tokenuse release while an azdocs release is signing. Do not rerun a failed login repeatedly; check the account in SimplySign first.
To prove the secrets work without a release, run the Windows signing check workflow (.github/workflows/signing-check.yml) by hand. It spends one login and signs a throwaway executable.
Without CERTUM_OTP_URI the Windows jobs build unsigned binaries, say so in the run summary, and SmartScreen warns on first run.
Homebrew Tap
After the GitHub Release is created, .github/workflows/update-tap.yml updates:
Formula/tokenuse.rbfor the TUI on macOS and Linux.Casks/tokenuse-desktop.rbfor the Apple Silicon macOS desktop DMG.
The tap downloads checksums from the newly published release before writing the formula and cask. Linux desktop assets are published only to GitHub Releases for now.
WinGet
After the GitHub Release is created, .github/workflows/update-winget.yml submits the Windows desktop app to WinGet as RussMckendrick.TokenUse. It uses gh repo sync to fast-forward the russmckendrick/winget-pkgs fork from microsoft/winget-pkgs, then runs vedantmgoyal9/winget-releaser to open a manifest pull request against upstream pointing at tokenuse-desktop-windows-amd64.msi. The classic PAT needs both public_repo and workflow because upstream changes can include files under .github/workflows/. The installer regex is pinned to the MSI for two reasons: the raw TUI binary tokenuse-windows-amd64.exe in the same release must never be picked up as an installer, and komac (which winget-releaser runs under the hood) fails to emulate the Tauri NSIS setup installer (it aborts in the WebView2 branch of the installer script), while the MSI yields a clean wix manifest with ProductCode and UpgradeCode metadata.
The action only updates packages that already exist in winget-pkgs; the initial RussMckendrick.TokenUse version was bootstrapped manually with komac new. The workflow can also be re-run for a given tag via workflow_dispatch. WinGet installs the MSI silently and each manifest pins the installer SHA256, so no Authenticode signature is required; signed releases still carry one, which helps SmartScreen reputation. Note the in-app Config-page updater ships the NSIS installer; WinGet users should update via winget upgrade to keep a single Apps & Features entry.
If the automatic fork sync fails, verify the PAT scopes and run gh repo sync russmckendrick/winget-pkgs --source microsoft/winget-pkgs with that token before re-running the workflow. Do not force the sync unless the fork intentionally contains commits that should be discarded.