| name | release |
| description | Ship new Qaio version. Bump semver across all packages, tag, push, let CI build + sign + notarize. STOP at draft — user publishes manually. Defaults patch bump. Minor needs explicit user permission. |
/release
Version. Bump. Tag. Push. Done.
Versioning
All packages share ONE version. Every release bumps ALL.
- Semver
0.x.y
- Default: patch bump (
0.3.0 → 0.3.1). Do this always unless told otherwise.
- Minor bump (
0.3.x → 0.4.0) needs explicit user permission. Never bump minor on own. Suggest: "This might warrant 0.4.0 — want minor?" Wait for approval.
- No rush to 1.0. FastAPI was 0.x for years in prod. Same energy.
Standard flow (CI/CD)
./scripts/version.sh 0.3.X
$EDITOR .github/release-notes/0.3.X.md
git add -A && git commit -m "release: v0.3.X"
git tag v0.3.X
git push origin main --tags
GH Actions (.github/workflows/release.yml) takes over:
- Builds
qaio-engine for BOTH aarch64-apple-darwin AND x86_64-apple-darwin
- Builds Tauri app w/
--target universal-apple-darwin (one fat .app)
- Signs w/ Apple Developer ID (
$APPLE_SIGNING_IDENTITY)
- Notarizes
.app w/ Apple
- Creates signed
.dmg
- Verifies engine sidecar is lipo'd fat (arm64 + x86_64 both present)
- Generates
latest.json w/ darwin-aarch64* AND darwin-x86_64* keys
- Creates draft GH Release w/ all artifacts
One DMG covers Apple Silicon + Intel. See knowledge-base/production-infra.md → "macOS Universal".
Duration: ~15-20 min (2-arch compile).
After CI: the release stays as a draft. Stop there. The user reviews the draft and clicks "Publish" themselves. Do NOT run gh release edit --draft=false or otherwise auto-publish — publishing is the user's call, every time.
Full checklist
- Verify:
cargo check --workspace && cd app && pnpm tsc --noEmit
- Commit all changes to
main
- Bump:
./scripts/version.sh 0.3.X (patch default)
- Write notes:
.github/release-notes/0.3.X.md — narrative, not a commit dump. Cover: what changed for the user, before-you-upgrade caveats (always include the macOS drag-install reminder), known limitations. Pattern from .github/release-notes/0.4.0.md. Skip only for trivial hotfixes.
- Commit bump + notes:
git add -A && git commit -m "release: v0.3.X"
- Tag + push:
git tag v0.3.X && git push origin main --tags
- Wait CI: ~10-15 min. Check
github.com/getqaio/qaio/actions
- If CI fails:
gh run view <id> --log-failed, fix, commit. Re-tag = git tag -d v0.3.X && git push origin :refs/tags/v0.3.X, then re-tag + push.
- STOP. Hand off draft to user. The CI-created GH Release is a draft. Tell the user it's ready for review and link it. Do NOT publish it yourself —
gh release edit --draft=false is the user's call. Publishing flips on auto-update for every installed Qaio, so it's never auto-pilot.
- After user publishes: Installed apps show "Update available" w/in 30 min or next launch.
Version bump only (no publish)
./scripts/version.sh 0.2.0
Common CI failures
bundle_dmg.sh failed — flaky CI runner. gh run rerun <id>.
- Missing env var at compile time — new
env!() added. Add secret to GitHub AND workflow YAML.
- Notarization failed — Apple servers slow. Rerun fixes.
- TS errors — run
pnpm tsc --noEmit locally BEFORE tagging.
Env vars required
See knowledge-base/production-infra.md for full table. Short version: APPLE_SIGNING_IDENTITY, APPLE_API_KEY, APPLE_API_KEY_PATH, APPLE_API_ISSUER, TAURI_SIGNING_PRIVATE_KEY, TAURI_SIGNING_PRIVATE_KEY_PASSWORD, POSTHOG_KEY, POSTHOG_HOST, SUPABASE_URL, SUPABASE_ANON_KEY, SENTRY_DSN. CI also APPLE_CERTIFICATE + APPLE_CERTIFICATE_PASSWORD.
Never hardcode. option_env!() in Rust, env vars in CI.
CI broken?
Fallback to manual build → /build-app-local.