Skip to content

Latest commit

 

History

History
967 lines (699 loc) · 21.6 KB

File metadata and controls

967 lines (699 loc) · 21.6 KB

A.R.C. CLI - Complete Release Guide

Everything you need to know about releasing A.R.C. CLI

📚 Table of Contents


📋 Quick Reference

Release Commands Summary

# Local Testing
make release-check      # Validate GoReleaser config
make release-test       # Test build (current platform)
make release-build      # Build all platforms locally
make release-snapshot   # Full dry-run (no publish)

# Main Release (Stable)
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# → Creates stable release automatically

# Feature Release (Pre-release) - Specify Convention
git checkout -b 042-awesome-feature
git push origin 042-awesome-feature
# → Creates pre-release automatically

# Feature Release (Pre-release) - Legacy Convention
git checkout -b feature/awesome-feature
git push origin feature/awesome-feature
# → Creates pre-release automatically

# Beta/Alpha Release
git tag -a v1.0.0-beta1 -m "Beta 1"
git push origin v1.0.0-beta1
# → Creates pre-release automatically

🌿 Branch Naming Conventions

A.R.C. CLI supports two branch naming conventions:

1. Specify Convention (Recommended) ⭐

Format: ###-feature-name (3 digits, dash, name)

# Examples:
001-initial-setup
042-add-authentication
099-refactor-database
123-fix-memory-leak

Benefits:

  • ✅ Matches .specify workflow tooling
  • ✅ Easy to track feature progression
  • ✅ Multiple branches can work on same spec (e.g., 042-fix-bug, 042-add-tests)
  • ✅ Automatically organized in specs/ directory

When to use:

  • Following Spec-Driven Development workflow
  • Working with .specify tools
  • Need numbered feature tracking

2. Legacy Convention

