This document describes the process for creating and publishing new releases of abacus.
- Prerequisites
- Release Checklist
- Step-by-Step Release Process
- Post-Release Verification
- Hotfix Releases
- Rollback Procedure
- Troubleshooting
- Git: Version control
- Go: 1.23 or later (for local testing)
- GoReleaser: Installed locally for testing (optional but recommended)
brew install --cask goreleaser
- GitHub Repository: Write access to
ChrisEdwards/abacus - Homebrew Tap: Write access configured via
HOMEBREW_TAP_TOKENsecret - Git Configuration: Properly configured user name and email
# Check git config
git config user.name
git config user.email
# Verify you're on main branch and up to date
git checkout main
git pull origin main
# Verify working directory is clean
git status
# Check GoReleaser (optional)
goreleaser checkBefore starting a release, ensure:
- All intended features/fixes are merged to
main - All tests pass:
go test ./... - All builds succeed:
make build - Working directory is clean (no uncommitted changes)
- You have reviewed the changes since last release
Note: You no longer need to manually determine version numbers or write changelog entries. The /update-changelog command will analyze changes and suggest the appropriate semantic version bump automatically.
One-step release: The
/release-abacusClaude Code command (included in this repo at.claude/commands/release-abacus.md) automates the entire process below end-to-end — pre-flight checks, changelog generation, version bump, dry run, execution, CI monitoring, and verification — with confirmation prompts at each step.
Use the /update-changelog Claude Code slash command to automatically analyze changes and prepare the release:
# In Claude Code, run:
/update-changelogWhat this does:
- Analyzes all commits since the last release
- Reviews all closed beads (issues)
- Examines code changes to understand scope
- Considers existing manual entries in CHANGELOG.md
- Uses AI to determine the appropriate semantic version bump (patch/minor/major)
- Generates Keep a Changelog format entries
- Updates
next-version.txtwith the suggested version - Updates the
[Unreleased]section in CHANGELOG.md
AI will present:
- Recommended version bump with rationale
- Generated changelog entries organized by category
- Request for your confirmation
You review and then:
- If approved: commit the changes
- If adjustments needed: ask for regeneration or manually edit
After reviewing the AI-generated changelog:
git add CHANGELOG.md next-version.txt
git commit -m "Prepare release v0.2.0"
git push origin mainRun the automated release script:
Preview the release (dry run - default):
./scripts/release.shExecute the release:
./scripts/release.sh --executeWhat the script does:
- Reads version from
next-version.txt - Runs pre-flight checks (tests, build, git status)
- Finalizes CHANGELOG.md (
[Unreleased]→[X.Y.Z] - YYYY-MM-DD) - Creates release commit and annotated tag
vX.Y.Z - Prompts for confirmation before pushing
- Pushes commit and tag to GitHub (triggers CI/CD)
- Auto-bumps
next-version.txtto next patch version - Commits and pushes the version bump
Options:
--dry-run: Show what would happen (default)--execute: Actually perform the release--no-push: Create commit/tag but don't push (for testing)
Once the tag is pushed, the release workflow automatically triggers:
-
Go to GitHub Actions: https://github.com/ChrisEdwards/abacus/actions
-
Watch the
Releaseworkflow:- GoReleaser job: Builds binaries for all platforms
- Update Homebrew job: Updates the Homebrew formula
-
Expected duration: 3-5 minutes
After the workflow completes:
-
Check the release page: https://github.com/ChrisEdwards/abacus/releases
-
Verify release assets:
abacus_X.Y.Z_darwin_amd64.tar.gzabacus_X.Y.Z_darwin_arm64.tar.gzabacus_X.Y.Z_linux_amd64.tar.gzabacus_X.Y.Z_linux_arm64.tar.gzabacus_X.Y.Z_windows_amd64.tar.gzchecksums.txt
-
Verify release notes: Should include our curated CHANGELOG entries (extracted via
scripts/extract-changelog.sh)
The GitHub Actions workflow automatically updates the Homebrew formula:
-
Check the tap repository: https://github.com/ChrisEdwards/homebrew-tap
-
Verify Formula/abacus.rb was updated:
- Version number matches
- SHA256 checksums are present (not placeholders)
- URLs point to correct release
-
Test Homebrew installation (optional but recommended):
# Uninstall old version if present brew uninstall ChrisEdwards/tap/abacus 2>/dev/null || true # Install new version brew install ChrisEdwards/tap/abacus # Verify version abacus --version
brew uninstall ChrisEdwards/tap/abacus 2>/dev/null || true
brew install ChrisEdwards/tap/abacus
abacus --version# Download from GitHub Releases
curl -LO https://github.com/ChrisEdwards/abacus/releases/download/vX.Y.Z/abacus_X.Y.Z_darwin_arm64.tar.gz
tar -xzf abacus_X.Y.Z_darwin_arm64.tar.gz
./abacus --versiongo install github.com/ChrisEdwards/abacus/cmd/abacus@vX.Y.Z
abacus --versionThe --version flag should display:
abacus version X.Y.Z (build: <commit-sha>) [<timestamp>]
Go version: go1.25.3
OS/Arch: darwin/arm64
For critical bug fixes that need immediate release:
git checkout -b hotfix/X.Y.Z# Make your changes
# Run tests
go test ./...
make buildgit add .
git commit -m "Fix: critical bug description"
git checkout main
git merge hotfix/X.Y.Z
git push origin mainOption A: Use AI to generate changelog
# In Claude Code:
/update-changelog
# AI will detect the bug fix and suggest a patch versionOption B: Manually update files
# Manually edit next-version.txt (increment patch)
# Manually add entry to [Unreleased] in CHANGELOG.md
git add next-version.txt CHANGELOG.md
git commit -m "Prepare hotfix release vX.Y.Z"
git push origin main./scripts/release.sh --executeIf a release has critical issues:
# Delete remote tag
git push --delete origin vX.Y.Z
# Delete local tag
git tag -d vX.Y.Z
# Delete GitHub Release
# Go to: https://github.com/ChrisEdwards/abacus/releases
# Click on the release → DeleteInstead of rolling back, publish a new patch release:
# Example: If v0.2.0 has issues, release v0.2.1
# 1. Make fixes and commit
# 2. Update next-version.txt to 0.2.1
# 3. Update CHANGELOG.md with fix notes
# 4. Commit changes
# 5. Run: ./scripts/release.sh --executeIf the Homebrew formula needs to be reverted:
# Clone tap
git clone https://github.com/ChrisEdwards/homebrew-tap.git
cd homebrew-tap
# Revert to previous version
git revert HEAD
git push origin mainProblem: GitHub Actions workflow fails during release
Solutions:
- Check workflow logs: https://github.com/ChrisEdwards/abacus/actions
- Common causes:
- GoReleaser configuration error → Fix
.goreleaser.yml - Missing HOMEBREW_TAP_TOKEN → Verify GitHub secret
- Build failures → Run
go test ./...andmake buildlocally - Network issues → Re-run workflow
- GoReleaser configuration error → Fix
Problem: Formula in tap repository wasn't updated
Solutions:
- Verify workflow completed: Check GitHub Actions
- Check HOMEBREW_TAP_TOKEN: Verify secret exists and has correct permissions
- Manual update (if needed):
# Clone tap git clone https://github.com/ChrisEdwards/homebrew-tap.git cd homebrew-tap # Edit Formula/abacus.rb manually # Update version and checksums # Commit and push git add Formula/abacus.rb git commit -m "Update abacus to vX.Y.Z" git push origin main
Problem: Built binaries show wrong version with --version
Solutions:
- Check GoReleaser config: Verify ldflags in
.goreleaser.yml - Verify tag format: Must be
vX.Y.Z(with 'v' prefix) - Check main.go: Ensure version variables exist
Problem: SHA256 checksums in formula don't match downloads
Solutions:
- Re-download assets: GitHub may have updated them
- Regenerate checksums:
# Download the archive curl -LO https://github.com/ChrisEdwards/abacus/releases/download/vX.Y.Z/abacus_X.Y.Z_darwin_arm64.tar.gz # Calculate SHA256 shasum -a 256 abacus_X.Y.Z_darwin_arm64.tar.gz
- Update formula manually if needed
Problem: brew install fails with error
Solutions:
- Update Homebrew:
brew update - Check formula syntax:
brew install --formula Formula/abacus.rb
- Verify URLs are accessible:
curl -I https://github.com/ChrisEdwards/abacus/releases/download/vX.Y.Z/abacus_X.Y.Z_darwin_arm64.tar.gz
- Clear Homebrew cache:
brew cleanup
Problem: Cannot create tag because it already exists
Solutions:
- Use a different version number: Increment patch version
- Delete existing tag (if it was a mistake):
git push --delete origin vX.Y.Z git tag -d vX.Y.Z
For additional help:
- GitHub Issues: https://github.com/ChrisEdwards/abacus/issues
- GitHub Actions Logs: https://github.com/ChrisEdwards/abacus/actions
- Homebrew Tap: https://github.com/ChrisEdwards/homebrew-tap
See CHANGELOG.md for detailed version history.