Release Process for Squad Maintainers
Squad has three automated release channels:
| Channel | Source | Version | npm tag | Package managers |
|---|---|---|---|---|
| Insider | Manual insider dispatch from dev | X.Y.Z-insider.N | insider | Homebrew and WinGet |
| Preview | Manual release dispatch from dev | X.Y.Z-preview.N | preview | Homebrew and WinGet |
| Stable | Sanitized promotion to main | X.Y.Z | latest | Homebrew and WinGet |
There is no staging preview branch. The word preview refers to a GitHub
prerelease and npm dist-tag.
Prepare the version
Create a normal release-preparation PR targeting dev. Keep the root, SDK, and
CLI versions in lockstep:
VERSION=1.2.0-preview.1
npm version "$VERSION" --workspaces --include-workspace-root --no-git-tag-version
npm pkg set "dependencies.@bradygaster/squad-sdk=>=$VERSION" \
--workspace @bradygaster/squad-cli
npm install --package-lock-only
Add an exact changelog heading:
## [1.2.0-preview.1] - YYYY-MM-DD
Before merging, verify:
node -p "require('semver').valid('$VERSION')"
grep '"version"' package.json packages/squad-sdk/package.json packages/squad-cli/package.json
grep -F "## [$VERSION]" CHANGELOG.md
npm run build
npx vitest run
Wait for dev CI to pass after the PR merges.
Publish a preview
Use a unique prerelease version such as 1.2.0-preview.1:
VERSION=1.2.0-preview.1
gh workflow run squad-release.yml \
--ref dev \
-f confirm_tag="v$VERSION"
gh run watch
The workflow validates that it is running on dev and that the version is not
stable. It then:
- Creates the immutable tag.
- Creates a GitHub prerelease.
- Publishes the SDK and CLI to npm
preview. - Uploads standalone archives for macOS, Linux, and Windows.
- Updates
squad-previewin Homebrew andbradygaster.Squad.Previewin WinGet.
Install the preview with:
npm install -g @bradygaster/squad-cli@preview
brew install --cask squad-preview
winget install --id bradygaster.Squad.Preview --exact
Publish an insider snapshot
Dispatch the insider workflow from dev:
gh workflow run squad-insider-publish.yml --ref dev -f dry_run=false
gh run watch
The workflow computes the next immutable X.Y.Z-insider.N version, publishes
both npm packages, creates a GitHub prerelease, uploads standalone archives,
updates squad-insider in Homebrew, and opens or reuses the
bradygaster.Squad.Insider WinGet PR.
Publish stable
Prepare another PR that changes all package versions and the changelog heading
from the prerelease version to stable 1.2.0. A preview version cannot be
converted in place after publication; 1.2.0-preview.1 and 1.2.0 are
different releases.
After the stable preparation lands on dev, a human must run the promotion
validation. This is not agent-safe: squad-promote.yml grants
actions: write and contents: write, checks out dev with the workflow
token, installs dependencies, and runs the release build and tests.
gh workflow run squad-promote.yml --ref dev -f dry_run=true
gh run watch
Only a human may then run the live promotion:
gh workflow run squad-promote.yml --ref dev -f dry_run=false
gh run watch
The promotion workflow merges dev directly into main, removes internal team
state from the release tree, validates versions and the changelog, builds, runs
tests, and pushes main.
Promotion explicitly dispatches squad-release.yml after pushing main,
because GitHub does not start another workflow from a GITHUB_TOKEN push. The
release workflow creates the stable tag and GitHub Release, publishes npm
latest, uploads standalone archives, updates the Homebrew cask, and opens or
reuses the WinGet manifest PR.
What gets removed from main
The promotion workflow strips:
.ai-team/
.squad/
.ai-team-templates/
team-docs/
docs/proposals/
Those paths remain on dev; no force push or staging branch is needed.
Verify a release
For preview:
npm view @bradygaster/squad-sdk dist-tags.preview
npm view @bradygaster/squad-cli dist-tags.preview
For stable:
npm view @bradygaster/squad-sdk dist-tags.latest
npm view @bradygaster/squad-cli dist-tags.latest
The values must equal the release version. The GitHub Release must contain six
archives and SHA256SUMS.txt. Every channel must update its Homebrew cask and
create or reuse its WinGet PR:
| Channel | Homebrew cask | WinGet identifier |
|---|---|---|
| Insider | squad-insider | bradygaster.Squad.Insider |
| Preview | squad-preview | bradygaster.Squad.Preview |
| Stable | squad | bradygaster.Squad |
Recover a failed publication
Do not recreate the tag or GitHub Release. Rerun the failed job. If a reusable workflow must be dispatched directly, build from the immutable tag:
VERSION=1.2.0
gh workflow run squad-npm-publish.yml --ref main \
-f version="$VERSION" -f source_ref="v$VERSION"
gh workflow run squad-standalone-release.yml --ref main \
-f upload=true -f release_tag="v$VERSION" -f source_ref="v$VERSION"
Use --ref dev for preview-release recovery. Publication steps verify existing
versions and assets instead of overwriting them.
After stable
Open a normal PR to dev that sets the next development version, for example:
NEXT_VERSION=1.3.0-preview.1
npm version "$NEXT_VERSION" --workspaces --include-workspace-root --no-git-tag-version
npm pkg set "dependencies.@bradygaster/squad-sdk=>=$NEXT_VERSION" \
--workspace @bradygaster/squad-cli
npm install --package-lock-only