A.R.C. CLI uses automated code quality checks both locally (pre-commit hooks) and in CI/CD (GitHub Actions) to ensure consistent, high-quality code.
# Run the setup script (installs pre-commit hooks)
make setup
# Or manually
./scripts/setup-dev.shThis will:
- ✅ Install pre-commit hook
- ✅ Install golangci-lint (if needed)
- ✅ Download Go dependencies
- ✅ Run initial tests
# Before committing, run:
make pre-commit
# Or run individual checks:
make fmt # Format code
make vet # Run go vet
make lint # Run linter
make test # Run testsThe pre-commit hook runs automatically before every commit and checks:
- ✅ Code formatting (gofmt)
- ✅ Go vet (static analysis)
- ✅ Tests (only for changed files)
# Automatic (recommended)
make setup
# Manual
cp scripts/pre-commit.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit# When you commit:
git commit -m "Add feature"
# The hook runs automatically:
🔍 Running pre-commit checks...
→ Checking code formatting...
✓ Format check passed
→ Running go vet...
✓ Go vet passed
→ Running tests...
✓ Tests passed
✅ All pre-commit checks passed!
# Commit succeeds!# Example: Code not formatted
git commit -m "Add feature"
🔍 Running pre-commit checks...
→ Checking code formatting...
❌ Code is not formatted. Run 'make fmt' or 'gofmt -s -w .'
Files that need formatting:
pkg/cli/root.go
cmd/arc/main.go
Auto-fixing? (y/n)Options:
- Type
y→ Auto-formats code, you need to re-commit - Type
n→ Aborts commit, fix manually withmake fmt
# Skip pre-commit checks (use sparingly!)
git commit --no-verify -m "WIP: emergency fix"Triggers:
- Push to
mainbranch - Pull requests to
main
What It Does:
1. ✅ Format check (gofmt)
2. ✅ Go vet
3. ✅ Lint (golangci-lint)
4. ✅ Tests with race detector
5. ✅ Upload code coverage (Codecov)
6. ✅ Build binary
Purpose: Ensures all code merged to main is high quality
Triggers:
- Push tags matching
v*(e.g.,v1.0.0)
What It Does:
Validation Job:
1. ✅ Format check
2. ✅ Go vet
3. ✅ Lint
4. ✅ Tests
Release Job (only if validation passes):
5. ✅ Build with GoReleaser
6. ✅ Create GitHub release
Purpose: Guarantees all releases pass quality checks
Triggers:
- Push to feature branches (
001-*,feature/*,feat/*)
What It Does:
1. ✅ Build with GoReleaser (no validation)
2. ✅ Create pre-release
Purpose: Quick feedback for testing (validation happens in CI on PRs)
# Development
make build # Build the binary
make run # Run without building
make test # Run all tests
make fmt # Format all code
make vet # Run go vet
make lint # Run golangci-lint
make pre-commit # Run all checks
make setup # Setup dev environment
# Release
make release-check # Validate GoReleaser config
make release-test # Test build locally# Format code
gofmt -s -w .
# Run tests
go test ./...
go test -v -race ./... # With race detector
go test -cover ./... # With coverage
# Run linter
golangci-lint run ./...
# Run specific linter
golangci-lint run --disable-all -E errcheck ./...Enabled Linters:
errcheck- Check for unchecked errorsgosimple- Simplify codegovet- Static analysisineffassign- Detect ineffectual assignmentsstaticcheck- Advanced static analysisunused- Find unused codegofmt- Formattinggoimports- Import formattingmisspell- Spell checkinggoconst- Find repeated stringsgosec- Security issues- And more...
Configuration:
run:
timeout: 5m
go: '{{ .GoVersion }}'
linters-settings:
lll:
line-length: 120 # Max line length
goconst:
min-occurrences: 3 # Repeated strings thresholdEdit .golangci.yml to:
- Enable/disable linters
- Adjust settings
- Exclude specific files/directories
# Example: Disable a linter
linters:
disable:
- gosec # Disable security checks1. Developer creates PR
↓
2. CI workflow runs automatically
✅ Format check
✅ Go vet
✅ Lint
✅ Tests
↓
3. If all pass → PR can be merged
If any fail → Developer must fix
↓
4. Merge to main
1. Developer tags version
git tag -a v1.0.0 -m "Release"
git push origin v1.0.0
↓
2. Release workflow triggers
↓
3. Validation job runs
✅ Format check
✅ Go vet
✅ Lint
✅ Tests
↓
4. If validation passes → Release job runs
✅ Build with GoReleaser
✅ Create GitHub release
5. If validation fails → Release aborted
❌ Fix issues and re-tag
# Check if installed
ls -la .git/hooks/pre-commit
# If missing, install:
make setup# Install
brew install golangci-lint
# Or use Go:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest# Run tests with race detector (like CI does)
go test -v -race ./...
# Check Go version matches CI
go version # Should be 1.24# Auto-fix formatting
make fmt
# Or manually
gofmt -s -w .
# Verify
gofmt -s -l . # Should output nothing- ✅ Run
make pre-committo catch issues early - ✅ Write tests for new code
- ✅ Update documentation if needed
- ✅ Use descriptive commit messages that follow the Conventional Commits specification.
- ✅ Ensure CI passes on your branch
- ✅ Review your own changes
- ✅ Write a clear and descriptive PR title and description. The description should explain the "why" behind the changes, not just the "what".
- ✅ Update CHANGELOG if applicable
- ✅ Link related issues
- ✅ Merge all PRs
- ✅ Ensure CI is green on main
- ✅ Update version in relevant files
- ✅ Create annotated tag with message
.github/workflows/
├── ci.yml # CI checks on PRs and main
├── release.yml # Validation + release on tags
└── feature-release.yml # Pre-releases on feature branches
scripts/
├── pre-commit.sh # Pre-commit hook script
└── setup-dev.sh # Development setup script
.golangci.yml # Linter configuration
Makefile # Common commands
| Command | When to Use |
|---|---|
make setup |
Once after cloning |
make pre-commit |
Before committing |
make fmt |
Fix formatting |
make test |
Run tests |
make lint |
Check code quality |
make build |
Build binary |
Questions or issues? Open an issue on GitHub!