--- name: "versioning-policy" description: "SemVer rules for Squad's stable, preview, insider, and local package versions" domain: "release, versioning, npm, CI" confidence: "high" source: "earned (PR #640 workspace resolution incident and automated release channels)" --- ## Context Squad publishes `@bradygaster/squad-sdk` and `@bradygaster/squad-cli` from one npm workspace. Their versions and the root version move together. A mismatched prerelease dependency can make npm silently resolve an older registry SDK instead of the local workspace. ## 1. Supported versions | Use | Version | Committed branch | |---|---|---| | Stable release | `MAJOR.MINOR.PATCH` | `main`, and briefly `dev` during promotion | | Preview release | `MAJOR.MINOR.PATCH-preview.N` | `dev` | | Insider snapshot | `MAJOR.MINOR.PATCH-insider.N` | Generated by the insider workflow | | Local build | `MAJOR.MINOR.PATCH-build.N` | Never committed | `preview` is a release channel, not a branch. Stable promotion merges a sanitized release tree directly from `dev` to `main`. ## 2. Package versions stay in lockstep These versions must always be identical: - `package.json` - `packages/squad-sdk/package.json` - `packages/squad-cli/package.json` - the corresponding workspace entries in `package-lock.json` Use the workspace-aware version command: ```bash npm version "$VERSION" --workspaces --include-workspace-root --no-git-tag-version ``` Never edit only one package version. ## 3. Prerelease workspace dependency rule The CLI depends on the SDK through a SemVer range. SemVer deliberately excludes prereleases unless the comparator names a prerelease with the same base version. For example, `>=0.13.0` does not match `0.14.0-preview.1`. For every committed preview version, set both the CLI manifest and lockfile dependency floor to that exact preview: ```bash npm pkg set "dependencies.@bradygaster/squad-sdk=>=$VERSION" \ --workspace @bradygaster/squad-cli npm install --package-lock-only ``` For `VERSION=0.14.0-preview.1`, the required range is `>=0.14.0-preview.1`. Before stable promotion, change the version and floor to `0.14.0` / `>=0.14.0`; never leave a prerelease floor in a stable release. This rule prevents the PR #640 failure mode, where the build succeeded against a stale published SDK rather than the workspace SDK. ## 4. Local build versions are ephemeral `scripts/bump-build.mjs` may create `-build.N` versions for local development. - Never commit a `-build.N` version. - The script skips itself when `CI=true` or `SKIP_BUILD_BUMP=1`. - If a build changes manifests locally, restore the intended release source versions before committing. ## 5. Release lifecycle 1. On a release-preparation branch from `dev`, set the next `X.Y.Z-preview.N` version and matching SDK dependency floor. 2. Merge to `dev`, wait for CI, and dispatch `squad-release.yml` from `dev`. 3. Repeat with a new immutable preview version when another candidate is needed. 4. Dispatch `squad-insider-publish.yml` whenever an on-demand development snapshot is needed; it computes the next immutable `X.Y.Z-insider.N`. 5. Prepare stable `X.Y.Z` and its stable SDK dependency floor on `dev`. 6. Dispatch `squad-promote.yml`; it sanitizes `dev`, pushes `main`, and explicitly dispatches the stable release. 7. Open the next preview-version PR for continued development. A preview such as `0.14.0-preview.1` is never renamed or converted in place. Stable `0.14.0` is a separate immutable package version and GitHub tag. ## 6. Ownership The current Release Manager owns release version changes. Other agents may update versions only when explicitly assigned release work or when reverting an accidentally committed local `-build.N` version. ## 7. CI enforcement CI verifies: - root, SDK, and CLI versions match; - package-lock workspace versions match; - committed prereleases use approved `preview` or `insider` identifiers; - a preview CLI dependency and lockfile entry equal `>=VERSION`; - stable source does not retain a prerelease dependency floor; and - workspace packages resolve through local links rather than stale registry packages. Release workflows repeat the dependency checks before creating a tag or publishing. ## Quick reference | Rule | Summary | |---|---| | Insider | The workflow generates `X.Y.Z-insider.N` from the stable base version | | Preview | Commit `X.Y.Z-preview.N` to `dev` for an on-demand prerelease | | Stable | Only `X.Y.Z` may release from `main` | | Sync | Root, SDK, CLI, and lockfile workspace versions must match | | Dependency | Preview CLI range and lockfile entry must be `>=VERSION` | | Local build | `-build.N` is local-only and never committed | | Ownership | The current Release Manager owns planned release version changes |