name: CI/CD Pipeline on: push: branches: [master, develop] pull_request: branches: [master, 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.2.0 - name: Initialize CodeQL uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.12 with: languages: go - name: Setup Go uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35 # v5.4.0 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@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.12 # Linting (runs on PRs and pushes) lint: name: Lint runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.2.0 - name: Setup Go uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35 # v5.4.0 with: go-version: "1.25" cache: true - name: golangci-lint uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v6.1.1 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.2.0 - name: Setup Go uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35 # v5.4.0 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.2.0 - name: Setup Go uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35 # v5.4.0 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.2.0 - name: Setup Go ${{ matrix.go-version }} uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35 # v5.4.0 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 ./...