Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 6 additions & 35 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ on:
env:
IMAGE_NAME: quay.io/dminnear/patternizer
GO_VERSION: '1.24'
GOLANGCI_LINT_VERSION: 'v2.1.6'

jobs:
lint-and-format:
Expand All @@ -28,26 +27,8 @@ jobs:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: src/go.sum

- name: Run gofmt
run: |
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
echo "The following files are not formatted:"
gofmt -s -l .
exit 1
fi
working-directory: ./src

- name: Run go vet
run: go vet ./...
working-directory: ./src

- name: Install golangci-lint
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin ${{ env.GOLANGCI_LINT_VERSION }}

- name: Run golangci-lint
run: $(go env GOPATH)/bin/golangci-lint run
working-directory: ./src
- name: Run linting checks
run: make lint

build-and-test:
runs-on: ubuntu-latest
Expand All @@ -63,26 +44,16 @@ jobs:
cache-dependency-path: src/go.sum

- name: Build binary
run: go build -v -o patternizer .
working-directory: ./src
run: make build

- name: Run unit tests
run: |
echo "Running unit tests for all packages..."
go test -v ./...
working-directory: ./src
run: make test-unit

- name: Generate test coverage report
run: |
echo "Generating test coverage report..."
go test ./... -coverprofile=coverage.out
go tool cover -func=coverage.out
working-directory: ./src
run: make test-coverage

- name: Run integration tests
run: ./test/integration_test.sh
env:
PATTERNIZER_BINARY: ./src/patternizer
run: make test-integration

build-container:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
src/patternizer
src/coverage.out
155 changes: 155 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Makefile for patternizer

# Variables
BINARY_NAME := patternizer
GO_VERSION := 1.24
GOLANGCI_LINT_VERSION := v2.1.6
IMAGE_NAME := patternizer
LOCAL_TAG := local
SRC_DIR := src
CONTAINER_ENGINE := podman

# Go-related variables
GO_CMD := go
GO_BUILD := $(GO_CMD) build
GO_TEST := $(GO_CMD) test
GO_CLEAN := $(GO_CMD) clean
GO_VET := $(GO_CMD) vet
GO_FMT := gofmt

# Default target
.DEFAULT_GOAL := help

# Help target
.PHONY: help
help: ## Show this help message
@echo "Available targets:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

# Build target
.PHONY: build
build: ## Build the patternizer binary
@echo "Building patternizer..."
cd $(SRC_DIR) && $(GO_BUILD) -v -o $(BINARY_NAME) .
@echo "Build complete: $(SRC_DIR)/$(BINARY_NAME)"

# Clean target
.PHONY: clean
clean: ## Clean build artifacts
@echo "Cleaning build artifacts..."
cd $(SRC_DIR) && $(GO_CLEAN)
rm -f $(SRC_DIR)/$(BINARY_NAME)
rm -f $(SRC_DIR)/coverage.out
@echo "Clean complete"

# Install dependencies
.PHONY: deps
deps: ## Download and install Go dependencies
@echo "Installing dependencies..."
cd $(SRC_DIR) && $(GO_CMD) mod download
cd $(SRC_DIR) && $(GO_CMD) mod tidy
@echo "Dependencies installed"

# Unit tests
.PHONY: test-unit
test-unit: ## Run unit tests
@echo "Running unit tests..."
cd $(SRC_DIR) && $(GO_TEST) -v ./...

# Test with coverage
.PHONY: test-coverage
test-coverage: ## Run unit tests with coverage report
@echo "Running unit tests with coverage..."
cd $(SRC_DIR) && $(GO_TEST) ./... -coverprofile=coverage.out
cd $(SRC_DIR) && $(GO_CMD) tool cover -func=coverage.out

# Integration tests
.PHONY: test-integration
test-integration: build ## Run integration tests
@echo "Running integration tests..."
PATTERNIZER_BINARY=./$(SRC_DIR)/$(BINARY_NAME) ./test/integration_test.sh

# All tests
.PHONY: test
test: test-unit test-integration ## Run all tests (unit + integration)

# Lint target
.PHONY: lint
lint: lint-fmt lint-vet lint-golangci ## Run all linting checks

# Format check
.PHONY: lint-fmt
lint-fmt: ## Check Go formatting
@echo "Checking Go formatting..."
@cd $(SRC_DIR) && if [ "$$($(GO_FMT) -s -l . | wc -l)" -gt 0 ]; then \
echo "The following files are not formatted:"; \
$(GO_FMT) -s -l .; \
exit 1; \
fi
@echo "Go formatting check passed"

# Vet check
.PHONY: lint-vet
lint-vet: ## Run go vet
@echo "Running go vet..."
cd $(SRC_DIR) && $(GO_VET) ./...
@echo "Go vet passed"

# golangci-lint check
.PHONY: lint-golangci
lint-golangci: ## Run golangci-lint
@echo "Running golangci-lint..."
@if ! command -v golangci-lint >/dev/null 2>&1; then \
echo "Installing golangci-lint..."; \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $$(go env GOPATH)/bin $(GOLANGCI_LINT_VERSION); \
fi
cd $(SRC_DIR) && $$(go env GOPATH)/bin/golangci-lint run
@echo "golangci-lint passed"

# Format code
.PHONY: fmt
fmt: ## Format Go code
@echo "Formatting Go code..."
cd $(SRC_DIR) && $(GO_FMT) -s -w .
@echo "Go code formatted"

