Slim, Production-Ready Go Template
Enterprise CI/CD, DevSecOps, clean architecture. Optimized for CLI tools and API servers.
A minimal, reusable GitHub template for building production-ready Go applications. Supports both CLI single-binary projects and API servers with zero bloat.
What you get:
- β Clean architecture (Domain/Usecase/Adapter layers)
- β CLI foundation (Cobra framework, ready for commands)
- β Structured logging (slog)
- β Configuration management
- β Comprehensive testing (unit, integration)
- β DevSecOps (gosec, govulncheck, CodeQL)
- β GitHub Actions CI/CD (linting, testing, releases)
- β Docker & multi-platform builds
- β DevContainer with pre-configured tools
- β Kubernetes & Terraform examples
What you don't get (keep it slim!):
- No bloated feature flag systems
- No unused HTTP/health endpoints (add only if needed)
- No example commands cluttering production code (we include one example to remove)
- No over-engineered abstractions
# Create a new repo from this template
gh repo create my-app --template go-template
# Setup
cd my-app
make dev-setup
# Build & run
make build
./bin/go-template hello --name "World"The template includes an example command in internal/cli/hello.go (via NewExampleCommand). Replace it with your own:
1. Create your command:
// internal/cli/mycommand.go
package cli
import (
"github.com/spf13/cobra"
"github.com/PlatformStackPulse/go-template/internal/logger"
)
func NewMyCommand(log *logger.Logger) *cobra.Command {
return &cobra.Command{
Use: "mycommand",
Short: "What my command does",
Long: "Detailed description of what my command does",
RunE: func(cmd *cobra.Command, args []string) error {
log.Info("Running mycommand")
// Your logic here
return nil
},
}
}2. Register in main.go:
// cmd/app/main.go
cmd.AddCommand(cli.NewMyCommand(log))3. Remove the example command:
rm internal/cli/hello.go
# Update cmd/app/main.go - remove the cli.NewExampleCommand linego-template/
βββ cmd/app/
β βββ main.go # Entry point (minimal, ~30 lines)
βββ internal/ # Private packages
β βββ cli/ # Cobra commands
β β βββ root.go # Root command
β β βββ hello.go # Example command (remove/rename)
β βββ config/ # Configuration loading
β βββ domain/ # Domain entities
β βββ logger/ # Structured logging (slog)
β βββ usecase/ # Business logic
β βββ adapter/ # External integrations (add as needed)
βββ pkg/
β βββ version/ # Version info (injected at build)
βββ test/
β βββ unit/ # Unit tests
β βββ integration/ # Integration tests (if needed)
βββ deploy/
β βββ kubernetes/ # K8s manifests (optional)
β βββ terraform/ # IaC (optional)
βββ Makefile # Core build targets
βββ Dockerfile # Multi-stage build
βββ go.mod / go.sum # Dependencies
βββ .github/workflows/ # GitHub Actions (6 workflows)
Your main.go stays slim:
func main() {
cfg := config.Load()
log := logger.NewLogger(cfg.Debug)
cmd := cli.NewRootCommand(log)
cmd.Version = version.Version
if err := cmd.ExecuteContext(context.Background()); err != nil {
os.Exit(1)
}
}Add your commands to internal/cli/ and register them in cmd/app/main.go.
Extend main.go with HTTP:
func main() {
cfg := config.Load()
log := logger.NewLogger(cfg.Debug)
// Create HTTP server
srv := &http.Server{
Addr: ":8080",
Handler: setupRoutes(log),
}
// Run with graceful shutdown
// (add your HTTP handler logic)
}Optional: Add files as needed:
internal/http/server.goβ HTTP server setupinternal/http/handlers.goβ Route handlerspkg/health/β Health check endpoints
Clean layers with clear separation:
CLI/HTTP Layer (User interaction)
β
Usecases (Business logic)
β
Domain (Entities, rules)
β
Adapters (External services)
Each layer is independent and testable.
- Slim β Only essential structure, no bloat
- Extensible β Easy to add features without refactoring
- Example-first β Rename/remove example command, add yours
- Test-friendly β Proper layering makes testing straightforward
- Single responsibility β Each package does ONE thing well
make dev-setup # Install tools
make build # Build binary
make test # Run tests
make coverage # Coverage report
make fmt # Format code
make lint # Lint check
make security # Security scan
make docker-build # Build Docker imageSee Makefile for all targets.
When using this template:
- Update
go.modmodule name - Rename
go-templatebinary inMakefileandREADME.md - Remove/rename
internal/cli/hello.goexample command - Update repository references in documentation
- Add your commands to
internal/cli/ - Update tests in
test/unit/
make build # Build locally
make release # Build all platforms (macOS/Linux/Windows)
make docker-build # Build Docker image# Already configured in Dockerfile (multi-stage build)
docker build -t my-app .
docker run my-app hello --name "Docker"kubectl apply -f deploy/kubernetes/See deploy/kubernetes/ for manifests.
cd deploy/terraform
terraform init
terraform plan -var-file=terraform.dev.tfvars# All tests
make test
# With coverage
make coverage
# Specific package
go test ./internal/usecase/...
# Race detection
go test -race ./...- Integrated security scanning (gosec, govulncheck, CodeQL)
- Vulnerability notifications via Dependabot
- Branch protection on main
- Commit signing support
See SECURITY.md for details.
- CONTRIBUTING.md β How to contribute
- SECURITY.md β Security policy
- WORKFLOW.md β Git workflow & branch protection
- Makefile β Build targets (run
make help)
MIT License β See LICENSE
Ready to build? Fork this template and start coding! π
- Command Pattern β Cobra commands
- Mediator Pattern β Feature manager
- Orchestrator Pattern β Usecase layer
- Dependency Injection β Idiomatic Go
make help # Show all available targets
make build # Build the application
make run # Build and run
make test # Run all tests with coverage
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make coverage # Generate coverage report
make clean # Remove build artifacts
make install # Install dependencies
make lint # Run linters
make fmt # Format code
make vet # Run go vet
make security # Run security checks
make sec-update # Check for security updates
make dev-setup # Setup development environment
make changelog # Regenerate CHANGELOG.md from commits
make changelog-check # Verify CHANGELOG.md is current
make watch # Watch for changes (air)
make version # Show version info
make all # Run all tasks./bin/go-template --help
./bin/go-template hello # Print "Hello, World!"
./bin/go-template hello --name Alice # Print "Hello, Alice!"
./bin/go-template version # Show version information# All tests with coverage
make test
# Specific test suite
make test-unit
make test-integration
# Generate HTML coverage report
make coverage
# Run with race detector
go test -race ./...- Minimum threshold: 70%
- Enforced in CI: Yes
- Table-driven tests: Domain and usecase layers
- Mock patterns: Via interfaces
| Tool | Purpose | Status |
|---|---|---|
golangci-lint |
Code quality & style | β CI/CD |
gosec |
Security issues | β CI/CD |
govulncheck |
Dependency vulnerabilities | β CI/CD |
CodeQL |
Static analysis | β CI/CD |
Dependabot |
Dependency updates | β Automated |
# Run all security scans
make security
# Check for vulnerabilities
make sec-update
# Manual gosec scan
gosec ./...
# Manual govulncheck
govulncheck ./...This project follows Semantic Versioning:
MAJOR.MINOR.PATCH
β β β
β β ββ Bug fixes
β βββββββββββ New features (backward compatible)
ββββββββββββββββββ Breaking changes
Commit messages must follow the Conventional Commits specification:
<type>(<scope>): <description>
<body>
<footer>
Types:
featβ New featurefixβ Bug fixdocsβ Documentationstyleβ Code stylerefactorβ Code refactoringperfβ Performance improvementtestβ Test additions/updateschoreβ Build, dependencies, etc.
Examples:
feat: add hello command with name parameter
fix: resolve panic in logger initialization
docs: update README with quick start guide
chore: upgrade Go from 1.21 to 1.22
-
Create and push tag:
git tag v1.2.3 git push origin v1.2.3
-
Release workflow triggers:
- Multi-platform builds
- GitHub Release creation
- Docker image push
- SBOM generation
-
Artifacts available at:
https://github.com/PlatformStackPulse/my-app/releases/tag/v1.2.3
CHANGELOG.mdis generated from Conventional Commits usinggit-chglog.- On merges/pushes to
main,.github/workflows/changelog.ymlupdates and commitsCHANGELOG.mdautomatically. - Maintainers can regenerate locally with:
make changelogfm := feature.NewManager()
if fm.IsEnabled(feature.FeatureHello) {
fmt.Println("Feature is enabled!")
}Edit internal/feature/flags.go:
const (
FeatureNewAPI Flag = "feature_new_api"
FeatureMetrics Flag = "feature_metrics"
)# Environment variable format
export FEATURE_FLAGS="feature_new_api=true,feature_metrics=false"
./bin/go-template hello- Config file support (YAML/JSON)
- Remote flag service integration
- Gradual rollout (percentage)
- User-based targeting
- A/B testing support
# Build locally
docker build -t go-template:latest .
# Run container
docker run --rm go-template:latest hello
# Run with feature flags
docker run --rm \
-e FEATURE_FLAGS="feature_hello=true" \
go-template:latest hello# Development
docker-compose up dev
# Run tests
docker-compose run test
# Run linter
docker-compose run lintRuns on every push and PR:
- Code linting (golangci-lint)
- Format verification
- Unit & integration tests
- Coverage enforcement (β₯70%)
- Security scans (gosec, CodeQL)
- PR commit message validation
- Multi-version Go testing (1.21, 1.22)
Triggers on version tags (v*.*.*):
- Multi-platform builds (Linux, macOS, Windows)
- Checksum generation
- GitHub Release creation with artifacts
- Docker image build and push
- SBOM generation
Weekly automated tasks:
- Dependency updates
- Security vulnerability scans
- Automated PR creation
Runs code scanning on pushes/PRs to main and on a weekly schedule.
Updates CHANGELOG.md from Conventional Commits on pushes to main.
Deploy to Kubernetes:
kubectl apply -f deploy/kubernetes/
# Check deployment
kubectl get pods -l app=go-templateDeploy to AWS Lambda:
cd deploy/terraform
terraform init
terraform plan -var-file=terraform.dev.tfvars
terraform apply -var-file=terraform.dev.tfvars| Variable | Description | Default |
|---|---|---|
DEBUG |
Enable debug logging | false |
APP_NAME |
Application name | go-template |
APP_VERSION |
Application version | dev |
FEATURE_FLAGS |
Enabled feature flags | "" |
DEBUG=true
APP_NAME=my-app
APP_VERSION=v1.0.0
FEATURE_FLAGS=feature_hello=true,feature_metrics=true- Fork the repository
- Create a feature branch:
git checkout -b feature/awesome-feature - Commit with conventional format:
git commit -m "feat: add awesome feature" - Push to branch:
git push origin feature/awesome-feature - Open a Pull Request
- β Must follow Conventional Commits
- β Tests passing (coverage β₯ 70%)
- β Code linting passing
- β No security warnings
- β Documentation updated
When using this template:
- Update
go.modmodule path - Update
module path in code imports - Create
.github/CODEOWNERSfile - Update README with project-specific info
- Configure branch protection rules
- Setup Dependabot alerts
- Update repository description
- Add repository topics
- Customize GitHub Actions (if needed)
- Update Terraform variables for your environment
This project is licensed under the MIT License β see LICENSE file for details.
Built with best practices from:
- π Documentation
- π Report Issues
- π¬ Discussions
Built with β€οΈ for platform engineers and Go developers