| name | release |
| description | Bump version, build, and release Noah for the current platform. Handles signing keys, version bumps across all config files, testing, committing, pushing, and uploading to GitHub Releases. |
| user-invocable | true |
Release Noah
Cut a release: Mac locally (universal binary), Windows + Linux via GitHub Actions.
Pre-flight
- Run
cargo test — abort if any fail.
- Check
git status — warn if there are uncommitted changes unrelated to the release.
- Lockfile check: Verify
pnpm-lock.yaml and Cargo.lock are committed and in sync with their respective manifest files. If either is modified/untracked, commit them first. Out-of-sync lockfiles cause --frozen-lockfile failures.
Version bump
The version lives in three files that must stay in sync:
apps/desktop/src-tauri/Cargo.toml (version = "X.Y.Z")
apps/desktop/src-tauri/tauri.conf.json ("version": "X.Y.Z")
apps/desktop/package.json ("version": "X.Y.Z")
After editing Cargo.toml, run cargo check to update Cargo.lock, then stage it too.
Determine the bump type from context:
- Patch (0.9.2 -> 0.9.3): bug fixes, minor tweaks
- Minor (0.9.2 -> 0.10.0): new features, notable changes
- Major (0.9.2 -> 1.0.0): breaking changes, major milestones
If the user specifies a bump type or target version, use that. Otherwise ask.
Update all three files + Cargo.lock, then commit:
Bump version to X.Y.Z
<one-line summary of what changed since last release>
Push the commit before building (CI needs the latest code).
Build and upload (Mac — local)
Two key families are required:
- Tauri updater key (
TAURI_SIGNING_PRIVATE_KEY) — signs the updater manifest so existing installs can auto-update
- Apple Developer ID (
APPLE_*) — code-signs and notarizes the .dmg/.app so Gatekeeper accepts it on first launch
export TAURI_SIGNING_PRIVATE_KEY="$(cat ~/.tauri/noah.key)"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="searchformeaning"
export APPLE_SIGNING_IDENTITY="Developer ID Application: You Xu (2VGY8SHNYJ)"
export APPLE_ID="xu.leaps@gmail.com"
export APPLE_PASSWORD="<app-specific password from appleid.apple.com>"
export APPLE_TEAM_ID="2VGY8SHNYJ"
node scripts/release.mjs --upload --skip-install
The APPLE_* vars are typically already set in the shell (.zshenv). If you see ==> APPLE_SIGNING_IDENTITY not set or ==> APPLE_ID/APPLE_PASSWORD/APPLE_TEAM_ID not set in the script's output, the build will succeed but the resulting .dmg will be unsigned — abort and export the missing vars before re-running, otherwise users hit Gatekeeper warnings.
This builds a universal macOS binary (ARM + Intel via --target universal-apple-darwin), signs with the Apple Developer ID, submits to Apple for notarization, staples the ticket, and uploads the .dmg + .tar.gz (with updater signature) to GitHub Releases. The latest.json registers both darwin-aarch64 and darwin-x86_64 for the updater.
The release script automatically:
- Installs
x86_64-apple-darwin Rust target if missing
- Cleans stale bundle artifacts before building
- Output goes to
target/universal-apple-darwin/release/bundle/
Build and upload (Windows + Linux — GitHub Actions)
After the Mac build uploads and creates the release, trigger CI for Windows and Linux:
gh workflow run release.yml --field tag=vX.Y.Z
This runs .github/workflows/release.yml which builds on both windows-latest and ubuntu-22.04 in parallel, then uploads artifacts (NSIS .exe, MSI .msi, deb, rpm, AppImage) to the same GitHub release.
Monitor progress:
gh run list --workflow=release.yml --limit 1
gh run watch
Signing secrets (TAURI_SIGNING_PRIVATE_KEY, TAURI_SIGNING_PRIVATE_KEY_PASSWORD) are configured as GitHub repo secrets — no manual setup needed per build.
Fallback: manual Windows build
If CI is broken, Windows can still be built manually on the Windows machine:
- SSH to Windows:
ssh xulea@100.87.199.115
- Run:
cd C:\Users\xulea\src\itman && git pull && node scripts/release.mjs --build
(Ensure signing key is at ~/.tauri/noah.key and PATH includes cargo, node, pnpm)
- SCP both NSIS (.exe) and MSI (.msi) artifacts back
- Upload with
gh release upload vX.Y.Z /tmp/Noah_*.exe /tmp/Noah_*.msi --clobber
Post-release
- Push all commits:
git push
- Print the release URL for the user.
- Optionally monitor CI:
gh run list --workflow=release.yml --limit 1
CI Notes
- macOS builds are local only — macOS CI runners cost 10x (would eat free tier fast).
- Windows + Linux via GitHub Actions —
release.yml is workflow_dispatch only (manual trigger). Free tier: 2,000 min/month; a typical release uses ~30 min (10 min Windows ×2 + 10 min Linux ×1).
ci.yml is also workflow_dispatch only (test-only, no builds).
- The
--skip-install flag skips pnpm install in the release script (saves time when deps haven't changed). Omit it if dependencies were recently added.