Format: feature/* or feat/*

# Examples:
feature/add-authentication
feature/new-ui-dashboard
feat/optimize-queries
feat/add-logging

When to use:

  • Migrating from existing projects
  • Quick feature branches without spec tracking
  • Teams not using .specify workflow

Branch Patterns Recognized by CI/CD

The feature-release workflow triggers on:

branches:
  - '[0-9][0-9][0-9]-*'    # Specify convention: 001-feature
  - 'feature/**'            # Legacy: feature/name
  - 'feat/**'               # Legacy: feat/name

Choosing a Convention

Use Case Recommended Convention
New projects using .specify ###-feature-name
Existing projects feature/* or feat/*
Bug fixes in spec ###-fix-description
Experiments/prototypes feature/experiment-name

🚀 Release Workflows

A.R.C. CLI has two automated release workflows:

Workflow 1: Main Release (Stable Production)

File: .github/workflows/release.yml

Triggers

# Push any tag matching v*
git push origin v1.0.0
git push origin v0.5.2
git push origin v2.0.0-final  # Still works but not recommended

What Happens

  1. ✅ Checkout code with full git history
  2. ✅ Setup Go (version from go.mod)
  3. ✅ Run goreleaser release --clean
  4. ✅ Build binaries for 6 platforms:
  • Linux (amd64, arm64)
  • macOS (amd64/Intel, arm64/Apple Silicon)
  • Windows (amd64, arm64)
  1. ✅ Create official GitHub release
  2. ✅ Upload binaries with SHA256 checksums
  3. ✅ Auto-generate changelog from commits
  4. ✅ Mark as stable release (green checkmark)

Result

📦 Release: github.com/arc-framework/arc-cli/releases/tag/v1.0.0
✓ Status: Stable
📥 Downloads: 6 platform binaries + checksums.txt

Workflow 2: Feature Release (Pre-release/Testing)

File: .github/workflows/feature-release.yml

Triggers

A. Specify Convention Branches:

git push origin 001-initial-setup
git push origin 042-add-auth
git push origin 123-refactor-code

B. Legacy Convention Branches:

git push origin feature/new-dashboard
git push origin feat/api-endpoints

C. Pre-release Tags:

git push origin v1.0.0-beta1
git push origin v0.5.0-alpha3
git push origin v2.0.0-rc2

What Happens

  1. ✅ Checkout code with full git history
  2. ✅ Setup Go (version from go.mod)
  3. ✅ Run goreleaser release --snapshot --skip=publish
  4. ✅ Build snapshot binaries (no version tag required)
  5. ✅ Create pre-release with auto-generated tag:
  • Branch: feature-042-add-auth-abc1234567
  • Tag: feature-v1.0.0-beta1-abc1234567
  1. ✅ Upload binaries with checksums
  2. ⚠️ Mark as pre-release (yellow badge)

Result

📦 Release: github.com/arc-framework/arc-cli/releases/tag/feature-042-add-auth-abc1234567
⚠️ Status: Pre-release
📥 Downloads: 6 platform binaries + checksums.txt
💬 Note: Includes installation instructions

📊 Workflow Comparison

Aspect Main Release Feature Release
Trigger v* tags (e.g., v1.0.0) ###-*, feature/**, feat/** branches or v*-beta/alpha/rc tags
Command goreleaser release --clean goreleaser release --snapshot --skip=publish
Version From git tag (v1.0.0) Snapshot (no version injection)
Release Tag v1.0.0 feature-{branch}-{sha}
Status Stable ✓ Pre-release ⚠️
Changelog Full, auto-generated, grouped Commit message only
Audience Production users Testers, developers, early adopters
Permanence Keep forever (version history) Clean up after merge
Platform Binaries 6 (all OS/arch) 6 (all OS/arch)

🎬 Example Scenarios

Scenario 1: Regular Development (No Release)

git checkout main
git add .
git commit -m "Fix typo in documentation"
git push origin main

# Result: No workflow triggered ✓

Scenario 2: Test Feature (Specify Convention)

# Create numbered feature branch
git checkout -b 042-add-authentication
# ... make changes ...
git add .
git commit -m "Add OAuth2 authentication"
git push origin 042-add-authentication

# Result:
# ✓ feature-release.yml triggers
# ✓ Creates: feature-042-add-authentication-abc1234567 (pre-release)
# ✓ Share with testers for feedback

Scenario 3: Test Feature (Legacy Convention)

# Create legacy feature branch
git checkout -b feature/new-dashboard
# ... make changes ...
git push origin feature/new-dashboard

# Result:
# ✓ feature-release.yml triggers
# ✓ Creates: feature-feature/new-dashboard-abc1234567 (pre-release)

Scenario 4: Beta Release

git tag -a v2.0.0-beta1 -m "First beta for v2.0.0"
git push origin v2.0.0-beta1

# Result:
# ✓ feature-release.yml triggers
# ✓ Creates: feature-v2.0.0-beta1-abc1234567 (pre-release)
# ✓ Early adopters can test

Scenario 5: Official Stable Release

git tag -a v2.0.0 -m "Official v2.0.0 release"
git push origin v2.0.0

# Result:
# ✓ release.yml triggers
# ✓ Creates: v2.0.0 (stable)
# ✓ Production users download

🔧 GoReleaser Configuration

Overview

File: .goreleaser.yaml

Both workflows use the same GoReleaser configuration:

  • Main Release: Full release mode
  • Feature Release: Snapshot mode (--snapshot --skip=publish)

Key Configuration Sections

Build Configuration

builds:
  - main: ./cmd/arc/main.go        # Entry point
    binary: arc                      # Output binary name
    env:
      - CGO_ENABLED=0               # Static binaries (no C deps)
    goos: [linux, windows, darwin]
    goarch: [amd64, arm64]

Version Injection

ldflags:
  - -s -w  # Strip debug info
  - -X github.com/arc-framework/arc-cli/internal/version.Version={{.Version}}
  - -X github.com/arc-framework/arc-cli/internal/version.GitCommit={{.Commit}}
  - -X github.com/arc-framework/arc-cli/internal/version.BuildDate={{.Date}}

Injects into internal/version/version.go:

  • Version: Git tag (e.g., v1.0.0)
  • GitCommit: Full commit hash
  • BuildDate: Build timestamp

Archives

archives:
  - name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
    formats: [tar.gz, zip]
    files:
      - LICENSE
      - README.md
      - docs/**/*

