Release Process
This document describes the release process for Pass-CLI using GoReleaser.
Prerequisites
- GoReleaser installed:
go install github.com/goreleaser/goreleaser/v2@latest - Git tags: Releases are triggered by pushing git tags
- GitHub token: Required for GitHub releases (set
GITHUB_TOKENenv var) - Clean working directory: No uncommitted changes
Local Testing
Build for Current Platform
# Test build for your current platform
goreleaser build --snapshot --clean --single-target
# Check the binary
./dist/pass-cli_<platform>/pass-cli versionBuild All Platforms
# Test full multi-platform build without publishing
goreleaser build --snapshot --clean
# Verify all binaries were created
ls -lh dist/Full Release Dry Run
# Simulate a complete release (no publishing)
goreleaser release --snapshot --clean --skip=publishRelease Process
1. Prepare Release
# Ensure you're on main and up-to-date
git checkout main
git pull origin main
# Run all tests
go test ./...
go test -v -tags=integration -timeout 5m ./test
# Run code quality checks
go fmt ./...
go vet ./...
golangci-lint run2. Create Release Tag
Note: Version numbers and dates in documentation are automatically updated by GitHub Actions when you push a tag. You don’t need to manually update them.
The update-docs-version.yml workflow automatically updates:
- Documentation version footers (8 files in
docs/) - “Last Updated” dates to current month/year
- Package manifest versions (homebrew/pass-cli.rb, scoop/pass-cli.json)
What you need to do manually:
- Update CHANGELOG.md with release notes (if you maintain one)
# Create and push a version tag
git tag -a v0.0.1 -m "Release v0.0.1"
git push origin v0.0.13. Run GoReleaser
# Release to GitHub
export GITHUB_TOKEN="your-github-token"
goreleaser release --clean
# Or use goreleaser with GitHub Actions (recommended)
# Push the tag and let CI handle the releaseConfiguration
Version Injection
GoReleaser injects version information at build time via ldflags:
ldflags:
- -s -w # Strip debug info (reduces binary size)
- -X pass-cli/cmd.version={{.Version}}
- -X pass-cli/cmd.commit={{.ShortCommit}}
- -X pass-cli/cmd.date={{.Date}}Supported Platforms
- Windows: amd64, arm64
- macOS: amd64, arm64 (with universal binary)
- Linux: amd64, arm64
Build Flags
-trimpath: Remove file system paths from binaries-mod=readonly: Ensure go.mod is not modifiedCGO_ENABLED=0: Static linking (no C dependencies)netgotag: Pure Go networking stack
Artifacts Generated
For each release, GoReleaser creates:
- Binaries: Cross-compiled for all platforms
- Archives:
.tar.gzfor Unix,.zipfor Windows - Checksums: SHA-256 checksums for verification
- SBOMs: Software Bill of Materials (security compliance)
- Release notes: Auto-generated from commits
Versioning
Pass-CLI follows Semantic Versioning:
- MAJOR (v1.0.0): Incompatible API changes
- MINOR (v0.1.0): New features (backward compatible)
- PATCH (v0.0.2): Bug fixes (backward compatible)
Current Release: v0.0.1 (Initial release)
GitHub Actions Integration
Example .github/workflows/release.yml:
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: '1.25.1'
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Binary Sizes
Typical binary sizes (with -s -w flags):
- Windows amd64: ~6.2 MB
- macOS arm64: ~6.0 MB
- Linux amd64: ~6.1 MB
All well under the 20MB target.
Verification
Verify Checksums
# Download checksums.txt and verify
sha256sum -c checksums.txtTest Binaries
# Download and test each platform binary
./pass-cli-linux-amd64 version
./pass-cli-darwin-arm64 version
./pass-cli-windows-amd64.exe versionTroubleshooting
“dirty” Git State
# GoReleaser requires clean working directory
git status
git stash # or commit changesMissing GitHub Token
# Set GitHub token for releases
export GITHUB_TOKEN=$(gh auth token)
# Or create a personal access token:
# https://github.com/settings/tokensBuild Failures
# Check individual platform builds
GOOS=linux GOARCH=amd64 go build .
GOOS=darwin GOARCH=arm64 go build .
GOOS=windows GOARCH=amd64 go build .Archive Issues
# Ensure required files exist
ls LICENSE README.md CHANGELOG.md
# Or adjust archives.files in .goreleaser.ymlBest Practices
- Test before tagging: Always run full test suite and quality checks
- Use semantic versioning: Follow semver strictly
- Write good commit messages: They become release notes
- Keep CHANGELOG updated: Manual changelog alongside auto-generated notes
- Test binaries: Download and test at least one binary per platform
- Sign releases: Consider adding GPG signing for security
- Document breaking changes: Clearly mark in release notes
Advanced Features
Universal macOS Binaries
GoReleaser automatically creates universal binaries for macOS that work on both Intel and Apple Silicon:
universal_binaries:
- id: pass-cli-darwin
replace: true
name_template: "pass-cli"Custom Release Notes
Override auto-generated notes by creating .goreleaser.yml:
release:
header: |
## Custom Header
footer: |
## Custom FooterMultiple Archives
Create different archives for different audiences:
archives:
- id: default
# Standard archives
- id: minimal
# Minimal archives (binary only)
files: []