diff --git a/.github/workflows/add-tf-integration-comment.yml b/.github/workflows/add-tf-integration-comment.yml new file mode 100644 index 0000000000..68b7929b27 --- /dev/null +++ b/.github/workflows/add-tf-integration-comment.yml @@ -0,0 +1,36 @@ +name: Add Terraform Integration Comment + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + pull-requests: write + +jobs: + post-comment: + runs-on: ubuntu-latest + steps: + - name: Upsert trigger comment + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR: ${{ github.event.pull_request.number }} + run: | + set -eu + marker="" + body=$(cat < /dev/null + else + gh api -X POST "/repos/${{ github.repository }}/issues/$PR/comments" \ + -f body="$body" > /dev/null + fi diff --git a/.github/workflows/terraform-integration.yml b/.github/workflows/terraform-integration.yml index 83811e24e4..a96dd56f4b 100644 --- a/.github/workflows/terraform-integration.yml +++ b/.github/workflows/terraform-integration.yml @@ -1,15 +1,8 @@ name: Terraform Integration -# Privileged terraform test/plan gated by the `terraform-privileged` environment -# (required reviewers configured in repo Settings). See MSRC #127928. - on: - pull_request_target: - paths: - - '**.tf' - - '**.json' - - '**.tfvars' - - 'modules/terraform/**' + issue_comment: + types: [created] permissions: contents: read @@ -19,8 +12,31 @@ env: TERRAFORM_AWS_MODULES_DIR: modules/terraform/aws jobs: + gate: + if: | + github.event.issue.pull_request != null && + github.event.comment.body == '/run-tf-integration' + runs-on: ubuntu-latest + steps: + - name: Check sender is authorized + env: + SENDER: ${{ github.event.comment.user.login }} + run: | + set -eu + curl -sf "https://raw.githubusercontent.com/${{ github.repository }}/main/CODEOWNERS" \ + | grep -v '^\s*#' | grep -v '^\s*$' | head -1 \ + | grep -oE '@[A-Za-z0-9_-]+' | tr -d '@' > /tmp/owners + echo "Authorized users:" + cat /tmp/owners + if grep -Fxq "$SENDER" /tmp/owners; then + echo "$SENDER is authorized" + else + echo "$SENDER is not authorized" + exit 1 + fi + terraform-test: - environment: terraform-privileged + needs: gate permissions: contents: read id-token: write @@ -29,8 +45,7 @@ jobs: - name: Checkout PR head uses: actions/checkout@v4 with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - ref: ${{ github.event.pull_request.head.sha }} + ref: refs/pull/${{ github.event.issue.number }}/head persist-credentials: false - name: Setup Terraform @@ -60,14 +75,14 @@ jobs: ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} setup-matrix: + needs: gate runs-on: ubuntu-latest name: Setup terraform plan matrix for test scenarios steps: - name: Checkout PR head uses: actions/checkout@v4 with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - ref: ${{ github.event.pull_request.head.sha }} + ref: refs/pull/${{ github.event.issue.number }}/head fetch-depth: 0 persist-credentials: false @@ -121,7 +136,6 @@ jobs: terraform-plan: needs: setup-matrix - environment: terraform-privileged permissions: id-token: write contents: read @@ -136,8 +150,7 @@ jobs: - name: Checkout PR head uses: actions/checkout@v4 with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - ref: ${{ github.event.pull_request.head.sha }} + ref: refs/pull/${{ github.event.issue.number }}/head persist-credentials: false - name: Setup Terraform @@ -175,3 +188,45 @@ jobs: env: ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} CLOUD: ${{ matrix.cloud }} + + report-status: + needs: [gate, terraform-test, setup-matrix, terraform-plan] + if: always() && needs.gate.result == 'success' + runs-on: ubuntu-latest + name: Terraform Integration Result + permissions: + statuses: write + pull-requests: read + steps: + - name: Post status back to PR head sha + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR: ${{ github.event.issue.number }} + TEST_RESULT: ${{ needs.terraform-test.result }} + SETUP_RESULT: ${{ needs.setup-matrix.result }} + PLAN_RESULT: ${{ needs.terraform-plan.result }} + run: | + set -eu + SHA=$(gh api "/repos/${{ github.repository }}/pulls/$PR" --jq '.head.sha') + echo "PR #$PR head sha: $SHA" + echo "terraform-test: $TEST_RESULT" + echo "setup-matrix : $SETUP_RESULT" + echo "terraform-plan: $PLAN_RESULT" + + state=success + for r in "$TEST_RESULT" "$SETUP_RESULT" "$PLAN_RESULT"; do + case "$r" in + success|skipped|"") ;; + *) state=failure ;; + esac + done + + gh api -X POST "/repos/${{ github.repository }}/statuses/$SHA" \ + -f state="$state" \ + -f context="Terraform Integration Result" \ + -f description="test=$TEST_RESULT setup=$SETUP_RESULT plan=$PLAN_RESULT" \ + -f target_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + + if [ "$state" != "success" ]; then + exit 1 + fi