feat: add CI/CD and release automation

- Add GitHub Actions CI for cross-platform testing (ubuntu/windows/macos × node 18/20/22)
- Add release workflow that auto-creates GitHub Releases and publishes to npm on tag push
- Add CONTRIBUTING.md with branching strategy (maintainers direct commit, contributors PR)
- Add MAINTAINERS.md with release workflows and recovery procedures
- Add PR template for contributors

Closes #221

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Lex Christopherson
2026-01-22 10:37:09 -06:00
parent 460f0d9963
commit a3a16be296
5 changed files with 484 additions and 0 deletions

24
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,24 @@
## What
<!-- One sentence: what does this PR do? -->
## Why
<!-- One sentence: why is this change needed? -->
## Testing
- [ ] Tested on macOS
- [ ] Tested on Windows
- [ ] Tested on Linux
## Checklist
- [ ] Follows GSD style (no enterprise patterns, no filler)
- [ ] Updates CHANGELOG.md for user-facing changes
- [ ] No unnecessary dependencies added
- [ ] Works on Windows (backslash paths tested)
## Breaking Changes
None

70
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build hooks
run: npm run build:hooks
- name: Run tests
run: |
if npm pkg get scripts.test | grep -q '"test"'; then
npm test
else
echo "No test script defined, skipping"
fi
shell: bash
- name: Verify installation
run: |
npm link
npx get-shit-done-cc --version
shell: bash
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run lint
run: |
if npm pkg get scripts.lint | grep -q '"lint"'; then
npm run lint
else
echo "No lint script defined, skipping"
fi

83
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,83 @@
name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- '!v*-*' # Exclude pre-release tags
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Releasing version: $VERSION"
- name: Extract changelog section
id: changelog
run: |
VERSION="${{ steps.version.outputs.VERSION }}"
awk -v ver="$VERSION" '
/^## \[/ {
if (found) exit
if ($0 ~ "\\[" ver "\\]") found=1
}
found {print}
' CHANGELOG.md > release_notes.md
if [ ! -s release_notes.md ]; then
echo "## v$VERSION" > release_notes.md
echo "" >> release_notes.md
echo "See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details." >> release_notes.md
fi
echo "Release notes:"
cat release_notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body_path: release_notes.md
draft: false
prerelease: false
generate_release_notes: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish:
needs: release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build:hooks
- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

160
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,160 @@
# Contributing to Get Shit Done
No enterprise theater. Ship useful code.
## Philosophy
GSD optimizes for **solo developer + Claude workflow**. The release process follows the same principle: complexity lives in automation, not your workflow.
## Branch Strategy
```
main ════════════════════════════════════════════►
▲ ▲ ▲ ▲
│ │ │ │
v1.9.0 v1.9.1 v1.10.0 v2.0.0
```
### `main`
Production. Always installable via `npx get-shit-done-cc`.
- Must pass CI (catches Windows/cross-platform issues)
- Protected from force pushes
### Who Can Commit Directly to Main
| Role | Direct commits | Branch + PR |
|------|----------------|-------------|
| Maintainers | Any change | Never required |
| Contributors | Typo/doc fixes only | All code changes |
**Why no PRs for maintainers?** Self-reviewed PRs are ceremony without value. CI still runs on push. For risky features, use pre-release tags instead.
### Feature Branches (Contributors)
```bash
git checkout -b feat/model-profiles
# or fix/windows-paths, docs/examples
git push origin feat/model-profiles
# Open PR, get review, merge
```
**Branch naming:**
- `feat/description` — New capability
- `fix/description` — Bug fix
- `docs/description` — Documentation only
- `refactor/description` — Internal changes
## Commits
Use conventional commits.
```
feat(checkpoints): add rollback capability
fix(install): use absolute paths on Windows (#207)
docs(readme): update installation instructions
refactor(orchestrator): extract context loading
```
| Type | Use |
|------|-----|
| `feat` | New feature |
| `fix` | Bug fix |
| `docs` | Documentation |
| `refactor` | Code change without behavior change |
| `chore` | Maintenance, dependencies |
| `revert` | Undoing previous commit |
## Releases
### Tag Strategy
| Change Type | Tag? | Version Bump |
|-------------|------|--------------|
| Breaking change | Yes | MAJOR (2.0.0) |
| New feature | Yes | MINOR (1.10.0) |
| Bug fix | Batch weekly | PATCH (1.9.x) |
| Documentation | No | — |
### Pre-release Tags for Risky Features
For experimental features, use pre-release tags:
```bash
npm version prerelease --preid=alpha # v1.10.0-alpha.0
git push origin main --tags
```
Users opt-in: `npm install get-shit-done-cc@1.10.0-alpha.0`
If it doesn't work out, delete the tag. No messy public revert.
### Creating a Release
Run `/gsd-publish-version` which walks you through:
1. Changelog generation from commits
2. Version bump
3. Push to GitHub
GitHub Actions automatically:
- Creates the GitHub Release from CHANGELOG.md
- Publishes to npm
## Pull Request Guidelines (Contributors)
### Title
Use conventional commit format:
```
feat(checkpoints): add rollback capability
fix(install): use absolute paths on Windows
```
### Description
- **What:** One sentence describing the change
- **Why:** One sentence explaining the need
- **Testing:** How you verified it works
- **Breaking Changes:** List any, or "None"
### Checklist
- [ ] Follows GSD style (no enterprise patterns)
- [ ] Updates CHANGELOG.md for user-facing changes
- [ ] No unnecessary dependencies
- [ ] Works on Windows (test backslash paths)
## What NOT to Do
**Enterprise patterns (banned):**
- Story points, sprint ceremonies
- RACI matrices, release committees
- Multi-week stabilization branches
**Vague commits (banned):**
```
# Bad
"Improve performance"
"Fix bugs"
# Good
"Reduce orchestrator context load from 12KB to 4KB"
"Fix Windows path handling in hook commands (#207)"
```
## Development Setup
```bash
git clone https://github.com/glittercowboy/get-shit-done.git
cd get-shit-done
npm install
npm link
npx get-shit-done-cc --version
```
## Getting Help
- **Issues:** Bug reports, feature requests
- **Discussions:** Questions, ideas

