Releasing lazycap
January 23, 2026 ยท View on GitHub
This document describes the release process for lazycap. The project uses trunk-based development with automated releases on every push to main.
Table of Contents
- Overview
- Automatic Releases
- Version Bumping
- Semantic Versioning
- Homebrew Distribution
- Manual Releases
- Troubleshooting
Overview
lazycap follows a simple trunk-based development workflow:
- Development: Work on
devbranch or feature branches - Merge: Merge changes to
mainvia pull request - Release: GitHub Actions automatically creates a release
Every push to main that modifies Go source files triggers the release workflow, which:
- Analyzes commit messages to determine version bump type
- Creates and pushes a new version tag
- Builds binaries for all supported platforms using GoReleaser
- Creates a GitHub Release with assets and changelog
- Updates the Homebrew formula
Automatic Releases
The release workflow triggers on pushes to main that modify:
**.go(any Go source file)go.modorgo.sum.goreleaser.yaml.github/workflows/release.yml
No manual intervention is required for standard releases. Just merge your PR and the release happens automatically.
Version Bumping
The release workflow automatically determines the version bump based on commit messages since the last tag.
Priority Order
- Manual override (highest priority): Include
[major],[minor], or[patch]in any commit message - Breaking changes:
BREAKING CHANGEin commit body or!after type (e.g.,feat!:) - Features: Commits starting with
feat:orfeat(scope): - Default: Patch version bump
Examples
| Commit Message | Version Bump |
|---|---|
fix: correct device detection | Patch (0.0.X) |
docs: update README | Patch (0.0.X) |
feat: add Firebase plugin | Minor (0.X.0) |
feat(ui): new settings panel | Minor (0.X.0) |
fix!: change config format | Major (X.0.0) |
feat!: redesign plugin API | Major (X.0.0) |
refactor: cleanup [minor] | Minor (0.X.0) |
fix: bug fix [major] | Major (X.0.0) |
Forcing a Specific Version Bump
To force a specific version bump regardless of commit content, include one of these tags in your commit message:
# Force major version bump (1.2.3 -> 2.0.0)
git commit -m "refactor: major API changes [major]"
# Force minor version bump (1.2.3 -> 1.3.0)
git commit -m "chore: add new capability [minor]"
# Force patch version bump (1.2.3 -> 1.2.4)
git commit -m "feat: small addition [patch]"
Semantic Versioning
lazycap follows Semantic Versioning 2.0.0:
- MAJOR (X.0.0): Incompatible API changes, breaking changes for users
- MINOR (0.X.0): New features that are backward compatible
- PATCH (0.0.X): Bug fixes and minor improvements
When to Use Each
| Change Type | Version Bump |
|---|---|
| Breaking CLI changes | Major |
| Breaking plugin API changes | Major |
| Removed features | Major |
| New commands or flags | Minor |
| New plugins | Minor |
| New keyboard shortcuts | Minor |
| Bug fixes | Patch |
| Performance improvements | Patch |
| Documentation updates | Patch |
| Dependency updates | Patch |
Homebrew Distribution
lazycap is distributed via Homebrew using a tap in the same repository.
Installation
# Add the tap (one-time setup)
brew tap icarus-itcs/lazycap https://github.com/icarus-itcs/lazycap
# Install lazycap
brew install lazycap
Updating
# Update all taps and upgrade
brew update && brew upgrade lazycap
# Or force reinstall
brew reinstall lazycap
How It Works
The Homebrew formula (Formula/lazycap.rb) is automatically updated by the release workflow:
- Release workflow creates a new tag
- GoReleaser builds and publishes the release
- Workflow calculates SHA256 of the source tarball
- Formula is updated with new URL and SHA256
- Changes are committed to
main
Note: The formula update commit does not trigger another release because it only modifies the .rb file, not Go source files.
Limitations
Since the tap is in the main repository (not a separate homebrew-lazycap repo), users need to explicitly specify the full URL when adding the tap:
# This works
brew tap icarus-itcs/lazycap https://github.com/icarus-itcs/lazycap
# This does NOT work (expects homebrew-lazycap repo)
brew tap icarus-itcs/lazycap
Manual Releases
In rare cases, you may need to create a release manually.
Prerequisites
- Go 1.21+
- GoReleaser installed
GITHUB_TOKENenvironment variable set
Steps
-
Create and push a tag:
git tag -a v1.2.3 -m "Release v1.2.3" git push origin v1.2.3 -
Run GoReleaser locally (optional, workflow will handle it):
goreleaser release --clean -
Update Homebrew formula manually (if needed):
# Get SHA256 curl -sL https://github.com/icarus-itcs/lazycap/archive/refs/tags/v1.2.3.tar.gz | sha256sum # Update Formula/lazycap.rb with new url and sha256 # Commit and push
Dry Run
To test the release process without publishing:
goreleaser release --snapshot --clean
Troubleshooting
Release Not Triggered
Symptoms: Pushed to main but no release was created.
Solutions:
- Check if the commit modified Go source files (
**.go,go.mod,go.sum) - Check GitHub Actions for workflow errors
- Verify the tag doesn't already exist
Tag Already Exists
Symptoms: "Tag already exists, skipping release" in workflow logs.
Solution: This is expected behavior. If you need to re-release the same version:
- Delete the tag:
git push --delete origin v1.2.3 - Delete the GitHub release
- Push to
mainagain
GoReleaser Errors
Symptoms: GoReleaser step fails in workflow.
Solutions:
- Run
goreleaser checklocally to validate config - Check
.goreleaser.yamlsyntax - Ensure all build targets are valid
Homebrew Formula Issues
Symptoms: brew install fails or installs wrong version.
Solutions:
- Update the tap:
brew update - Check
Formula/lazycap.rbhas correct URL and SHA256 - Try reinstalling:
brew reinstall lazycap
Build Failures
Symptoms: Builds fail for specific platforms.
Solutions:
- Test locally:
GOOS=linux GOARCH=arm64 go build - Check for CGO dependencies (should be CGO_ENABLED=0)
- Verify ignore rules in
.goreleaser.yaml
Release Checklist
For maintainers preparing a release:
- All tests pass on
devbranch - Code reviewed and approved
- Commit messages follow conventional commits format
- Breaking changes documented in commit body with
BREAKING CHANGE: - Version bump type is appropriate for changes
- PR merged to
main - Release workflow completed successfully
- GitHub Release created with correct version
- Homebrew formula updated automatically
Questions?
If you have questions about the release process, please open an issue.