name: CI Pipeline on: push: branches: [ main, develop ] pull_request: branches: [ main ] env: GO_VERSION: '1.21' CGO_ENABLED: 1 jobs: test: name: Run Tests runs-on: ubuntu-latest services: 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@v4 - name: Setup Go uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} - name: Cache Go modules uses: actions/cache@v3 with: path: | ~/.cache/go-build ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y sqlite3 bc curl jq go mod download - name: Run unit tests run: | go test -v -race -coverprofile=coverage.out -covermode=atomic ./... - name: Run integration tests run: | go test -v -tags=integration ./test/... -timeout 10m - name: Generate coverage report run: | go tool cover -html=coverage.out -o coverage.html - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: files: ./coverage.out fail_ci_if_error: true - name: Build application run: | go build -o bin/gateway cmd/gateway/main.go chmod +x bin/gateway - name: Upload build artifacts uses: actions/upload-artifact@v3 with: name: gateway-binary-${{ github.sha }} path: bin/gateway lint: name: Lint Code runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} - name: Run golangci-lint uses: golangci/golangci-lint-action@v3 with: version: latest args: --timeout=5m security: name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Gosec Security Scanner uses: securecodewarrior/github-action-gosec@master with: args: '-fmt sarif -out gosec.sarif ./...' - name: Upload SARIF file uses: github/codeql-action/upload-sarif@v2 with: sarif_file: gosec.sarif build-docker: name: Build Docker Images runs-on: ubuntu-latest needs: [test, lint] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . file: ./Dockerfile.prod push: true tags: | ghcr.io/${{ github.repository }}:latest ghcr.io/${{ github.repository }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max e2e-tests: name: E2E Tests runs-on: ubuntu-latest needs: [build-docker] steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup test environment run: | sudo apt-get update sudo apt-get install -y sqlite3 bc curl jq - name: Start services run: | docker-compose -f docker-compose.test.yml up -d - name: Wait for services run: | timeout 60 bash -c 'until curl -sf http://localhost:9876/api/health; do sleep 1; done' - name: Run E2E tests run: | chmod +x test/e2e/*.sh ./test/e2e/run_all_tests.sh - name: Collect logs on failure if: failure() run: | docker-compose -f docker-compose.test.yml logs - name: Stop services if: always() run: | docker-compose -f docker-compose.test.yml down -v