Output Example: arc_v1.0.0_Darwin_x86_64.tar.gz

Changelog

changelog:
  groups:
    - title: 'New Features'
      regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
    - title: 'Bug Fixes'
      regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'

Auto-generates grouped changelog from conventional commits.

Installation of GoReleaser

# macOS
brew install goreleaser

# Linux (snap)
sudo snap install --classic goreleaser

# Go install
go install github.com/goreleaser/goreleaser/v2@latest

Validate Configuration

# Check if .goreleaser.yaml is valid
goreleaser check

# Or using make
make release-check

📝 Step-by-Step Guides

Guide 1: Create Your First Feature Release

# Step 1: Create feature branch (Specify convention)
git checkout -b 001-my-first-feature

# Step 2: Make your changes
echo "new feature" > feature.txt
git add feature.txt
git commit -m "feat: add my first feature"

# Step 3: Push to trigger release
git push origin 001-my-first-feature

# Step 4: Wait ~2-5 minutes for GitHub Actions

# Step 5: Check the release
# Visit: https://github.com/arc-framework/arc-cli/releases
# You'll see: feature-001-my-first-feature-{sha} (pre-release)

# Step 6: Download and test
curl -sfL https://github.com/arc-framework/arc-cli/releases/download/feature-001-my-first-feature-{sha}/arc_*_Darwin_arm64.tar.gz | tar xz
./arc --version

# Step 7: Clean up after merge
git checkout main
git merge 001-my-first-feature
git push origin main
git push origin --delete 001-my-first-feature
# Manually delete the pre-release on GitHub

Guide 2: Create Your First Stable Release

# Step 1: Ensure you're on main and up-to-date
git checkout main
git pull origin main

# Step 2: Run pre-release checks
make test                   # All tests pass
make fmt                    # Code is formatted
make vet                    # No vet warnings
make release-check          # GoReleaser config valid

# Step 3: Test build locally (optional)
make release-snapshot

# Step 4: Create the version tag
git tag -a v0.1.0 -m "Initial release

Features:
- CLI framework with Cobra
- Beautiful UI with lipgloss
- Theming system
- Version command
"

# Step 5: Push the tag
git push origin v0.1.0

# Step 6: Monitor GitHub Actions
# Visit: https://github.com/arc-framework/arc-cli/actions
# Wait for "Release" workflow to complete

# Step 7: Verify the release
# Visit: https://github.com/arc-framework/arc-cli/releases/tag/v0.1.0
# Download and test the binaries

# Step 8: Test installation
curl -sfL https://github.com/arc-framework/arc-cli/releases/download/v0.1.0/arc_0.1.0_Darwin_arm64.tar.gz | tar xz
./arc --version
# Should output: A.R.C. CLI 0.1.0 (built 2025-12-19, commit abc123...)

Guide 3: Create a Beta Release

# Step 1: Prepare beta code on main
git checkout main
# ... make changes ...
git commit -m "feat: prepare v1.0.0 beta"
git push origin main

# Step 2: Create beta tag
git tag -a v1.0.0-beta1 -m "Beta 1 for v1.0.0

Testing:
- New authentication system
- Updated UI theme
- Performance improvements
"

# Step 3: Push beta tag
git push origin v1.0.0-beta1

# Step 4: GitHub Actions creates pre-release
# Tag: feature-v1.0.0-beta1-{sha}
# Status: Pre-release

# Step 5: Share with testers
# Send them: https://github.com/arc-framework/arc-cli/releases

# Step 6: After testing, create stable release
git tag -a v1.0.0 -m "Official v1.0.0 release"
git push origin v1.0.0

🛠️ Local Testing

Test builds locally without creating releases:

Quick Test (Current Platform)

make release-test

# Or manually:
goreleaser build --snapshot --clean --single-target

# Output: dist/{platform}/arc

Build All Platforms

make release-build

# Or manually:
goreleaser build --snapshot --clean

