.PHONY: all build clean test test-all test-integration-go test-unit-go test-connection schema-install broker-start broker-stop install deps docker-up docker-down help # Build variables BINARY_NAME=pgsql-broker BIN_DIR=bin CMD_DIR=cmd/broker GO=go GOFLAGS=-v LDFLAGS=-w -s # Auto-detect container runtime (Docker or Podman) CONTAINER_RUNTIME := $(shell \ if command -v podman > /dev/null 2>&1; then \ echo "podman"; \ elif command -v docker > /dev/null 2>&1; then \ echo "docker"; \ else \ echo "none"; \ fi) # Detect compose command COMPOSE_CMD := $(shell \ if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \ echo "podman-compose"; \ elif command -v docker-compose > /dev/null 2>&1; then \ echo "docker-compose"; \ else \ echo "docker compose"; \ fi) # Version information VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") BUILD_TIME=$(shell date -u '+2026-01-02_19:58:30') COMMIT=$(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") # Inject version info LDFLAGS += -X 'main.Version=$(VERSION)' -X 'main.BuildTime=$(BUILD_TIME)' -X 'main.Commit=$(COMMIT)' all: clean deps build ## Build everything build: ## Build the broker binary @echo "Building $(BINARY_NAME)..." @mkdir -p $(BIN_DIR) $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/$(BINARY_NAME) ./$(CMD_DIR) @echo "Built: $(BIN_DIR)/$(BINARY_NAME)" clean: ## Remove build artifacts @echo "Cleaning..." @rm -rf $(BIN_DIR) @$(GO) clean @echo "Clean complete" deps: ## Download dependencies @echo "Downloading dependencies..." @$(GO) mod download @$(GO) mod tidy @echo "Dependencies ready" # Main test target to run everything test-local-unit: deps ## Run local unit tests @echo "Running local unit tests..." @$(GO) test -v -race -cover $(shell $(GO) list ./... | grep -v /tests/integration) test-all: test-teardown test-setup test-connection schema-install broker-start test-local-unit test-integration-go broker-stop test-teardown ## Run all unit and integration tests test-connection: deps ## Test database connection with retry @echo "Testing database connection..." @$(GO) test -v ./tests/integration/connection_test.go schema-install: build ## Install database schema using the broker CLI @echo "Installing database schema..." @$(BIN_DIR)/$(BINARY_NAME) install --config broker.test.yaml test-setup: build ## Start test environment (docker-compose) @echo "Starting test environment..." @podman-compose -f tests/docker-compose.yml up -d test-teardown: ## Stop test environment (docker-compose) @echo "Stopping test environment..." @podman-compose -f tests/docker-compose.yml down -v --rmi all @sleep 5 # Give Docker time to release resources broker-start: build ## Start the broker in the background @echo "Starting broker..." @setsid $(BIN_DIR)/$(BINARY_NAME) start --config broker.test.yaml > broker.log 2>&1 < /dev/null & echo $$! > broker.pid @sleep 5 # Give the broker a moment to start broker-stop: ## Stop the broker @echo "Stopping broker..." @if [ -f broker.pid ]; then \ kill -15 -- -$$(cat broker.pid); \ rm broker.pid; \ else \ echo "broker.pid not found, broker might not be running."; \ fi test-integration-go: ## Run Go integration tests @echo "Running Go integration tests..." @$(GO) test -v ./tests/integration/... install: build ## Install the binary to GOPATH/bin @echo "Installing to GOPATH/bin..." @$(GO) install $(GOFLAGS) -ldflags "$(LDFLAGS)" ./$(CMD_DIR) @echo "Installed: $(BINARY_NAME)" run: build ## Build and run the broker @echo "Running $(BINARY_NAME)..." @$(BIN_DIR)/$(BINARY_NAME) fmt: ## Format the code @echo "Formatting code..." @$(GO) fmt ./... @echo "Formatting complete" vet: ## Run go vet @echo "Running go vet..." @$(GO) vet ./... @echo "Vet complete" lint: ## Run golangci-lint (if installed) @if command -v golangci-lint >/dev/null 2>&1; then \ echo "Running golangci-lint..."; \ golangci-lint run ./...; \ else \ echo "golangci-lint not installed, skipping"; \ fi sql-install: build ## Install SQL tables and procedures using broker CLI @echo "Installing SQL schema..." @$(BIN_DIR)/$(BINARY_NAME) install sql-install-manual: ## Install SQL tables and procedures manually via psql @echo "Installing SQL schema manually..." @if [ -z "$$PGDATABASE" ]; then \ echo "Error: PGDATABASE environment variable not set"; \ exit 1; \ fi @psql -f pkg/broker/install/sql/tables/00_install.sql @psql -f pkg/broker/install/sql/procedures/00_install.sql @echo "SQL schema installed" docker-up: ## Start PostgreSQL test database @echo "Starting PostgreSQL test database (using $(CONTAINER_RUNTIME))..." @if [ "$(CONTAINER_RUNTIME)" = "none" ]; then \ echo "Error: Neither Docker nor Podman is installed"; \ exit 1; \ fi @if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \ podman run -d --name pgsql-broker-test-postgres \ -e POSTGRES_USER=user \ -e POSTGRES_PASSWORD=password \ -e POSTGRES_DB=broker_test \ -p 5433:5432 \ postgres:13 2>/dev/null || echo "Container already running"; \ else \ cd tests && $(COMPOSE_CMD) up -d; \ fi @echo "Waiting for PostgreSQL to be ready..." @sleep 3 @echo "PostgreSQL is running on port 5433" @echo "Connection: postgres://user:password@localhost:5433/broker_test" docker-down: ## Stop PostgreSQL test database @echo "Stopping PostgreSQL test database (using $(CONTAINER_RUNTIME))..." @if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then \ podman stop pgsql-broker-test-postgres 2>/dev/null || true; \ podman rm pgsql-broker-test-postgres 2>/dev/null || true; \ else \ cd tests && $(COMPOSE_CMD) down; \ fi @echo "PostgreSQL stopped" release: ## Create and push a new release tag (auto-increments patch version) @echo "Creating new release..." @latest_tag=$$(git describe --tags --abbrev=0 2>/dev/null || echo ""); \ if [ -z "$$latest_tag" ]; then \ version="v1.0.0"; \ echo "No existing tags found. Creating first release: $$version"; \ commit_logs=$$(git log --pretty=format:"- %s" --no-merges); \ else \ echo "Latest tag: $$latest_tag"; \ version_number=$${latest_tag#v}; \ IFS='.' read -r major minor patch <<< "$$version_number"; \ patch=$$((patch + 1)); \ version="v$$major.$$minor.$$patch"; \ echo "Creating new release: $$version"; \ commit_logs=$$(git log "$${latest_tag}..HEAD" --pretty=format:"- %s" --no-merges); \ fi; \ if [ -z "$$commit_logs" ]; then \ tag_message="Release $$version"; \ else \ tag_message="Release $$version\n\n$$commit_logs"; \ fi; \ git tag -a "$$version" -m "$$tag_message"; \ git push origin "$$version"; \ echo "Tag $$version created and pushed to remote repository." help: ## Show this help message @echo "Usage: make [target]" @echo "" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'