name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: # Security scanning with CodeQL (only on main branch pushes) security-scan: name: Security Scan runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' permissions: actions: read contents: read security-events: write steps: - name: Checkout code uses: actions/checkout@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: go - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.25" cache: true - name: Install dependencies run: go mod download - name: Build run: go build -v ./... - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 # Linting (runs on PRs and pushes) lint: name: Lint runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.25" cache: true - name: golangci-lint uses: golangci/golangci-lint-action@v6 with: version: latest args: --timeout=5m # Testing and coverage (runs on PRs and pushes) test: name: Test runs-on: ubuntu-latest services: postgres: image: postgres:15 env: POSTGRES_PASSWORD: postgres POSTGRES_DB: testdb options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 redis: image: redis:7-alpine ports: - 6379:6379 options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.25" cache: true - name: Install dependencies run: go mod download - name: Run tests with coverage run: | go test -v -race -coverprofile=coverage.out -covermode=atomic ./... go tool cover -html=coverage.out -o coverage.html - name: Upload coverage reports uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage.html retention-days: 30 # Build and verify (runs on PRs and pushes) build: name: Build runs-on: ubuntu-latest permissions: contents: read attestations: write id-token: write steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.25" cache: true - name: Install dependencies run: go mod download - name: Verify dependencies run: go mod verify - name: Build application run: | go build -v -o bin/tercul-backend ./cmd ls -la bin/ - name: Test build run: ./bin/tercul-backend --help || echo "Binary built successfully" - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: terbul-backend-binary path: bin/ retention-days: 30 # Matrix testing across Go versions (only on main branch pushes) test-matrix: name: Test Matrix (Go ${{ matrix.go-version }}) runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' strategy: matrix: go-version: ["1.22", "1.23", "1.24", "1.25"] services: postgres: image: postgres:15 env: POSTGRES_PASSWORD: postgres POSTGRES_DB: testdb options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 redis: image: redis:7-alpine ports: - 6379:6379 options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup Go ${{ matrix.go-version }} uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} cache: true - name: Install dependencies run: go mod download - name: Run tests run: go test -v -race ./... - name: Build run: go build -v ./...