| name: "Terraform: CI Pipelines Infrastructure" |
| |
| on: |
| pull_request: |
| paths: ["buildkite/terraform/**"] |
| push: |
| branches: ["master"] |
| paths: ["buildkite/terraform/**"] |
| |
| # go/github-security: Explicitly set minimum permissions |
| permissions: |
| contents: read # Required to check out the code |
| id-token: write # Required for Workload Identity Federation (WIF) |
| pull-requests: write # Required to post plan output as a comment |
| |
| jobs: |
| # Job 1: Detect which organization folders changed |
| detect-changes: |
| runs-on: ubuntu-latest |
| outputs: |
| orgs: ${{ steps.process-orgs.outputs.orgs }} |
| steps: |
| - name: Checkout Code |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
| with: |
| fetch-depth: 0 |
| |
| - name: Get Changed Files |
| id: changed-files |
| uses: tj-actions/changed-files@48d8f15b2aaa3d255ca5af3eba4870f807ce6b3c # v45 |
| with: |
| files: buildkite/terraform/** |
| |
| - name: Extract Orgs |
| id: process-orgs |
| shell: bash |
| run: | |
| CHANGED_FILES="${{ steps.changed-files.outputs.all_changed_files }}" |
| |
| # Pull Specific Orgs -> Cut Org Name -> Sort Unique -> JSON Array |
| ORGS=$(echo "$CHANGED_FILES" | tr ' ' '\n' | \ |
| grep -E -o "^buildkite/terraform/(bazel|bazel-trusted|bazel-testing)/" | cut -d/ -f3 | sort -u | \ |
| jq -R -s -c 'split("\n") | map(select(length > 0))') |
| |
| echo "DEBUG:ORGS changed are: $ORGS" |
| echo "DEBUG:Event Name is: ${{ github.event_name }}" |
| echo "DEBUG:Author is: ${{ github.event.pull_request.author_association }}" |
| echo "orgs=${ORGS:-[]}" >> "$GITHUB_OUTPUT" |
| |
| # Job 2: Terraform Execution |
| terraform: |
| needs: detect-changes |
| # Run only if we have changed orgs AND (it's a push to master OR PR from trusted users) |
| if: needs.detect-changes.outputs.orgs != '[]' |
| runs-on: ubuntu-latest |
| |
| # Lock per organization. Cancels old runs on PRs (saves time), but queues pushes (safe apply). |
| concurrency: |
| group: ${{ github.workflow }}-${{ matrix.org }}-${{ github.ref }} |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} |
| |
| # Use environment for secret isolation and manual approvals |
| environment: ${{ matrix.org }} |
| strategy: |
| fail-fast: false # If one org fails, don't stop the others |
| matrix: |
| org: ${{ fromJSON(needs.detect-changes.outputs.orgs) }} |
| |
| defaults: |
| run: |
| working-directory: ./buildkite/terraform/${{ matrix.org }} |
| |
| steps: |
| - name: Checkout Code |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 |
| |
| #TODO: change this back to WIP once the provider request is approved |
| - name: Authenticate to Google Cloud |
| uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 |
| with: |
| credentials_json: '${{ secrets.GCP_SA_KEY }}' |
| |
| - name: Setup Terraform |
| uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 |
| with: |
| terraform_wrapper: true |
| terraform_version: "1.9.5" |
| |
| - name: Terraform Init |
| run: terraform init |
| |
| - name: Terraform Plan |
| if: github.event_name == 'pull_request' |
| id: plan |
| env: |
| TF_VAR_buildkite_api_token: ${{ secrets.BUILDKITE_API_TOKEN }} |
| run: terraform plan -no-color -input=false |
| |
| - name: Post Plan to PR |
| if: github.event_name == 'pull_request' |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 |
| env: |
| PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" |
| with: |
| script: | |
| const output = `#### Terraform Plan for \`${{ matrix.org }}\` 📖 |
| <details><summary>Show Plan</summary> |
| |
| \`\`\`${process.env.PLAN}\`\`\` |
| |
| </details> |
| |
| *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; |
| |
| github.rest.issues.createComment({ |
| issue_number: context.issue.number, |
| owner: context.repo.owner, |
| repo: context.repo.repo, |
| body: output |
| }) |
| |
| - name: Terraform Apply |
| if: github.ref == 'refs/heads/master' && github.event_name == 'push' |
| env: |
| TF_VAR_buildkite_api_token: ${{ secrets.BUILDKITE_API_TOKEN }} |
| run: terraform apply -auto-approve -input=false |