Back to Get Shit Done

Versioning & Release Strategy

VERSIONING.md

1.40.07.0 KB
Original Source

Versioning & Release Strategy

GSD follows Semantic Versioning 2.0.0 with three release tiers mapped to npm dist-tags.

Release Tiers

TierWhat shipsVersion formatnpm tagBranchInstall
PatchBug fixes only1.27.1latesthotfix/1.27.1npx get-shit-done-cc@latest
MinorFixes + enhancements1.28.0latest (after RC)release/1.28.0npx get-shit-done-cc@next (RC)
MajorFixes + enhancements + features2.0.0latest (after beta)release/2.0.0npx get-shit-done-cc@next (beta)

npm Dist-Tags

Only two tags, following Angular/Next.js convention:

TagMeaningInstalled by
latestStable production releasenpm install get-shit-done-cc (default)
nextPre-release (RC or beta)npm install get-shit-done-cc@next (opt-in)

The version string (-rc.1 vs -beta.1) communicates stability level. Users never get pre-releases unless they explicitly opt in.

Semver Rules

IncrementWhenExamples
PATCH (1.27.x)Bug fixes, typo corrections, test additionsHook filter fix, config corruption fix
MINOR (1.x.0)Non-breaking enhancements, new commands, new runtime supportNew workflow command, discuss-mode feature
MAJOR (x.0.0)Breaking changes to config format, CLI flags, or runtime API; new features that alter existing behaviorRemoving a command, changing config schema

Pre-Release Version Progression

Major and minor releases use different pre-release types:

Minor: 1.28.0-rc.1  →  1.28.0-rc.2  →  1.28.0
Major: 2.0.0-beta.1 →  2.0.0-beta.2 →  2.0.0
  • beta (major releases only): Feature-complete but not fully tested. API mostly stable. Used for major releases to signal a longer testing cycle.
  • rc (minor releases only): Production-ready candidate. Only critical fixes expected.
  • Each version uses one pre-release type throughout its cycle. The rc action in the release workflow automatically selects the correct type based on the version.

Branch Structure

main                              ← stable, always deployable
  │
  ├── hotfix/1.27.1               ← patch: cherry-pick fix from main, publish to latest
  │
  ├── release/1.28.0              ← minor: accumulate fixes + enhancements, RC cycle
  │     ├── v1.28.0-rc.1          ← tag: published to next
  │     └── v1.28.0               ← tag: promoted to latest
  │
  ├── release/2.0.0               ← major: features + breaking changes, beta cycle
  │     ├── v2.0.0-beta.1         ← tag: published to next
  │     ├── v2.0.0-beta.2         ← tag: published to next
  │     └── v2.0.0                ← tag: promoted to latest
  │
  ├── fix/1200-bug-description    ← bug fix branch (merges to main)
  ├── feat/925-feature-name       ← feature branch (merges to main)
  └── chore/1206-maintenance      ← maintenance branch (merges to main)

Release Workflows

Patch Release (Hotfix)

For fixes that need to ship without waiting for the next minor.

A hotfix vX.YY.Z cumulatively includes everything in vX.YY.{Z-1} plus every fix:/chore: commit landed on main since that base. The base tag is the anchor — git cherry $BASE_TAG main reveals exactly which commits are still unshipped, and the new vX.YY.Z tag becomes the next hotfix's base, so the cycle is self-documenting.

Two paths

Path A — hotfix.yml (canonical, two-step):

  1. Trigger hotfix.yml with action=create, version=1.27.1, auto_cherry_pick=true (default).
    • Workflow detects BASE_TAG = highest v1.27.* < v1.27.1 (so 1.27.1 branches from v1.27.0; 1.27.2 would branch from v1.27.1).
    • Branches hotfix/1.27.1 from BASE_TAG.
    • Auto-cherry-picks every fix:/chore: commit on origin/main not already in the base, oldest-first. Patch-equivalents are skipped via git cherry. feat:/refactor: are never auto-included.
    • On conflict the workflow halts with the offending SHA. Resolve manually on the branch, then re-run finalize with auto_cherry_pick=false.
    • Bumps package.json (and sdk/package.json), pushes the branch, and lists every included SHA in the run summary.
  2. (Optional) push additional manual commits to hotfix/1.27.1.
  3. Trigger hotfix.yml with action=finalize. The workflow:
    • Runs install-smoke cross-platform gate.
    • Runs full test suite + coverage.
    • Builds SDK, bundles sdk-bundle/gsd-sdk.tgz inside the CC tarball (parity with release-sdk.yml).
    • Tags v1.27.1, publishes to @latest, re-points @next → v1.27.1.
    • Opens merge-back PR against main.

Path B — release-sdk.yml (stopgap, one-shot):

Active while the @gsd-build/sdk npm token is unavailable; bundles the SDK inside the CC tarball.

  1. Trigger release-sdk.yml with action=hotfix, version=1.27.1, auto_cherry_pick=true.
    • The prepare job creates the branch and cherry-picks (same logic as Path A).
    • install-smoke runs against the new branch.
    • The release job tags, publishes to @latest, re-points @next, opens merge-back PR.
    • Idempotent: if hotfix/1.27.1 already exists (e.g. you ran hotfix.yml create first), the prepare job checks it out and re-runs cherry-pick as a no-op.
  2. dry_run=true exercises the full pipeline without pushing the branch or publishing.

Minor Release (Standard Cycle)

For accumulated fixes and enhancements.

  1. Trigger release.yml with action create and version (e.g., 1.28.0)
  2. Workflow creates release/1.28.0 branch from main, bumps package.json
  3. Trigger release.yml with action rc to publish 1.28.0-rc.1 to next
  4. Test the RC: npx get-shit-done-cc@next
  5. If issues found: fix on release branch, publish rc.2, rc.3, etc.
  6. Trigger release.yml with action finalize — publishes 1.28.0 to latest
  7. Merge release branch to main

Major Release

Same as minor but uses -beta.N instead of -rc.N, signaling a longer testing cycle.

  1. Trigger release.yml with action create and version (e.g., 2.0.0)
  2. Trigger release.yml with action rc to publish 2.0.0-beta.1 to next
  3. If issues found: fix on release branch, publish beta.2, beta.3, etc.
  4. Trigger release.yml with action finalize -- publishes 2.0.0 to latest
  5. Merge release branch to main

Conventional Commits

Branch names map to commit types:

Branch prefixCommit typeVersion bump
fix/fix:PATCH
feat/feat:MINOR
hotfix/fix:PATCH (immediate)
chore/chore:none
docs/docs:none
refactor/refactor:none

Publishing Commands (Reference)

bash
# Stable release (sets latest tag automatically)
npm publish

# Pre-release (must use --tag to avoid overwriting latest)
npm publish --tag next

# Verify what latest and next point to
npm dist-tag ls get-shit-done-cc