From 1636246ae5cbe999ff1752388043b6cf200301f7 Mon Sep 17 00:00:00 2001 From: Melvin Hillsman Date: Wed, 20 May 2026 16:22:59 -0500 Subject: [PATCH] feat: add Makefile with CI/CD automation targets Add comprehensive Makefile providing convenient shortcuts for common development tasks including test, vet, lint, build, and formatting. Update development documentation to describe both the Makefile targets and existing GitHub Actions CI/CD workflows. Add test coverage files to .gitignore. This addresses the missing Makefile mentioned in issue #10, complementing the GitHub Actions workflows that were recently added. The Makefile uses podman as the default container runtime (aligned with OpenShift/RHEL ecosystem) but allows override via CONTAINER_RUNTIME=docker. Resolves: #10 Signed-off-by: Melvin Hillsman --- .gitignore | 4 ++ Makefile | 70 ++++++++++++++++++++++++++++++++++ docs/development.md | 93 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 30fde5a..d8e1b2b 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,10 @@ bin/ /virtctl *.exe +# Test coverage +coverage.out +*.coverprofile + # Audit database virtwork.db diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f1eaaf9 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +# Container runtime (podman by default, override with CONTAINER_RUNTIME=docker) +CONTAINER_RUNTIME ?= podman + +.PHONY: help +help: ## Display this help message + @echo "Available targets:" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' + +.PHONY: test +test: ## Run unit tests (excludes integration and e2e tests) + @echo "Running unit tests..." + go test -v -race -coverprofile=coverage.out -covermode=atomic ./... + +.PHONY: test-integration +test-integration: ## Run integration tests (requires live OpenShift cluster with KubeVirt) + @echo "Running integration tests..." + go test -v -race -tags=integration ./... + +.PHONY: test-e2e +test-e2e: ## Run end-to-end tests (requires live OpenShift cluster with KubeVirt) + @echo "Running e2e tests..." + go test -v -race -tags=e2e ./tests/e2e/... + +.PHONY: test-all +test-all: test test-integration test-e2e ## Run all tests (unit, integration, and e2e) + +.PHONY: vet +vet: ## Run go vet + @echo "Running go vet..." + go vet ./... + +.PHONY: lint +lint: ## Run golangci-lint + @echo "Running golangci-lint..." + @which golangci-lint > /dev/null || (echo "golangci-lint not found. Install from https://golangci-lint.run/usage/install/" && exit 1) + golangci-lint run + +.PHONY: fmt +fmt: ## Format Go code + @echo "Formatting code..." + go fmt ./... + +.PHONY: build +build: ## Build the virtwork binary + @echo "Building virtwork..." + go build -o bin/virtwork ./cmd/virtwork + +.PHONY: clean +clean: ## Remove build artifacts and test coverage files + @echo "Cleaning build artifacts..." + rm -rf bin/ + rm -f coverage.out + +.PHONY: ci +ci: vet test build ## Run CI validation locally (vet, test, build) + +.PHONY: install-tools +install-tools: ## Install development tools (golangci-lint) + @echo "Installing development tools..." + @which golangci-lint > /dev/null || go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +.PHONY: container-build +container-build: ## Build container image locally (uses podman by default, override with CONTAINER_RUNTIME=docker) + @echo "Building container image with $(CONTAINER_RUNTIME)..." + $(CONTAINER_RUNTIME) build -t virtwork:local -f Dockerfile . + +.PHONY: verify +verify: fmt vet lint test ## Run all verification checks (fmt, vet, lint, test) + +.DEFAULT_GOAL := help diff --git a/docs/development.md b/docs/development.md index a96b10e..792dc85 100644 --- a/docs/development.md +++ b/docs/development.md @@ -154,6 +154,99 @@ VIRTWORK_BINARY=./virtwork go test -tags e2e ./tests/e2e/... go test -tags "integration e2e" ./... ``` +## Makefile Targets + +A `Makefile` provides convenient shortcuts for common development tasks: + +```bash +# Show all available targets +make help + +# Run unit tests (excludes integration/e2e) +make test + +# Run integration tests (requires cluster) +make test-integration + +# Run e2e tests (requires cluster) +make test-e2e + +# Run all tests (unit + integration + e2e) +make test-all + +# Run go vet +make vet + +# Run golangci-lint +make lint + +# Format code +make fmt + +# Build the binary +make build + +# Run full CI validation locally (vet + test + build) +make ci + +# Run all verification checks (fmt + vet + lint + test) +make verify + +# Clean build artifacts +make clean + +# Install development tools (golangci-lint) +make install-tools + +# Build container image locally (uses podman by default) +make container-build + +# Build with docker instead of podman +CONTAINER_RUNTIME=docker make container-build +``` + +## CI/CD Pipeline + +The project uses GitHub Actions for automated validation on push and pull requests: + +### Workflows + +- **Build & Test** (`.github/workflows/build.yml`) — Runs on every push/PR to main + - Go vet checks + - Unit tests with race detector + - Binary build verification + - Only runs unit tests (integration/e2e require live cluster) + +- **Linting** (`.github/workflows/lint.yml`) — Runs golangci-lint on every push/PR + - Code quality checks + - Static analysis + - Best practices enforcement + +- **Container Image** (`.github/workflows/image.yml`) — Builds and pushes container images + - Triggered on main branch pushes and tags + +- **Release** (`.github/workflows/release.yml`) — Automated releases via GoReleaser + - Triggered on version tags (e.g., `v1.0.0`) + - Builds multi-platform binaries + - Generates release notes + +### Running CI Checks Locally + +Before pushing code, run the same checks that CI will execute: + +```bash +# Quick validation (vet + test + build) +make ci + +# Full verification (includes fmt and lint) +make verify + +# Or run individual checks +make vet +make test +make lint +``` + ## Project Layout ```