blob: c868c637f690cb5d5acd7a6bcfaeeffadb7f1343 [file] [log] [blame] [edit]
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