147
MAINTAINERS.md Normal file
View File

@@ -0,0 +1,147 @@
# GSD Maintainer Guide
Quick reference for release workflows and maintenance tasks.
## Release Workflow
### Standard Release
```bash
/gsd-publish-version
```
The command walks you through:
1. Check uncommitted changes
2. Generate changelog from commits
3. Review and approve changelog
4. Update CHANGELOG.md
5. Bump version (`npm version patch|minor|major`)
6. Push to GitHub with tags
GitHub Actions then:
- Creates GitHub Release from CHANGELOG.md
- Publishes to npm
### Pre-release (Experimental Features)
For risky features, ship as alpha first:
```bash
# Bump to alpha
npm version prerelease --preid=alpha
# Push
git push origin main --tags
```
Pre-release tags (`v1.10.0-alpha.0`) don't trigger npm publish or GitHub Release creation. Users opt-in explicitly.
If it works, promote to stable:
```bash
npm version minor # or patch
git push origin main --tags
```
If it fails, delete the tag and move on.
### Hotfix
Production broken? Skip changelog ceremony:
```bash
# Fix the issue
git add . && git commit -m "fix(install): handle Windows UNC paths"
# Bump and push
npm version patch
git push origin main --tags
```
## Version Cadence
| Type | When | Example |
|------|------|---------|
| MAJOR | Breaking changes | Command removed, format changed |
| MINOR | New features | New command, new capability |
| PATCH | Bug fixes | Batch weekly, or immediately if critical |
## Changelog Format
Follow [Keep a Changelog](https://keepachangelog.com/):
```markdown
## [1.10.0] - 2025-01-22
### Added
- New `/gsd:whats-new` command
### Changed
- Improved parallel execution
### Fixed
- STATE.md progress calculation
### Removed
- **BREAKING:** Deprecated ISSUES.md system
```
## Dependency Policy
Before adding dependencies:
1. Check bundle size impact
2. Evaluate if it's worth the weight
3. Consider if the functionality can be implemented without it
The codebase intelligence system was removed partly because sql.js added 21MB.
## Recovery Procedures
### Broken npm Release
Within 72 hours:
```bash
npm unpublish get-shit-done-cc@1.9.5
```
After 72 hours: Publish a fix as new patch version.
### Wrong Tag
```bash
# Delete local and remote
git tag -d v1.9.5
git push origin :refs/tags/v1.9.5
# Recreate correctly
git tag -a v1.9.5 -m "Release v1.9.5"
git push origin v1.9.5
```
### Missing Changelog Entry
Either amend the release commit or add a follow-up commit with the missing content.
## CI/CD Setup
### Required Secrets
In GitHub repo settings → Secrets → Actions:
- `NPM_TOKEN`: npm automation token with publish access
`GITHUB_TOKEN` is provided automatically.
### Branch Protection (Optional)
Settings → Branches → Add rule for `main`:
- Require status checks: `test`, `lint`
- Disable force pushes
## Reviewing Contributor PRs
Checklist:
- [ ] Follows conventional commit format
- [ ] No enterprise patterns or filler
- [ ] CHANGELOG.md updated for user-facing changes
- [ ] No unnecessary dependencies
- [ ] Tested on Windows if touching paths