# Local container build
.PHONY: local-container-build
local-container-build: ## Build container image locally
@echo "Building container image..."
$(CONTAINER_ENGINE) build -t $(IMAGE_NAME):$(LOCAL_TAG) -f Containerfile .
@echo "Container image built: $(IMAGE_NAME):$(LOCAL_TAG)"

# Full CI pipeline locally
.PHONY: ci
ci: lint build test ## Run the full CI pipeline locally

# Development setup
.PHONY: dev-setup
dev-setup: deps ## Set up development environment
@echo "Setting up development environment..."
@if ! command -v golangci-lint >/dev/null 2>&1; then \
echo "Installing golangci-lint..."; \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $$(go env GOPATH)/bin $(GOLANGCI_LINT_VERSION); \
fi
@echo "Development environment ready"

# Version info
.PHONY: version
version: ## Show version information
@echo "Go version: $$(go version)"
@echo "Git commit: $$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')"
@echo "Build date: $$(date -u +%Y-%m-%dT%H:%M:%SZ)"

# Generate documentation
.PHONY: docs
docs: ## Generate Go documentation
@echo "Generating documentation..."
cd $(SRC_DIR) && $(GO_CMD) doc -all ./...

# Quick check (fast feedback loop)
.PHONY: check
check: lint-fmt lint-vet build test-unit ## Quick check (format, vet, build, unit tests)

.PHONY: all
all: clean deps lint build test local-container-build ## Run everything
112 changes: 80 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ The tool provides both a standalone CLI and containerized execution for maximum
- 🔐 **Secrets integration** with Vault and External Secrets support
- ✅ **Comprehensive testing** with unit and integration tests
- 🏗️ **Multi-stage builds** for minimal container images
- 🛠️ **Makefile-driven development** for consistent local development and CI

## Quick Start for Developers

```bash
# Clone the repository
git clone https://github.com/dminnear-rh/patternizer.git
cd patternizer

# Set up development environment
make dev-setup

# See all available targets
make help

# Build and test
make build
make test
```

---

Expand Down Expand Up @@ -103,51 +122,58 @@ podman run --rm -it -v .:/repo:z quay.io/dminnear/patternizer init --with-secret
- Go 1.24+
- Podman or Docker
- Git
- Make

### Building the CLI
### Quick Start

```bash
cd src
go build -o patternizer .
# Set up development environment (installs dependencies and tools)
make dev-setup

# Show all available targets
make help
```

### Running Tests
### Common Development Tasks

```bash
# Run unit tests
cd src
go test -v ./...
# Build the CLI
make build

# Run integration tests (requires built binary)
cd ..
./test/integration_test.sh
```
# Run all tests (unit + integration)
make test

### Building the Container
# Run only unit tests
make test-unit

```bash
# Build with default settings
podman build -t patternizer:local .
# Run only integration tests
make test-integration

# Build container image locally
make local-container-build

# Build with custom alpine version
podman build --build-arg ALPINE_VERSION=3.22 -t patternizer:local .
# Run full CI pipeline locally
make ci

# Quick feedback loop (format check, vet, build, unit tests)
make check
```

### Code Quality

The project uses comprehensive linting and formatting:

```bash
cd src
# Run all linting checks (gofmt, go vet, golangci-lint)
make lint

# Format code
gofmt -s -w .

# Run linter
golangci-lint run
make fmt

# Run vet
go vet ./...
# Run individual lint checks
make lint-fmt # gofmt check
make lint-vet # go vet
make lint-golangci # golangci-lint
```

---
Expand Down Expand Up @@ -189,25 +215,27 @@ The integration test (`test/integration_test.sh`) validates the complete workflo

Run integration tests locally:
```bash
# Build the binary first
cd src && go build -o patternizer .
# Run integration tests (automatically builds binary first)
make test-integration

# Run integration tests
cd .. && ./test/integration_test.sh
# Or run all tests (unit + integration)
make test
```

---

## CI/CD Pipeline

The project uses a comprehensive CI pipeline with three stages:
The project uses a comprehensive CI pipeline with three stages that leverage the Makefile for consistency:

1. **Lint & Format**: Code quality checks with `gofmt`, `go vet`, and `golangci-lint`
2. **Build & Test**: Binary compilation, unit tests, and integration tests
1. **Lint & Format**: `make lint` - Code quality checks with `gofmt`, `go vet`, and `golangci-lint`
2. **Build & Test**: `make build`, `make test-unit`, `make test-coverage`, `make test-integration`
3. **Container Build**: Multi-stage container build and push to Quay.io

All code must pass linting and tests before being merged or deployed.

The CI pipeline uses the same Makefile targets that developers use locally, ensuring perfect consistency between local development and CI environments. You can run the same checks locally with `make ci`.

---

## Architecture
Expand Down Expand Up @@ -243,7 +271,27 @@ This modular design makes the codebase maintainable, testable, and extensible.
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests: `go test ./... && ./test/integration_test.sh`
4. Run the development workflow:
```bash
make dev-setup # Set up development environment
make check # Quick feedback loop
make test # Run all tests
make lint # Run all linting checks
```
5. Submit a pull request

All contributions must pass the CI pipeline including linting, formatting, and comprehensive testing.

### Development Workflow

For the best development experience:
```bash
# Initial setup
make dev-setup

# During development (fast feedback)
make check

# Before committing
make ci # Runs the full CI pipeline locally
```