CI Pipeline #75
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
| name: CI Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run nightly tests at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| env: | |
| GO_VERSION: '1.21' | |
| KUBERNETES_VERSION: 'v1.28.2' | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| # Static analysis and linting | |
| lint: | |
| name: Lint and Static Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up 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: go mod download | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v3 | |
| with: | |
| version: latest | |
| args: --timeout=5m | |
| - name: Run go vet | |
| run: go vet ./... | |
| - name: Run go fmt check | |
| run: | | |
| if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then | |
| echo "The following files need formatting:" | |
| gofmt -s -l . | |
| exit 1 | |
| fi | |
| - name: Check for security issues | |
| 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 | |
| # Unit tests | |
| unit-tests: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| go-version: ['1.20', '1.21'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: ${{ matrix.go-version }} | |
| - name: Cache Go modules | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go-${{ matrix.go-version }}- | |
| - name: Install dependencies | |
| run: go mod download | |
| - name: Run unit tests | |
| run: | | |
| go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... ./pkg/... | |
| - 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: | |
| file: ./coverage.out | |
| flags: unittests | |
| name: codecov-umbrella | |
| - name: Upload coverage artifacts | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: coverage-report-${{ matrix.go-version }} | |
| path: | | |
| coverage.out | |
| coverage.html | |
| # Build and test Docker images | |
| build-images: | |
| name: Build Docker Images | |
| runs-on: ubuntu-latest | |
| needs: [lint, unit-tests] | |
| outputs: | |
| admission-webhook-image: ${{ steps.meta-webhook.outputs.tags }} | |
| policy-manager-image: ${{ steps.meta-manager.outputs.tags }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for admission webhook | |
| id: meta-webhook | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/admission-webhook | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push admission webhook image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./build/docker/admission-webhook.Dockerfile | |
| push: true | |
| tags: ${{ steps.meta-webhook.outputs.tags }} | |
| labels: ${{ steps.meta-webhook.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Extract metadata for policy manager | |
| id: meta-manager | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/policy-manager | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push policy manager image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./build/docker/policy-manager.Dockerfile | |
| push: true | |
| tags: ${{ steps.meta-manager.outputs.tags }} | |
| labels: ${{ steps.meta-manager.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Integration tests | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up 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: go mod download | |
| - name: Set up test environment | |
| run: | | |
| # Install test dependencies | |
| go install github.com/onsi/ginkgo/v2/ginkgo@latest | |
| go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest | |
| - name: Run integration tests | |
| run: | | |
| export KUBEBUILDER_ASSETS=$(setup-envtest use ${{ env.KUBERNETES_VERSION }} --bin-dir /tmp/envtest-bins -p path) | |
| go test -v -race -coverprofile=coverage-integration.out ./test/integration/... | |
| - name: Upload integration test results | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: integration-test-results | |
| path: | | |
| coverage-integration.out | |
| test-results/ | |
| # End-to-end tests on Kind | |
| e2e-kind: | |
| name: E2E Tests (Kind) | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Install Kind | |
| run: | | |
| curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 | |
| chmod +x ./kind | |
| sudo mv ./kind /usr/local/bin/kind | |
| - name: Install kubectl | |
| run: | | |
| curl -LO "https://dl.k8s.io/release/${{ env.KUBERNETES_VERSION }}/bin/linux/amd64/kubectl" | |
| chmod +x kubectl | |
| sudo mv kubectl /usr/local/bin/ | |
| - name: Install Helm | |
| run: | | |
| curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash | |
| - name: Run Kind E2E tests | |
| run: | | |
| export CLEANUP=false | |
| ./scripts/test/test-kind.sh | |
| - name: Collect test artifacts | |
| if: always() | |
| run: | | |
| mkdir -p artifacts/kind | |
| cp -r test-results/kind/* artifacts/kind/ || true | |
| kubectl get pods -A -o wide > artifacts/kind/final-pods.txt || true | |
| kubectl get events -A --sort-by='.lastTimestamp' > artifacts/kind/final-events.txt || true | |
| - name: Upload Kind test artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: kind-test-artifacts | |
| path: artifacts/kind/ | |
| # End-to-end tests on k3s | |
| e2e-k3s: | |
| name: E2E Tests (k3s) | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Install kubectl | |
| run: | | |
| curl -LO "https://dl.k8s.io/release/${{ env.KUBERNETES_VERSION }}/bin/linux/amd64/kubectl" | |
| chmod +x kubectl | |
| sudo mv kubectl /usr/local/bin/ | |
| - name: Install Helm | |
| run: | | |
| curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash | |
| - name: Run k3s E2E tests | |
| run: | | |
| export CLEANUP=false | |
| sudo ./scripts/test/test-k3s.sh | |
| - name: Collect test artifacts | |
| if: always() | |
| run: | | |
| mkdir -p artifacts/k3s | |
| sudo cp -r test-results/k3s/* artifacts/k3s/ || true | |
| sudo kubectl get pods -A -o wide > artifacts/k3s/final-pods.txt || true | |
| sudo kubectl get events -A --sort-by='.lastTimestamp' > artifacts/k3s/final-events.txt || true | |
| - name: Upload k3s test artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: k3s-test-artifacts | |
| path: artifacts/k3s/ | |
| # Security scanning | |
| security-scan: | |
| name: Security Scanning | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload Trivy scan results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Scan admission webhook image | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ needs.build-images.outputs.admission-webhook-image }} | |
| format: 'sarif' | |
| output: 'trivy-webhook.sarif' | |
| - name: Scan policy manager image | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ needs.build-images.outputs.policy-manager-image }} | |
| format: 'sarif' | |
| output: 'trivy-manager.sarif' | |
| # Performance tests | |
| performance-tests: | |
| name: Performance Tests | |
| runs-on: ubuntu-latest | |
| needs: [e2e-kind] | |
| if: github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'performance') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| - name: Install Kind | |
| run: | | |
| curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 | |
| chmod +x ./kind | |
| sudo mv ./kind /usr/local/bin/kind | |
| - name: Install kubectl | |
| run: | | |
| curl -LO "https://dl.k8s.io/release/${{ env.KUBERNETES_VERSION }}/bin/linux/amd64/kubectl" | |
| chmod +x kubectl | |
| sudo mv kubectl /usr/local/bin/ | |
| - name: Install Helm | |
| run: | | |
| curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash | |
| - name: Run performance tests | |
| run: | | |
| export CLEANUP=false | |
| ./scripts/test/test-kind.sh | |
| # Run additional performance benchmarks | |
| go test -bench=. -benchmem ./internal/... ./pkg/... > performance-results.txt | |
| - name: Upload performance results | |
| uses: actions/upload-artifact@v3 | |
| with: | |
| name: performance-results | |
| path: performance-results.txt | |
| # Helm chart testing | |
| helm-tests: | |
| name: Helm Chart Tests | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Helm | |
| run: | | |
| curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash | |
| - name: Install chart-testing | |
| run: | | |
| curl -sSLo ct.tar.gz https://github.com/helm/chart-testing/releases/download/v3.9.0/chart-testing_3.9.0_linux_amd64.tar.gz | |
| tar -xzf ct.tar.gz | |
| sudo mv ct /usr/local/bin/ | |
| - name: Lint Helm charts | |
| run: | | |
| ct lint --config .github/ct.yaml | |
| - name: Install Kind | |
| run: | | |
| curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 | |
| chmod +x ./kind | |
| sudo mv ./kind /usr/local/bin/kind | |
| - name: Create Kind cluster for chart testing | |
| run: | | |
| kind create cluster --name chart-testing | |
| - name: Test Helm charts | |
| run: | | |
| ct install --config .github/ct.yaml | |
| # Documentation tests | |
| docs-tests: | |
| name: Documentation Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Check for broken links | |
| uses: gaurav-nelson/github-action-markdown-link-check@v1 | |
| with: | |
| use-quiet-mode: 'yes' | |
| use-verbose-mode: 'yes' | |
| config-file: '.github/mlc_config.json' | |
| - name: Validate YAML files | |
| run: | | |
| find . -name "*.yaml" -o -name "*.yml" | xargs -I {} sh -c 'echo "Validating {}" && python -c "import yaml; yaml.safe_load(open(\"{}\"))"' | |
| - name: Check Helm chart documentation | |
| run: | | |
| helm-docs --check | |
| # Release preparation | |
| prepare-release: | |
| name: Prepare Release | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: [lint, unit-tests, integration-tests, e2e-kind, e2e-k3s, security-scan, helm-tests, docs-tests] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Generate changelog | |
| run: | | |
| # Generate changelog using conventional commits | |
| npx conventional-changelog-cli -p angular -i CHANGELOG.md -s | |
| - name: Create release PR | |
| if: contains(github.event.head_commit.message, 'feat:') || contains(github.event.head_commit.message, 'fix:') | |
| uses: peter-evans/create-pull-request@v5 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| commit-message: 'chore: update changelog for release' | |
| title: 'chore: prepare release' | |
| body: | | |
| This PR prepares a new release with the following changes: | |
| - Updated changelog | |
| - Version bump (if applicable) | |
| Please review and merge to trigger the release process. | |
| branch: prepare-release | |
| delete-branch: true | |
| # Notification | |
| notify: | |
| name: Notify Results | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: [lint, unit-tests, integration-tests, e2e-kind, e2e-k3s, security-scan, helm-tests, docs-tests] | |
| steps: | |
| - name: Notify Slack on failure | |
| if: failure() | |
| uses: 8398a7/action-slack@v3 | |
| with: | |
| status: failure | |
| channel: '#kube-policies-ci' | |
| webhook_url: ${{ secrets.SLACK_WEBHOOK }} | |
| fields: repo,message,commit,author,action,eventName,ref,workflow | |
| - name: Notify Slack on success | |
| if: success() && github.ref == 'refs/heads/main' | |
| uses: 8398a7/action-slack@v3 | |
| with: | |
| status: success | |
| channel: '#kube-policies-ci' | |
| webhook_url: ${{ secrets.SLACK_WEBHOOK }} | |
| fields: repo,message,commit,author,action,eventName,ref,workflow | |