Releasing
How an Oktapod release is cut, verified, and published to the stable or beta channel. For maintainers.
Releases are judged by real install, update, and rollback journeys, not only by unit tests. This page is the maintainer checklist.
Tags and channels
Tags use CalVer: YYYY.MM.DD, or YYYY.MM.DD.N for a second cut on the same
day. A beta tag says so, for example 2026.04.14-beta.1.
There is one artifact set per release. Stable or beta only depends on whether GitHub marks the release as a prerelease.
| Stable | Beta | |
|---|---|---|
| Workflow input | channel: stable (default) | channel: beta |
| Installs it | install.sh and install.ps1 default | --channel beta or -Channel beta |
| Updates to it | updater channel stable (default) | updater channel prerelease |
An install remembers its channel, so a beta install keeps following beta and a stable install never drifts onto a prerelease.
Cut a release
Ordinary development CI combines types, lint, repository checks and required
smoke tests in one job. Full validation runs on production pushes and manual CI
dispatches. pnpm release:cut obtains successful full validation for the exact
commit before promoting it; a development check cannot substitute for release
evidence.
Run the preflight locally:
pnpm release:preflight -- --tag=2026.04.14Promote the tested
maincommit toproduction, then run the private-release workflow fromproductionwith thetag(andchannelfor a beta). The workflow rejects other branches, including preflight runs. It runs the release gates, builds every platform, runs install and upgrade smoke tests, and uploads everything to a draft release. A draft is invisible to installers and the updater.Check, then publish:
pnpm release:publish -- --tag 2026.04.14 --dry-run pnpm release:publish -- --tag 2026.04.14 pnpm release:publish -- --tag 2026.04.14-beta.1 --channel beta
release:publish refuses to publish a release that is missing anything an
install needs: source and bundle archives, a binary and single-executable build
for linux-x64, linux-arm64, darwin-arm64, and windows-x64, the Windows
setup package, and the Linux setup packages for x64 and ARM64. It re-downloads
and re-verifies the final artifacts, and creates or checks the Git tag at the
verified commit. It never moves an existing tag.
Publishing a stable release makes it the repository's latest release, which is
what an installer without --ref installs.
pnpm release:prepare -- --tag=<tag> builds the bundle and notes locally
under .oktapod/releases/<tag>/, with release-notes.md,
release-manifest.json, and SHA256SUMS.
Mac releases are Apple Silicon only.
Prove install and update
pnpm release:validate -- --repo-url="$(pwd)" --install-ref=2026.04.13 --update-ref=2026.04.14
pnpm release:validate:docker -- --repo-root="$(pwd)" --install-ref=2026.04.14
The first installs the older release, updates to the new one, and writes
.oktapod/reports/private-install-update.json. The second runs a Linux
container install.
Required evidence
oktapod smoke browser-search
oktapod smoke browser-workflows
pnpm security:dependencies
oktapod evidence setup-upgrade-restore
oktapod evidence operator-journey
oktapod evidence proactive
pnpm capability:guidance:evidence
oktapod release-gates --enforce
pnpm go-live:current-state -- --fail-on-blocked
security:dependencies blocks moderate, high, or critical advisories in the
production dependency graph. go-live:current-state is the final blocker
audit: it joins release gates, readiness, security, and signoff into
.oktapod/reports/go-live-current-state.json, and lists the next action for
each blocker. When only signoff remains:
pnpm production:signoff --section=all --approver="release_owner"
For the web app, also run pnpm ui:parity and pnpm test:ui:e2e.
Rollback drills
If a change touches onboarding, auth, or runtime configuration:
pnpm exec tsx tools/runtime/run-bootstrap-rollback-drill.ts
pnpm exec tsx tools/dev/run-failure-mode-drills.ts
If release evidence is incomplete, do not cover it with confident wording. Fix the missing evidence or stop the cut.
The full internal runbook, including CI host limits and catalog details, is
docs/RELEASING.md in the repository.