| name | release |
| description | Pre-release checklist to ensure CHANGELOG, version numbers, tests, and documentation are updated before cutting a release. |
Release Skill - Pre-Release Validation
You are an expert at preparing software releases and ensuring no critical steps are missed.
When to Use
Use this skill before cutting any release to validate:
- CHANGELOG is updated with all changes
- Version numbers are consistent across files
- All tests pass
- Documentation reflects new features
- No uncommitted changes exist
The Problem
Releases often ship with:
- ❌ Missing CHANGELOG entries
- ❌ Inconsistent version numbers
- ❌ Outdated documentation
- ❌ Failing tests
- ❌ Uncommitted changes
This skill provides a systematic checklist to prevent these issues.
Pre-Release Checklist
Step 1: Determine Release Version
git describe --tags --abbrev=0
git log --oneline $(git describe --tags --abbrev=0)..HEAD
Semantic Versioning:
MAJOR.MINOR.PATCH (e.g., 1.2.0)
- MAJOR: Breaking changes
- MINOR: New features (backwards compatible)
- PATCH: Bug fixes only
Next version for this release:
- Breaking changes? → Bump MAJOR (2.0.0)
- New features? → Bump MINOR (1.3.0)
- Bug fixes only? → Bump PATCH (1.2.1)
Step 2: Update CHANGELOG.md
CRITICAL: This must be done BEFORE creating the release.
cat CHANGELOG.md
git log --oneline $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s"
CHANGELOG Format:
## [X.Y.Z] - YYYY-MM-DD
### Added
- New features go here
- Each feature as a bullet point
- Use present tense ("Add feature" not "Added feature")
### Changed
- Breaking changes
- Improvements to existing features
- Documentation updates
### Fixed
- Bug fixes
- Security patches
### Removed
- Deprecated features removed
[X.Y.Z]: https://github.com/USER/REPO/compare/vX.Y.Z-1...vX.Y.Z
What to Include:
- ✅ All user-facing changes
- ✅ New commands, flags, features
- ✅ Bug fixes that users would notice
- ✅ Breaking changes (ALWAYS mention these)
- ✅ New skills or major documentation
- ❌ Internal refactoring (unless it improves performance)
- ❌ Code cleanup that doesn't affect users
- ❌ Test-only changes
Step 3: Update Version Numbers
Check and update version in all files:
grep "version" Formula/linear-cli.rb
grep -r "version.*=.*\"" --include="*.go" .
grep "version" package.json 2>/dev/null
Files to check:
Formula/linear-cli.rb - version field
- Any version constants in Go code
- README badges (if version is shown)
Step 4: Verify Documentation
README.md:
grep -i "search" README.md
CLAUDE.md:
cat CLAUDE.md | head -100
Questions to ask:
Step 5: Run All Tests
make test
echo $?
If tests fail:
- ❌ DO NOT proceed with release
- Fix the failing tests first
- Commit the fixes
- Run tests again
Step 6: Check for Uncommitted Changes
git status
Must show:
On branch main
nothing to commit, working tree clean
If there are uncommitted changes:
- Review them carefully
- Commit if they should be in the release
- Discard if they're experimental
Step 7: Build and Smoke Test
make build
./bin/linear --help
./bin/linear search --help
./bin/linear skills list
./bin/linear issues list --limit 1
Step 8: Execute Release
Only after ALL previous steps pass.
CRITICAL: Do NOT run goreleaser locally
goreleaser release --clean
git tag vX.Y.Z && git push origin vX.Y.Z
gh run watch --exit-status
gh release download vX.Y.Z --pattern checksums.txt --output -
Running goreleaser locally AND having GitHub Actions run it causes duplicate artifact uploads and release failures.
git add -A
git commit -m "fix: Description of changes
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
git push origin main
git tag vX.Y.Z && git push origin vX.Y.Z
gh run watch --exit-status
gh release download vX.Y.Z --pattern checksums.txt --output -
git add Formula/linear-cli.rb
git commit -m "chore: Update formula to vX.Y.Z"
git push origin main
Step 9: Install and Verify
cd /opt/homebrew/Library/Taps/joa23/homebrew-linear-cli && git pull && cd -
brew upgrade linear-cli
linear --version
linear issues list --state "In Progress" --team TEST --limit 1
linear --help
linear issues list --limit 1
If upgrade fails or wrong version:
brew uninstall linear-cli
brew install linear-cli
Release Checklist Template
Copy this checklist before each release:
## Release vX.Y.Z Checklist
### Pre-Release
- [ ] Determined version number (MAJOR.MINOR.PATCH)
- [ ] Updated CHANGELOG.md with all changes
- [ ] Added section
- [ ] Changed section
- [ ] Fixed section
- [ ] Version link at bottom
- [ ] Verified version numbers consistent
- [ ] Formula/linear-cli.rb
- [ ] Code constants (if any)
- [ ] Documentation updated
- [ ] README.md includes new features
- [ ] CLAUDE.md current
- [ ] Help text accurate
- [ ] All tests pass (`make test`)
- [ ] No uncommitted changes (`git status`)
- [ ] Built and smoke tested (`make build`)
### Release
- [ ] Committed all changes with proper message
- [ ] Pushed to main
- [ ] Created and pushed tag (`git tag vX.Y.Z && git push origin vX.Y.Z`)
- [ ] Waited for GitHub Actions (`gh run watch --exit-status`)
- [ ] Downloaded checksums (`gh release download vX.Y.Z --pattern checksums.txt --output -`)
- [ ] Updated Homebrew formula
- [ ] Version number
- [ ] All SHA256 checksums (Darwin arm64, Darwin x86_64, Linux arm64, Linux x86_64)
- [ ] Committed and pushed formula
### Post-Release
- [ ] Updated local Homebrew tap (`cd /opt/homebrew/.../homebrew-linear-cli && git pull`)
- [ ] Upgraded via Homebrew (`brew upgrade linear-cli`)
- [ ] Verified `linear --version` shows correct version
- [ ] Manually tested the fix/feature
- [ ] Smoke tested critical commands
Common Mistakes to Avoid
❌ Forgetting CHANGELOG
Problem: Users don't know what changed.
Solution: ALWAYS update CHANGELOG BEFORE creating tag.
❌ Inconsistent Versions
Problem: Formula says v1.2.0 but tag is v1.3.0.
Solution: Grep for all version references before tagging.
❌ Releasing with Failing Tests
Problem: Broken release shipped to users.
Solution: make test must pass before release.
❌ Missing Documentation
Problem: New feature exists but isn't documented.
Solution: Update README and skills before release.
❌ Wrong Semantic Version
Problem: Bug fix released as MINOR version.
Solution: Review commit log to classify changes:
- New features = MINOR
- Bug fixes = PATCH
- Breaking changes = MAJOR
Rollback Procedure
If you need to rollback a bad release:
gh release delete vX.Y.Z --yes
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
Automation Notes
What could be automated:
- ✅ Version bump in files (script)
- ✅ CHANGELOG generation from commits (partially - needs human review)
- ✅ Running tests (CI/CD)
- ❌ Writing good CHANGELOG descriptions (needs human judgment)
- ❌ Deciding what's user-facing vs internal (needs context)
This skill focuses on the human judgment parts that can't be automated.
Example Release Session
User: I want to cut a new release for the search feature we just added.
Assistant (using /release skill):
Let me guide you through the pre-release checklist for cutting a release.
**Step 1: Determine Version**
Current version: v1.0.1
Commits since last release:
- feat: Add unified search command
- feat: Add dependency filtering
- feat: Add /link-deps skill
- docs: Update documentation
- fix: Token sanitization
This contains new features (search, link-deps skill), so we should bump MINOR version.
→ Next version: v1.2.0
**Step 2: CHANGELOG Check**
Let me read CHANGELOG.md...
❌ CHANGELOG.md is missing v1.2.0 section!
I need to add a section for v1.2.0. Let me review commits to categorize:
Added:
- Unified search command
- Dependency filters (--blocked-by, --blocks, etc.)
- /link-deps skill
- Enhanced documentation
Changed:
- All skills updated with search references
Fixed:
- Token sanitization
Let me update CHANGELOG.md now...
[Updates CHANGELOG]
✅ CHANGELOG.md now includes v1.2.0
**Step 3: Version Numbers**
Checking Formula/linear-cli.rb... shows v1.1.1
❌ Needs update to v1.2.0 (but this happens AFTER goreleaser)
**Step 4: Documentation**
Checking README.md... ✅ Search feature documented
Checking CLAUDE.md... ✅ Current
Checking --help output... ✅ Up to date
**Step 5: Tests**
Running: make test
✅ All tests pass
**Step 6: Uncommitted Changes**
Running: git status
Modified files:
- CHANGELOG.md
❌ We have uncommitted CHANGELOG changes
→ Commit these before proceeding
[User commits CHANGELOG]
**Step 7: Build and Smoke Test**
Running: make build
Testing: ./bin/linear search --help
✅ Build successful, commands working
**Step 8: Execute Release**
✅ All checks passed! Executing release:
1. git add -A && git commit -m "..." && git push origin main
2. git tag v1.2.0 && git push origin v1.2.0
3. gh run watch --exit-status # Wait for GitHub Actions
4. gh release download v1.2.0 --pattern checksums.txt --output -
5. [Update Formula/linear-cli.rb with checksums]
6. git add Formula/linear-cli.rb && git commit && git push
**Step 9: Install and Verify**
cd /opt/homebrew/Library/Taps/joa23/homebrew-linear-cli && git pull && cd -
brew upgrade linear-cli
linear --version # Shows v1.2.0
linear search --help # Test the new feature
✅ Release complete!
This systematic approach caught the missing CHANGELOG entry!
Quick Reference
Before EVERY release, run through this:
git log --oneline $(git describe --tags --abbrev=0)..HEAD
grep -A 20 "## \[.*\]" CHANGELOG.md | head -30
make test
git status
make build && ./bin/linear --help
If ANY check fails, stop and fix it before creating the tag.
Best Practices
- Update CHANGELOG first - Don't wait until after tagging
- Review every commit - Understand what's actually changing
- Test the build - Don't assume it works
- Document new features - Users need to know what's new
- Use semantic versioning - Breaking changes = MAJOR bump
Success Criteria
After using this skill, you should have:
- ✅ Complete CHANGELOG entry for the new version
- ✅ All version numbers updated
- ✅ All tests passing
- ✅ Documentation current
- ✅ Clean git state
- ✅ Confidence that the release is ready
Never skip the checklist. Ever.