# Makefile pour Veza Backend API # Ce Makefile facilite le développement et la maintenance du backend Go # Tests: ports depuis ../.env ou défauts docker-compose (Redis 16379, RabbitMQ 15672) -include ../.env PORT_REDIS ?= 16379 PORT_RABBITMQ_AMQP ?= 15672 DB_USER ?= veza DB_PASS ?= password .PHONY: help build test clean lint format vet tidy deps install run dev docker-build docker-run # Variables BINARY_NAME=veza-backend-api DOCKER_IMAGE=veza-backend-api DOCKER_TAG=latest GO_VERSION=1.21 LINT_VERSION=1.54.2 # Couleurs pour les messages GREEN=\033[0;32m YELLOW=\033[1;33m RED=\033[0;31m NC=\033[0m # No Color # Aide par défaut help: ## Affiche cette aide @echo "$(GREEN)Veza Backend API - Makefile$(NC)" @echo "" @echo "$(YELLOW)Commandes disponibles:$(NC)" @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(GREEN)%-15s$(NC) %s\n", $$1, $$2}' $(MAKEFILE_LIST) # Développement build: ## Compile l'application @echo "$(GREEN)🔨 Compilation de l'application...$(NC)" @go build -o bin/$(BINARY_NAME) ./cmd/api/main.go @echo "$(GREEN)✅ Compilation terminée: bin/$(BINARY_NAME)$(NC)" build-linux: ## Compile l'application pour Linux @echo "$(GREEN)🔨 Compilation pour Linux...$(NC)" @GOOS=linux GOARCH=amd64 go build -o bin/$(BINARY_NAME)-linux ./cmd/api/main.go @echo "$(GREEN)✅ Compilation Linux terminée: bin/$(BINARY_NAME)-linux$(NC)" # Tests test: ## Exécute tous les tests (sans tests en quarantaine) @echo "$(GREEN)🧪 Exécution des tests...$(NC)" @go test -v ./internal/... -short -tags '!integration' test-coverage: ## Exécute les tests avec couverture @echo "$(GREEN)🧪 Tests avec couverture...$(NC)" @go test -coverprofile=coverage.out ./internal/... -short -tags '!integration' @go tool cover -html=coverage.out -o coverage.html @echo "$(GREEN)✅ Rapport de couverture généré: coverage.html$(NC)" test-race: ## Exécute les tests avec détection de race conditions @echo "$(GREEN)🧪 Tests avec détection de race conditions...$(NC)" @REDIS_ADDR=$(TEST_REDIS_ADDR) REDIS_TEST_URL=$(TEST_REDIS_URL) RABBITMQ_URL=$(TEST_RABBITMQ_URL) \ go test -race ./internal/... -short -tags '!integration' test-integration: ## Exécute les tests d'intégration (nécessite make infra-up ou Redis/Postgres) @echo "$(GREEN)🧪 Exécution des tests d'intégration...$(NC)" @echo "$(YELLOW)Note: make infra-up depuis la racine ou REDIS_ADDR=localhost:16379$(NC)" @REDIS_ADDR=$(TEST_REDIS_ADDR) REDIS_TEST_URL=$(TEST_REDIS_URL) RABBITMQ_URL=$(TEST_RABBITMQ_URL) \ go test -tags=integration -v ./tests/integration/... test-quarantine: ## Exécute les tests en quarantaine (validation manuelle) @echo "$(GREEN)🧪 Exécution des tests en quarantaine...$(NC)" @echo "$(YELLOW)Note: Nécessite Docker pour testcontainers$(NC)" @go test ./internal/... -count=1 -tags integration -v test-short: ## Exécute les tests courts uniquement @echo "$(GREEN)🧪 Tests courts...$(NC)" @go test ./internal/... -count=1 -short -tags '!integration' -timeout 30s # Qualité du code lint: ## Exécute golangci-lint @echo "$(GREEN)🔍 Vérification avec golangci-lint...$(NC)" @if command -v golangci-lint >/dev/null 2>&1; then \ golangci-lint run; \ else \ echo "$(YELLOW)⚠️ golangci-lint non installé. Installation...$(NC)"; \ go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(LINT_VERSION); \ golangci-lint run; \ fi format: ## Formate le code Go @echo "$(GREEN)🎨 Formatage du code...$(NC)" @go fmt ./... @if command -v goimports >/dev/null 2>&1; then \ find . -name "*.go" -not -path "./vendor/*" | xargs goimports -w; \ else \ echo "$(YELLOW)⚠️ goimports non installé. Installation...$(NC)"; \ go install golang.org/x/tools/cmd/goimports@latest; \ find . -name "*.go" -not -path "./vendor/*" | xargs goimports -w; \ fi @echo "$(GREEN)✅ Code formaté$(NC)" vet: ## Exécute go vet @echo "$(GREEN)🔍 Vérification avec go vet...$(NC)" @go vet ./... # Dépendances deps: ## Installe les dépendances @echo "$(GREEN)📦 Installation des dépendances...$(NC)" @go mod download @go mod tidy @echo "$(GREEN)✅ Dépendances installées$(NC)" install: ## Installe l'application @echo "$(GREEN)📦 Installation de l'application...$(NC)" @go install ./cmd/api/main.go @echo "$(GREEN)✅ Application installée$(NC)" # Nettoyage clean: ## Nettoie les fichiers générés @echo "$(GREEN)🧹 Nettoyage...$(NC)" @rm -rf bin/ @rm -f coverage.out coverage.html @go clean @echo "$(GREEN)✅ Nettoyage terminé$(NC)" # Exécution run: build ## Compile et exécute l'application @echo "$(GREEN)🚀 Démarrage de l'application...$(NC)" @./bin/$(BINARY_NAME) dev: ## Exécute l'application en mode développement @echo "$(GREEN)🚀 Mode développement...$(NC)" @go run ./cmd/api/main.go # Docker docker-build: ## Construit l'image Docker @echo "$(GREEN)🐳 Construction de l'image Docker...$(NC)" @docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) . @echo "$(GREEN)✅ Image Docker construite: $(DOCKER_IMAGE):$(DOCKER_TAG)$(NC)" docker-run: docker-build ## Construit et exécute l'image Docker @echo "$(GREEN)🐳 Exécution de l'image Docker...$(NC)" @docker run -p 8080:8080 $(DOCKER_IMAGE):$(DOCKER_TAG) # Outils de développement install-tools: ## Installe les outils de développement @echo "$(GREEN)🛠️ Installation des outils de développement...$(NC)" @go install golang.org/x/tools/cmd/goimports@latest @go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(LINT_VERSION) @go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest @go install golang.org/x/vuln/cmd/govulncheck@latest @go install honnef.co/go/tools/cmd/staticcheck@latest @echo "$(GREEN)✅ Outils installés$(NC)" # Sécurité security: ## Exécute les vérifications de sécurité @echo "$(GREEN)🔒 Vérifications de sécurité...$(NC)" @if command -v gosec >/dev/null 2>&1; then \ gosec ./...; \ else \ echo "$(YELLOW)⚠️ gosec non installé. Installation...$(NC)"; \ go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest; \ gosec ./...; \ fi @echo "$(GREEN)🔒 Recherche de vulnérabilités (govulncheck)...$(NC)" @if command -v govulncheck >/dev/null 2>&1; then \ govulncheck ./...; \ else \ echo "$(YELLOW)⚠️ govulncheck non installé. Installation...$(NC)"; \ go install golang.org/x/vuln/cmd/govulncheck@latest; \ $$(go env GOPATH)/bin/govulncheck ./... || \ $$HOME/go/bin/govulncheck ./... || \ (echo "$(RED)❌ Impossible de trouver govulncheck après installation$(NC)" && exit 1); \ fi vulncheck: ## Scan des vulnérabilités Go uniquement (govulncheck) @echo "$(GREEN)🔒 Scan des vulnérabilités Go...$(NC)" @if command -v govulncheck >/dev/null 2>&1; then \ govulncheck ./...; \ else \ echo "$(YELLOW)⚠️ govulncheck non installé. Installation...$(NC)"; \ go install golang.org/x/vuln/cmd/govulncheck@latest; \ $$(go env GOPATH)/bin/govulncheck ./... || \ $$HOME/go/bin/govulncheck ./... || \ (echo "$(RED)❌ Impossible de trouver govulncheck après installation$(NC)" && exit 1); \ fi docker-scan: docker-build ## Scan de l'image Docker avec Trivy @echo "$(GREEN)🔒 Scan de l'image Docker...$(NC)" @if command -v trivy >/dev/null 2>&1; then \ trivy image --severity CRITICAL,HIGH $(DOCKER_IMAGE):$(DOCKER_TAG); \ else \ echo "$(YELLOW)⚠️ Trivy non installé. Utilisation via Docker...$(NC)"; \ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image --severity CRITICAL,HIGH $(DOCKER_IMAGE):$(DOCKER_TAG); \ fi docker-scan-full: docker-build ## Scan complet de l'image Docker (toutes sévérités) @echo "$(GREEN)🔒 Scan complet de l'image Docker...$(NC)" @if command -v trivy >/dev/null 2>&1; then \ trivy image $(DOCKER_IMAGE):$(DOCKER_TAG); \ else \ echo "$(YELLOW)⚠️ Trivy non installé. Utilisation via Docker...$(NC)"; \ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ aquasec/trivy:latest image $(DOCKER_IMAGE):$(DOCKER_TAG); \ fi # Performance load-test: ## Exécute le test de charge k6 (smoke) @echo "$(GREEN)🔥 Exécution du test de charge (smoke)...$(NC)" @k6 run ../loadtests/smoke.js 2>/dev/null || docker run --rm -i --network=host -v $(CURDIR)/../loadtests:/scripts grafana/k6 run /scripts/smoke.js load-test-uploads: ## Exécute le test de charge uploads (requiert AUTH_TOKEN) @echo "$(GREEN)🔥 Exécution du test de charge (uploads)...$(NC)" @k6 run ../loadtests/backend/uploads.js 2>/dev/null || docker run --rm -i --network=host -e AUTH_TOKEN=$${AUTH_TOKEN} -v $(CURDIR)/../loadtests:/scripts grafana/k6 run /scripts/backend/uploads.js benchmark: ## Exécute les benchmarks @echo "$(GREEN)⚡ Exécution des benchmarks...$(NC)" @go test -bench=. ./... # Documentation docs: ## Génère la documentation @echo "$(GREEN)📚 Génération de la documentation...$(NC)" @go doc -all ./... > docs.txt @echo "$(GREEN)✅ Documentation générée: docs.txt$(NC)" # OpenAPI (v0.923 Contract) openapi: ## Régénère openapi.yaml depuis les annotations Swagger @echo "$(GREEN)📄 Génération OpenAPI...$(NC)" @if command -v swag >/dev/null 2>&1; then \ swag init -g cmd/api/main.go --parseDependency --parseInternal; \ else \ echo "$(YELLOW)⚠️ swag non installé. Installation...$(NC)"; \ go install github.com/swaggo/swag/cmd/swag@latest; \ $$(go env GOPATH)/bin/swag init -g cmd/api/main.go --parseDependency --parseInternal; \ fi @cp docs/swagger.yaml openapi.yaml @echo "$(GREEN)✅ openapi.yaml généré$(NC)" @echo "$(GREEN)🔍 Validation de la spec (Swagger 2.0)...$(NC)" @cd .. && (npx @apidevtools/swagger-cli validate veza-backend-api/openapi.yaml && echo "$(GREEN)✅ openapi.yaml validé$(NC)") || \ (echo "$(YELLOW)⚠️ swagger-cli signale des écarts OAS3 (Swagger 2.0). Spec utilisable pour generate-types.$(NC)" && true) # Scripts personnalisés cleanup: ## Exécute le script de nettoyage @echo "$(GREEN)🧹 Exécution du script de nettoyage...$(NC)" @./scripts/cleanup-go.sh # CI/CD ci: deps lint security test build ## Pipeline CI complet @echo "$(GREEN)✅ Pipeline CI terminé$(NC)" ci-test: ## CI: Tests normaux (sans quarantaine) @echo "$(GREEN)🧪 CI: Tests normaux...$(NC)" @go test ./internal/... -count=1 -short -tags '!integration' -coverprofile=coverage.out ci-test-integration: ## CI: Tests d'intégration (séparé, optionnel) @echo "$(GREEN)🧪 CI: Tests d'intégration...$(NC)" @go test ./tests/integration/... -tags integration -v -timeout 10m # Déploiement deploy-staging: build-linux ## Déploie en staging @echo "$(GREEN)🚀 Déploiement en staging...$(NC)" @echo "$(YELLOW)⚠️ Déploiement en staging non implémenté$(NC)" deploy-production: build-linux ## Déploie en production @echo "$(GREEN)🚀 Déploiement en production...$(NC)" @echo "$(YELLOW)⚠️ Déploiement en production non implémenté$(NC)" # Monitoring health: ## Vérifie la santé de l'application @echo "$(GREEN)🏥 Vérification de la santé...$(NC)" @curl -f http://localhost:8080/health || echo "$(RED)❌ Application non accessible$(NC)" # Base de données migrate: ## Exécute les migrations de base de données @echo "$(GREEN)🗄️ Exécution des migrations...$(NC)" @go run cmd/migrate_tool/main.go @echo "$(GREEN)✅ Migrations terminées$(NC)" db-migrate: migrate ## Alias pour migrate db-seed: ## Peuple la base de données avec des données réalistes (1200 users, 5000 tracks) @echo "$(GREEN)🌱 Peuplement de la base de données...$(NC)" @go run ./cmd/tools/seed/ db-seed-minimal: ## Peuple la base avec un jeu réduit (50 users, 200 tracks) @echo "$(GREEN)🌱 Peuplement réduit...$(NC)" @go run ./cmd/tools/seed/ --minimal # Lab Environment migrate-lab: ## Applique les migrations en environnement Lab @echo "$(GREEN)🧪 Migrating Lab Database...$(NC)" @./scripts/apply_migrations_lab.sh run-lab: build ## Lance l'application en mode Lab (dégradé sans Redis/RabbitMQ bloquant) @echo "$(GREEN)🧪 Running Lab Server...$(NC)" @export DATABASE_URL=$${VEZA_LAB_DSN:-postgres://veza:veza_password@localhost:5432/veza_lab?sslmode=disable} && \ export APP_ENV=development && \ export JWT_SECRET=lab-insecure-secret-key-must-be-32-chars-long && \ export REDIS_URL=redis://localhost:6379/0 && \ export REDIS_ENABLE=false && \ export RABBITMQ_ENABLE=false && \ ./bin/$(BINARY_NAME) # Par défaut .DEFAULT_GOAL := help