mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-25 17:25:23 +02:00
feat: 3-tier release strategy with hotfix, release, and CI workflows (#1289)
* feat: 3-tier release strategy with hotfix, release, and CI workflows Supersedes PRs #1208 and #1210 with a consolidated approach: - VERSIONING.md: Strategy document with 3 release tiers (patch/minor/major) - hotfix.yml: Emergency patch releases to latest - release.yml: Standard release cycle with RC/beta pre-releases to next - auto-branch.yml: Create branches from issue labels - branch-naming.yml: Convention validation (advisory) - pr-gate.yml: PR size analysis and labeling - stale.yml: Weekly cleanup of inactive issues/PRs - dependabot.yml: Automated dependency updates npm dist-tags: latest (stable) and next (pre-release) only, following Angular/Next.js convention. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review findings for release workflow security and correctness - Move all ${{ }} expression interpolation from run: blocks into env: mappings in both hotfix.yml (~12 instances) and release.yml (~16 instances) to prevent potential command injection via GitHub Actions expression evaluation - Reorder rc job in release.yml to run npm ci and test:coverage before pushing the git tag, preventing broken tagged commits when tests fail - Update VERSIONING.md to accurately describe the implementation: major releases use beta pre-releases only, minor releases use rc pre-releases only (no beta-then-rc progression) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: harden release workflows — SHA pinning, provenance, dry-run guards Addresses deep adversarial review + best practices research: HIGH: - Fix release.yml rc/finalize: dry_run now gates tag+push (not just npm publish) - Fix hotfix.yml finalize: reorder tag-before-publish (was publish-before-tag) MEDIUM — Security hardening: - Pin ALL actions to SHA hashes (actions/checkout@11bd7190, actions/setup-node@39370e39, actions/github-script@60a0d830) - Add --provenance --access public to all npm publish commands - Add id-token: write permission for npm provenance OIDC - Add concurrency groups (cancel-in-progress: false) on both workflows - Add branch-naming.yml permissions: {} (deny-all default) - Scope permissions per-job instead of workflow-level where possible MEDIUM — Reliability: - Add post-publish verification (npm view + dist-tag check) after every publish - Add npm publish --dry-run validation step before actual publish - Add branch existence pre-flight check in create jobs LOW: - Fix VERSIONING.md Semver Rules: MINOR = "enhancements" not "new features" (aligns with Release Tiers table) Tests: 1166/1166 pass Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: pin actions/stale to SHA hash Last remaining action using a mutable version tag. Now all actions across all workflow files are pinned to immutable SHA hashes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address all Copilot review findings on release strategy workflows - Configure git identity in all committing jobs (hotfix + release) - Base hotfix on latest patch tag instead of vX.Y.0 - Add issues: write permission for PR size labeling - Remove stale size labels before adding new one - Make tagging and PR creation idempotent for reruns - Run dry-run publish validation unconditionally - Paginate listFiles for large PRs - Fix VERSIONING.md table formatting and docs accuracy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: clean up next dist-tag after finalize in release and hotfix workflows After finalizing a release, the next dist-tag was left pointing at the last RC pre-release. Anyone running npm install @next would get a stale version older than @latest. Now both workflows point next to the stable release after finalize, matching Angular/Next.js convention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ci): address blocking issues in 3-tier release workflows - Move back-merge PR creation before npm publish in hotfix/release finalize - Move version bump commit after test step in rc workflow - Gate hotfix create branch push behind dry_run check - Add confirmed-bug and confirmed to stale.yml exempt labels - Fix auto-branch priority: critical prefix collision with hotfix/ naming Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
126
VERSIONING.md
Normal file
126
VERSIONING.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Versioning & Release Strategy
|
||||
|
||||
GSD follows [Semantic Versioning 2.0.0](https://semver.org/) with three release tiers mapped to npm dist-tags.
|
||||
|
||||
## Release Tiers
|
||||
|
||||
| Tier | What ships | Version format | npm tag | Branch | Install |
|
||||
|------|-----------|---------------|---------|--------|---------|
|
||||
| **Patch** | Bug fixes only | `1.27.1` | `latest` | `hotfix/1.27.1` | `npx get-shit-done-cc@latest` |
|
||||
| **Minor** | Fixes + enhancements | `1.28.0` | `latest` (after RC) | `release/1.28.0` | `npx get-shit-done-cc@next` (RC) |
|
||||
| **Major** | Fixes + enhancements + features | `2.0.0` | `latest` (after beta) | `release/2.0.0` | `npx get-shit-done-cc@next` (beta) |
|
||||
|
||||
## npm Dist-Tags
|
||||
|
||||
Only two tags, following Angular/Next.js convention:
|
||||
|
||||
| Tag | Meaning | Installed by |
|
||||
|-----|---------|-------------|
|
||||
| `latest` | Stable production release | `npm install get-shit-done-cc` (default) |
|
||||
| `next` | Pre-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
|
||||
|
||||
| Increment | When | Examples |
|
||||
|-----------|------|----------|
|
||||
| **PATCH** (1.27.x) | Bug fixes, typo corrections, test additions | Hook filter fix, config corruption fix |
|
||||
| **MINOR** (1.x.0) | Non-breaking enhancements, new commands, new runtime support | New workflow command, discuss-mode feature |
|
||||
| **MAJOR** (x.0.0) | Breaking changes to config format, CLI flags, or runtime API; new features that alter existing behavior | Removing 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 critical bugs that can't wait for the next minor release.
|
||||
|
||||
1. Trigger `hotfix.yml` with version (e.g., `1.27.1`)
|
||||
2. Workflow creates `hotfix/1.27.1` branch from the latest patch tag for that minor version (e.g., `v1.27.0` or `v1.27.1`)
|
||||
3. Cherry-pick or apply fix on the hotfix branch
|
||||
4. Push — CI runs tests automatically
|
||||
5. Trigger `hotfix.yml` finalize action
|
||||
6. Workflow runs full test suite, bumps version, tags, publishes to `latest`
|
||||
7. Merge hotfix branch back to main
|
||||
|
||||
### 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 prefix | Commit type | Version 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
|
||||
```
|
||||
Reference in New Issue
Block a user