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 ```