# Output: dist/{linux,darwin,windows}_{amd64,arm64}/arc

Full Release Simulation

make release-snapshot

# Or manually:
goreleaser release --snapshot --clean --skip=publish

# Output: Complete dist/ structure with archives and checksums

Test Version Injection

# Build with version
make build-release

# Check version
./arc --version
# Should show: A.R.C. CLI 0.0.1 (built 2025-12-19, commit abc123)

🔍 Finding Releases

GitHub Web Interface

All releases:     https://github.com/arc-framework/arc-cli/releases
Latest stable:    https://github.com/arc-framework/arc-cli/releases/latest
Specific version: https://github.com/arc-framework/arc-cli/releases/tag/v1.0.0
Pre-releases:     (look for yellow "Pre-release" badge)

GitHub CLI

# List all releases
gh release list

# View latest release
gh release view

# View specific release
gh release view v1.0.0

# Download latest stable
gh release download

# Download specific version
gh release download v1.0.0

# Download pre-release
gh release download feature-042-add-auth-abc1234567

Using cURL

# Latest stable (auto-redirects)
curl -sfL https://github.com/arc-framework/arc-cli/releases/latest/download/arc_*_Darwin_arm64.tar.gz | tar xz

# Specific version
curl -sfL https://github.com/arc-framework/arc-cli/releases/download/v1.0.0/arc_1.0.0_Darwin_arm64.tar.gz | tar xz

# Pre-release (need full tag)
curl -sfL https://github.com/arc-framework/arc-cli/releases/download/feature-042-auth-abc123/arc_*_Darwin_arm64.tar.gz | tar xz

🧹 Cleanup & Maintenance

Delete Old Feature Releases

# List all releases
gh release list

# Delete specific pre-release
gh release delete feature-001-old-feature-abc123

# Delete with tag
git push origin --delete feature-001-old-feature-abc123

# Or via GitHub web interface:
# Releases → Click pre-release → Delete release

Keep Stable Releases

Never delete stable releases (v1.0.0, v2.0.0, etc.) - these are your version history.

Cleanup After Branch Merge

# After merging feature branch to main
git checkout main
git merge 001-add-feature
git push origin main

# Delete the branch
git branch -d 001-add-feature
git push origin --delete 001-add-feature

# Delete the pre-release manually on GitHub
# The tag will remain until manually deleted

🐛 Troubleshooting

Issue: GoReleaser Not Found

Symptom:

goreleaser: command not found

Solution:

# macOS
brew install goreleaser

# Linux
sudo snap install --classic goreleaser

# Go install
go install github.com/goreleaser/goreleaser/v2@latest

Issue: Feature Release Not Triggering

Symptom: Pushed feature branch but no release created

Check:

  1. Branch name matches pattern?

    # Should match one of:
    001-feature-name          # Specify convention ✓
    feature/feature-name      # Legacy ✓
    feat/feature-name         # Legacy ✓
    my-branch                 # ✗ Won't trigger
  2. Workflow file exists?

    ls -la .github/workflows/feature-release.yml
  3. Check GitHub Actions tab:

    https://github.com/arc-framework/arc-cli/actions
    
  4. Workflow enabled?

  • Go to Settings → Actions → General
  • Ensure "Allow all actions" is selected

Issue: Main Release Failing

Symptom:

git doesn't contain any tags - either add a tag or use --snapshot

Solution: Tag must start with v:

# ✗ Wrong
git tag 1.0.0
git tag release-1.0.0

# ✓ Correct
git tag v1.0.0
git tag v0.1.0

Issue: "dirty working directory"

Symptom:

error: dirty working directory

Solution: Commit all changes before tagging:

git status
git add .
git commit -m "prepare release"
git tag v1.0.0
git push origin v1.0.0

Issue: GITHUB_TOKEN Not Set (Local)

Symptom:

GITHUB_TOKEN environment variable not set

Solution:

# Create token: https://github.com/settings/tokens
# Scopes needed: repo, write:packages

export GITHUB_TOKEN="ghp_your_token_here"
goreleaser release --clean

