Skip to content

Latest commit

 

History

History
415 lines (299 loc) · 7.63 KB

File metadata and controls

415 lines (299 loc) · 7.63 KB

Code Quality & Development Setup

Overview

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.

Quick Start

One-Time Setup

# Run the setup script (installs pre-commit hooks)
make setup

# Or manually
./scripts/setup-dev.sh

This will:

  • ✅ Install pre-commit hook
  • ✅ Install golangci-lint (if needed)
  • ✅ Download Go dependencies
  • ✅ Run initial tests

Daily Development

# 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 tests

Local Enforcement (Pre-Commit Hook)

What It Does

The pre-commit hook runs automatically before every commit and checks:

  1. Code formatting (gofmt)
  2. Go vet (static analysis)
  3. Tests (only for changed files)

Installation

# Automatic (recommended)
make setup

# Manual
cp scripts/pre-commit.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

Behavior

# 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!

If Checks Fail

# 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 with make fmt

Bypassing (Not Recommended)

# Skip pre-commit checks (use sparingly!)
git commit --no-verify -m "WIP: emergency fix"

CI/CD Workflows

1. CI Workflow (.github/workflows/ci.yml)

Triggers:

  • Push to main branch
  • 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

2. Release Workflow (.github/workflows/release.yml)

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

3. Feature Release Workflow

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)


Available Commands

Make Targets

# 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

Manual Commands

# 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 ./...

Linting Configuration

File: .golangci.yml

Enabled Linters:

  • errcheck - Check for unchecked errors
  • gosimple - Simplify code
  • govet - Static analysis
  • ineffassign - Detect ineffectual assignments
  • staticcheck - Advanced static analysis
  • unused - Find unused code
  • gofmt - Formatting
  • goimports - Import formatting
  • misspell - Spell checking
  • goconst - Find repeated strings
  • gosec - 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 threshold

Customizing

Edit .golangci.yml to:

  • Enable/disable linters
  • Adjust settings
  • Exclude specific files/directories
# Example: Disable a linter
linters:
  disable:
    - gosec  # Disable security checks

Workflow Integration

Pull Request Flow

1. 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

Release Flow

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

Troubleshooting

Pre-commit hook not running

# Check if installed
ls -la .git/hooks/pre-commit

# If missing, install:
make setup

golangci-lint not found

# Install
brew install golangci-lint

# Or use Go:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

Tests failing in CI but passing locally

# Run tests with race detector (like CI does)
go test -v -race ./...

# Check Go version matches CI
go version  # Should be 1.24

Format check failing

# Auto-fix formatting
make fmt

# Or manually
gofmt -s -w .

# Verify
gofmt -s -l .  # Should output nothing

Best Practices

Before Committing

  1. ✅ Run make pre-commit to catch issues early
  2. ✅ Write tests for new code
  3. ✅ Update documentation if needed
  4. ✅ Use descriptive commit messages that follow the Conventional Commits specification.

Before Creating PR

  1. ✅ Ensure CI passes on your branch
  2. ✅ Review your own changes
  3. ✅ Write a clear and descriptive PR title and description. The description should explain the "why" behind the changes, not just the "what".
  4. ✅ Update CHANGELOG if applicable
  5. ✅ Link related issues

Before Releasing

  1. ✅ Merge all PRs
  2. ✅ Ensure CI is green on main
  3. ✅ Update version in relevant files
  4. ✅ Create annotated tag with message

Files Overview

.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

Quick Reference

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!