| name | release-kata-agents |
| description | Runbook for releasing Kata Agents desktop builds to GitHub Releases. Use this skill whenever the user asks to release, ship, publish, cut a release, run a release workflow, do a nightly, do a nightly dry run, do a stable release, or anything about releasing or publishing Kata Agents. Covers the full sequence: Nightly Dry Run → Nightly Release → Stable Dry Run → Stable Release. Dispatches the release.yml workflow, polls for status, verifies results at each stage, and knows exactly what a passing run looks like vs. a real failure.
|
Release Runbook — Kata Agents
Overview
Releases are published to https://github.com/gannonh/kata-agents/releases via
.github/workflows/release.yml. The workflow has three triggers:
schedule — automatic nightly every 3 hours; only proceeds when main has
changed since the last nightly tag (see check_changes job); no input needed
workflow_dispatch — manual dispatch with channel (stable|nightly),
version (required for stable, ignored for nightly), and dry_run (true|false)
- Tag push — pushing a
v*.*.* tag (excluding v*-nightly.*) triggers a
stable release automatically
Recommended order for a new release cycle:
- Nightly Dry Run
- Nightly Release
- Stable Dry Run
- Stable Release
You do not have to run all four. A dry-run failure is expected to be fixed before proceeding.
Stable release notes (required, not automated)
The in-app What's New overlay reads versioned files at
apps/electron/resources/release-notes/<version>.md. PRs accumulate pending
bullets in next.md. Stable dispatches are not auto-generated from
next.md — the release_meta job fails fast if <version>.md is missing:
Stable release is missing release notes at
apps/electron/resources/release-notes/.md. Promote next.md to
.md (see docs/operations/release.md) before releasing.
Before dispatching any stable release (dry run or real), promote the notes:
- Copy
apps/electron/resources/release-notes/next.md to
apps/electron/resources/release-notes/<version>.md with a
# v<version> — <summary> header (match the style of existing versioned
files like 0.10.6.md / 0.10.7.md).
- Reset
next.md to the empty pending template (keep the header comment and
the empty Features / Improvements / Bug Fixes / Breaking Changes sections).
- Commit as
docs(release): promote next.md to <version>.md and push to main.
Nightlies are exempt — they never promote next.md and bundle the latest
existing versioned file (so nightly What's New lags one stable cycle by design).
Pre-flight checks
Before dispatching any release:
git status
git log origin/main..HEAD
bun --print "require('./apps/electron/package.json').version"
gh secret list --repo gannonh/kata-agents
Stable-only: promote release notes
For stable dispatches, also verify the versioned notes file exists before
dispatching. The workflow gates this in release_meta and fails before any
build work:
version=0.10.7
notes="apps/electron/resources/release-notes/${version}.md"
[[ -f "$notes" ]] && echo "OK: $notes" || echo "MISSING: promote next.md to $notes first (see the Stable release notes section above)"
If missing, promote next.md → <version>.md and push before dispatching.
Nightly dispatches skip this check entirely.
Dispatch commands
gh workflow run release.yml --repo gannonh/kata-agents \
--field channel=nightly --field dry_run=true
gh workflow run release.yml --repo gannonh/kata-agents \
--field channel=nightly --field dry_run=false
gh workflow run release.yml --repo gannonh/kata-agents \
--field channel=stable --field version=0.10.4 --field dry_run=true
gh workflow run release.yml --repo gannonh/kata-agents \
--field channel=stable --field version=0.10.4 --field dry_run=false
git tag v0.10.4 && git push origin v0.10.4
For stable dispatch, the version input is the source of truth. It may be
0.10.4 or v0.10.4; the leading v is stripped and the tag becomes v<version>.
The version input is required — stable dispatch without it fails the release_meta
job. Stable dispatch no longer reads apps/electron/package.json.
For nightly, the version is computed automatically as
X.Y.(Z+1)-nightly.YYYYMMDD.N from the current apps/electron/package.json version.
This applies to both the scheduled run and any manual channel=nightly dispatch.
Polling for status
After dispatching, get the run ID and watch it:
gh run list --repo gannonh/kata-agents --workflow=release.yml --limit 3
gh run view RUN_ID --repo gannonh/kata-agents
gh api repos/gannonh/kata-agents/actions/jobs/JOB_ID/logs | tail -80
The workflow has these jobs: check_changes (scheduled only) → release_meta →
signing_gate → build (matrix) → release → finalize (stable only) → publish_cli (disabled).
check_changes is skipped on non-schedule events
build has four matrix legs: macos-14 arm64 (required), macos-14 x64 (required),
ubuntu-latest linux x64 (best-effort, continue-on-error), windows-latest win x64 (best-effort)
- The
release job only runs when dry_run != true
finalize runs only for successful, non-dry-run stable releases and
commits the version bump back to main (see below)
What to verify at each stage
Dry Run (nightly or stable)
gh release list --repo gannonh/kata-agents --limit 5
Nightly Release
- GitHub release is a prerelease (
is_prerelease=true)
- Tag format:
v<X>.<Y>.<Z+1>-nightly.<YYYYMMDD>.<N>
- Release is not marked latest
- Assets include:
Kata-Agents-arm64.dmg, Kata-Agents-x64.dmg, .zip equivalents,
nightly-mac.yml, nightly.yml (the auto-update manifests)
gh release view --repo gannonh/kata-agents <tag>
Stable Release
- GitHub release is not a prerelease (
is_prerelease=false)
- Marked latest
- Assets include: DMGs, ZIPs,
latest-mac.yml, latest.yml
gh release view --repo gannonh/kata-agents <tag>
Common failures and fixes
| Symptom | Cause | Fix |
|---|
GitHub Personal Access Token is not set | electron-builder trying to auto-publish | Add --publish never to the electron-builder invocation in the build script |
Release package manifest not found: D:\D:\... | Windows path doubling from .pathname | Use fileURLToPath(import.meta.url) instead of new URL(import.meta.url).pathname |
signing_gate fails | Missing Apple secrets | Run gh secret list --repo gannonh/kata-agents and add missing secrets from .env |
| macOS build fails after 10+ minutes | Notarization timeout or Apple service issue | Retry; notarization can be rate-limited |
Stable release <version> is missing release notes at .../<version>.md | Stable dispatch with no versioned What's New file | Promote next.md to apps/electron/resources/release-notes/<version>.md, reset next.md, commit docs(release): promote next.md to <version>.md, push to main, then re-dispatch |
Secrets reference
All values are in /Volumes/EVO/dev/kata-agents/.env.
| Secret | Purpose |
|---|
CSC_LINK | Base64 .p12 signing cert |
CSC_KEY_PASSWORD | .p12 password |
APPLE_ID | Notarization Apple ID |
APPLE_APP_SPECIFIC_PASSWORD | App-specific password for notarization |
APPLE_TEAM_ID | Apple Developer team ID (ZBZKKWF95G) |
APPLE_SIGNING_IDENTITY | Developer ID Application identity |
RELEASE_APP_ID | GitHub App ID for the finalize job (post-stable version bump to main) |
RELEASE_APP_PRIVATE_KEY | Private key (.pem) for the finalize GitHub App |
GITHUB_TOKEN | Auto-provided by Actions — no setup needed |
To re-set a secret from .env:
gh secret set SECRET_NAME --repo gannonh/kata-agents --body "value"
After a successful release
- Verify the release page looks correct at https://github.com/gannonh/kata-agents/releases
- Stable releases: the
finalize job automatically bumps
apps/electron/package.json + package.json on main to the shipped
version and commits chore(release): prepare v<version>, so the next nightly
resolves to X.Y.(Z+1)-nightly.*. No manual bump needed. If finalize skips
or fails (missing RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY), bump manually
as a fallback and fix the secrets before the next stable.
- Update
docs/specs/index.md and docs/log.md if this release closes a project milestone