Note: GitHub Actions automatically provides GITHUB_TOKEN - no setup needed.


Issue: Version Not Showing in Binary

Symptom:

./arc --version
# Output: A.R.C. CLI 0.0.1-dev (built 2025-12-19, commit )

Causes:

  1. Built with go build instead of GoReleaser
  2. ldflags paths are wrong

Solution:

# Use GoReleaser or make
make release-test

# Or use build-release target
make build-release

# Check version
./arc --version
# Should show commit hash now

Issue: GoReleaser Config Invalid

Symptom:

configuration is invalid

Solution:

# Validate config
goreleaser check

# Common issues:
# 1. YAML indentation
# 2. Deprecated fields
# 3. Invalid template syntax

# Fix and re-validate
vim .goreleaser.yaml
goreleaser check

Issue: Build Fails for Specific Platform

Symptom:

build for darwin/arm64 failed

Solution:

  1. Check ignore patterns:

    # In .goreleaser.yaml
    ignore:
      - goos: darwin
        goarch: "386"  # Correct
  2. Test locally:

    GOOS=darwin GOARCH=arm64 go build ./cmd/arc
  3. Check dependencies:

    go mod tidy
    go mod verify

📚 Best Practices

For Stable Releases

  1. Test thoroughly before tagging
  2. Follow Semantic Versioning:
  • v1.0.0 - Major (breaking changes)
  • v0.1.0 - Minor (new features)
  • v0.0.1 - Patch (bug fixes)
  1. Use descriptive tag messages:
    git tag -a v1.0.0 -m "Release v1.0.0
    
    Features:
    - Add authentication system
    - Improve performance by 50%
    
    Breaking Changes:
    - Renamed config file from .arc to arc.yaml
    
    Bug Fixes:
    - Fixed memory leak in worker pool
    "
  2. Test binaries after release
  3. Update documentation if needed
  4. Announce the release (blog, Twitter, etc.)

For Feature Releases

  1. Use for testing and feedback only
  2. Use Specify convention (###-name) for better tracking
  3. Clean up old pre-releases after merge
  4. Include clear descriptions in commit messages
  5. ⚠️ Don't use in production
  6. Share download links with testers
  7. Document known issues in release notes

For Branch Naming

  1. Specify convention for spec-driven features: 042-add-auth
  2. Legacy convention for quick features: feature/quick-fix
  3. Be descriptive: 042-add-oauth2-authentication not 042-stuff
  4. Use lowercase and hyphens: feature/add-new-ui not feature/Add_New_UI
  5. Keep it short but meaningful

🎯 Quick Decision Tree

Do you want to release?
│
├─ YES → Is it production-ready?
│   │
│   ├─ YES → Create stable release
│   │        git tag -a v1.0.0 -m "Release"
│   │        git push origin v1.0.0
│   │
│   └─ NO → Need testing?
│       │
│       ├─ Public beta → Create beta tag
│       │               git tag -a v1.0.0-beta1 -m "Beta"
│       │               git push origin v1.0.0-beta1
│       │
│       └─ Internal test → Push feature branch
│                          git push origin 042-feature
│
└─ NO → Just developing?
         git push origin main
         (no release created)

📊 Summary Table

Want to... Do this... Result
Develop normally git push origin main No release
Test a feature (Specify) git push origin 042-feature Pre-release
Test a feature (Legacy) git push origin feature/name Pre-release
Beta release git push origin v1.0.0-beta1 Pre-release
Stable release git push origin v1.0.0 Stable release
Build locally make release-test Local binary
Validate config make release-check Check only

🎓 Additional Resources


✅ Pre-Release Checklist

Before creating a stable release:

  • All tests pass (make test)
  • Code is formatted (make fmt)
  • No vet warnings (make vet)
  • GoReleaser config valid (make release-check)
  • Version number follows semantic versioning
  • Changelog/release notes prepared
  • Documentation updated
  • Local build test successful (make release-snapshot)
  • Tag message is descriptive
  • Ready to announce

Happy Releasing! 🎉

Last Updated: December 27, 2025