Bump nginx from 1.25-alpine to 1.29.8-alpine in /infrastructure #39
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CI: path-aware jobs, reproducible scans, Docker builds gated on tests | |
| name: ChaosLabs CI/CD | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: | |
| inputs: | |
| skip_tests: | |
| description: "Skip test execution" | |
| required: false | |
| default: "false" | |
| deploy_environment: | |
| description: "Deploy to environment" | |
| required: false | |
| default: "none" | |
| type: choice | |
| options: | |
| - none | |
| - staging | |
| - production | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY: ghcr.io | |
| GO_VERSION: "1.24.0" | |
| NODE_VERSION: "20" | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| go-changed: ${{ steps.changes.outputs.go }} | |
| frontend-changed: ${{ steps.changes.outputs.frontend }} | |
| infra-changed: ${{ steps.changes.outputs.infra }} | |
| tests-changed: ${{ steps.changes.outputs.tests }} | |
| should-deploy: ${{ steps.deploy-check.outputs.should-deploy }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: dorny/paths-filter@v3 | |
| id: changes | |
| with: | |
| filters: | | |
| go: | |
| - 'controller/**/*.go' | |
| - 'agent/**/*.go' | |
| - 'agent/cmd/**/*.go' | |
| - 'cli/**/*.go' | |
| - 'bench/**/*.go' | |
| - 'tests/**/*.go' | |
| - 'tests/**/go.mod' | |
| - 'tests/**/go.sum' | |
| - 'go.work' | |
| - 'go.work.sum' | |
| - '.golangci.yml' | |
| frontend: | |
| - 'dashboard-v2/**' | |
| infra: | |
| - 'infrastructure/**' | |
| - 'docker-compose*.yml' | |
| - '.github/workflows/**' | |
| - 'Dockerfile*' | |
| tests: | |
| - 'tests/**' | |
| - id: deploy-check | |
| run: | | |
| if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then | |
| echo "should-deploy=true" >> $GITHUB_OUTPUT | |
| elif [[ "${{ github.event.inputs.deploy_environment }}" != "none" ]]; then | |
| echo "should-deploy=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "should-deploy=false" >> $GITHUB_OUTPUT | |
| fi | |
| lint-go: | |
| name: Lint Go | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.go-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: | | |
| controller/go.sum | |
| agent/go.sum | |
| agent/cmd/doctor/go.sum | |
| cli/go.sum | |
| bench/go.sum | |
| - name: Install golangci-lint | |
| run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5 | |
| - name: Run golangci-lint | |
| run: | | |
| for d in controller agent cli bench; do | |
| echo "==> $d" | |
| (cd "$d" && golangci-lint run --timeout=5m --config=../.golangci.yml ./...) | |
| done | |
| lint-frontend: | |
| name: Lint Frontend | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.frontend-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: npm | |
| cache-dependency-path: dashboard-v2/package-lock.json | |
| - run: | | |
| cd dashboard-v2 | |
| npm ci --prefer-offline --no-audit | |
| npm run lint | |
| npm run type-check | |
| unit-tests: | |
| name: Unit Tests (${{ matrix.component }}) | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| needs.detect-changes.outputs.go-changed == 'true' && | |
| github.event.inputs.skip_tests != 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| component: [controller, agent, cli, agent/cmd/doctor] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: ${{ matrix.component }}/go.sum | |
| - name: Test | |
| working-directory: ${{ matrix.component }} | |
| run: go test -race -coverprofile=coverage.out -covermode=atomic ./... | |
| - name: Coverage HTML | |
| working-directory: ${{ matrix.component }} | |
| run: go tool cover -html=coverage.out -o coverage.html | |
| - uses: codecov/codecov-action@v4 | |
| continue-on-error: true | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./${{ matrix.component }}/coverage.out | |
| flags: ${{ matrix.component }} | |
| name: ${{ matrix.component }}-coverage | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: ${{ matrix.component }}-test-results | |
| path: | | |
| ${{ matrix.component }}/coverage.out | |
| ${{ matrix.component }}/coverage.html | |
| frontend-tests: | |
| name: Frontend Tests | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, lint-frontend] | |
| if: | | |
| needs.detect-changes.outputs.frontend-changed == 'true' && | |
| (needs.lint-frontend.result == 'success' || needs.lint-frontend.result == 'skipped') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: npm | |
| cache-dependency-path: dashboard-v2/package-lock.json | |
| - run: | | |
| cd dashboard-v2 | |
| npm ci --prefer-offline --no-audit | |
| npm run test:coverage | |
| - uses: codecov/codecov-action@v4 | |
| continue-on-error: true | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./dashboard-v2/coverage/lcov.info | |
| flags: frontend | |
| name: frontend-coverage | |
| - run: cd dashboard-v2; npm audit --audit-level=high | |
| continue-on-error: true | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| (needs.detect-changes.outputs.go-changed == 'true' || | |
| needs.detect-changes.outputs.infra-changed == 'true' || | |
| needs.detect-changes.outputs.tests-changed == 'true') && | |
| github.event.inputs.skip_tests != 'true' | |
| services: | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| nats: | |
| image: nats:2.10-alpine | |
| ports: | |
| - 4222:4222 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache-dependency-path: tests/integration/go.sum | |
| - name: Wait for Redis | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y redis-tools | |
| timeout 60s bash -c 'until redis-cli -h 127.0.0.1 -p 6379 ping 2>/dev/null | grep -q PONG; do sleep 1; done' | |
| - name: Run integration tests | |
| working-directory: tests/integration | |
| env: | |
| REDIS_URL: redis://127.0.0.1:6379 | |
| NATS_URL: nats://127.0.0.1:4222 | |
| run: go test -tags=integration -v -race ./... | |
| tests-ok: | |
| name: Tests gate | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, lint-go, unit-tests, integration-tests] | |
| if: always() | |
| steps: | |
| - name: Verify | |
| run: | | |
| g="${{ needs.detect-changes.outputs.go-changed }}" | |
| if [[ "$g" == "true" ]]; then | |
| [[ "${{ needs.lint-go.result }}" == "success" ]] || { echo "lint-go failed"; exit 1; } | |
| [[ "${{ needs.unit-tests.result }}" == "success" ]] || { echo "unit-tests failed"; exit 1; } | |
| fi | |
| if [[ "$g" == "true" || "${{ needs.detect-changes.outputs.tests-changed }}" == "true" || "${{ needs.detect-changes.outputs.infra-changed }}" == "true" ]]; then | |
| ir="${{ needs.integration-tests.result }}" | |
| if [[ "$ir" != "success" && "$ir" != "skipped" ]]; then | |
| echo "integration-tests failed" | |
| exit 1 | |
| fi | |
| fi | |
| echo "ok" | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.go-changed == 'true' || needs.detect-changes.outputs.infra-changed == 'true' | |
| permissions: | |
| security-events: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Install gosec | |
| run: go install github.com/securego/gosec/v2/cmd/gosec@v2.22.0 | |
| - name: Gosec (controller) | |
| working-directory: controller | |
| run: gosec -fmt sarif -out ../gosec-controller.sarif ./... | |
| continue-on-error: true | |
| - name: Upload SARIF (controller) | |
| if: hashFiles('gosec-controller.sarif') != '' | |
| uses: github/codeql-action/upload-sarif@v3 | |
| continue-on-error: true | |
| with: | |
| sarif_file: gosec-controller.sarif | |
| - name: govulncheck | |
| run: | | |
| go install golang.org/x/vuln/cmd/govulncheck@latest | |
| for d in controller agent cli bench; do | |
| echo "==> $d" | |
| (cd "$d" && govulncheck ./...) | |
| done | |
| echo "==> agent/cmd/doctor" | |
| (cd agent/cmd/doctor && govulncheck ./...) | |
| build-images: | |
| name: Build ${{ matrix.component }} image | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, tests-ok] | |
| if: | | |
| always() && !cancelled() && | |
| needs.tests-ok.result == 'success' && | |
| (needs.detect-changes.outputs.go-changed == 'true' || needs.detect-changes.outputs.infra-changed == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - component: controller | |
| target: production | |
| - component: agent | |
| target: runtime | |
| - component: dashboard | |
| target: runtime | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - uses: docker/login-action@v3 | |
| if: github.event_name == 'push' | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.component }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./infrastructure/Dockerfile.${{ matrix.component }}.optimized | |
| target: ${{ matrix.target }} | |
| platforms: linux/amd64 | |
| push: ${{ github.event_name == 'push' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=${{ matrix.component }} | |
| cache-to: type=gha,mode=max,scope=${{ matrix.component }} | |
| performance-tests: | |
| name: Performance Tests (k6) | |
| runs-on: ubuntu-latest | |
| needs: [build-images, detect-changes] | |
| if: | | |
| always() && !cancelled() && | |
| needs.build-images.result == 'success' && | |
| github.event.inputs.skip_tests != 'true' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install k6 | |
| run: | | |
| sudo gpg -k | |
| sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69 | |
| echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list | |
| sudo apt-get update | |
| sudo apt-get install -y k6 | |
| - name: Start test stack | |
| run: | | |
| docker compose --project-directory . -f infrastructure/docker-compose.test.yml up -d | |
| sleep 5 | |
| - name: k6 smoke | |
| run: | | |
| k6 run tests/performance/load-test.js | |
| k6 run tests/performance/stress-test.js | |
| - name: Cleanup | |
| if: always() | |
| run: docker compose --project-directory . -f infrastructure/docker-compose.test.yml down -v | |
| # Re-enable when a cluster and registry are ready. Prefer AWS/GitHub OIDC | |
| # (aws-actions/configure-aws-credentials with role-to-assume) over long-lived keys. | |
| deploy: | |
| name: Deploy (disabled) | |
| runs-on: ubuntu-latest | |
| needs: [build-images, performance-tests, detect-changes] | |
| if: false | |
| environment: | |
| name: ${{ github.event.inputs.deploy_environment || 'staging' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Apply Kubernetes manifests | |
| run: kubectl apply -f infrastructure/k8s/ | |
| report: | |
| name: CI Report | |
| runs-on: ubuntu-latest | |
| needs: [unit-tests, integration-tests, performance-tests, security, build-images, tests-ok] | |
| if: always() | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| continue-on-error: true | |
| with: | |
| path: artifacts | |
| - name: Write report | |
| run: | | |
| echo "## ChaosLabs CI report" > ci-report.md | |
| echo "- Tests gate: ${{ needs.tests-ok.result }}" >> ci-report.md | |
| echo "- Unit tests: ${{ needs.unit-tests.result }}" >> ci-report.md | |
| echo "- Integration: ${{ needs.integration-tests.result }}" >> ci-report.md | |
| echo "- Security: ${{ needs.security.result }}" >> ci-report.md | |
| echo "- Images: ${{ needs.build-images.result }}" >> ci-report.md | |
| echo "- k6: ${{ needs.performance-tests.result }}" >> ci-report.md | |
| - uses: thollander/comment-pull-request@v2 | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| with: | |
| filePath: ci-report.md | |
| comment_tag: chaoslabs-ci | |
| - uses: 8398a7/action-slack@v3 | |
| continue-on-error: true | |
| with: | |
| status: ${{ job.status }} | |
| channel: "#ci-cd" | |
| text: | | |
| ChaosLabs CI ${{ job.status }} — ${{ github.ref_name }} @ ${{ github.sha }} | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} |