Default GitHub team members to member role, not maintainer (#80) #165
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: Platform CI | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'terraform/platform/**' | |
| - 'terraform/lambda-src/**' | |
| - 'scripts/**' | |
| - '.github/workflows/**' | |
| pull_request: | |
| schedule: | |
| # Drift detection — Monday 06:00 UTC (runs drift job only) | |
| - cron: '0 6 * * 1' | |
| workflow_dispatch: | |
| # Manual trigger — useful for syncing new repos immediately | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: platform-ci-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| TF_ROOT: terraform/platform | |
| AWS_REGION: eu-central-1 | |
| AWS_ACCOUNT_ID: "553637109631" | |
| PLAN_BUCKET: javabin-ci-plan-artifacts-553637109631 | |
| jobs: | |
| # -------------------------------------------------------------------------- | |
| # Plan — terraform init, validate, fmt, plan | |
| # -------------------------------------------------------------------------- | |
| plan: | |
| name: Terraform Plan | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'schedule' | |
| outputs: | |
| has_changes: ${{ steps.plan.outputs.has_changes }} | |
| plan_key: ${{ steps.upload.outputs.plan_key }} | |
| plan_sha256: ${{ steps.upload.outputs.plan_sha256 }} | |
| risk_level: ${{ steps.review.outputs.risk_level }} | |
| steps: | |
| - name: Set session name | |
| run: echo "SESSION_NAME=$(echo "${GITHUB_ACTOR}-${GITHUB_SHA:0:8}-${GITHUB_RUN_ID}" | head -c 64)" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for infra changes | |
| id: changes | |
| run: | | |
| BASE="${{ github.event.pull_request.base.sha || github.event.before || 'HEAD~1' }}" | |
| if git diff --name-only "$BASE" HEAD | grep -qE '^(terraform/|scripts/|\.github/workflows/)'; then | |
| echo "has_infra_changes=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_infra_changes=false" >> "$GITHUB_OUTPUT" | |
| echo "No infrastructure changes — skipping plan." | |
| fi | |
| - uses: hashicorp/setup-terraform@v4 | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| with: | |
| terraform_version: "1.7" | |
| terraform_wrapper: false | |
| - name: Configure AWS credentials via OIDC | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/javabin-ci-infra-plan | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-session-name: ${{ env.SESSION_NAME }} | |
| - name: Sync registered teams from GitHub org | |
| if: steps.changes.outputs.has_infra_changes == 'true' && github.ref == 'refs/heads/main' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: python3 scripts/sync-registered-teams.py "${{ env.TF_ROOT }}/registered-teams.auto.tfvars" || echo "Sync skipped — will use existing tfvars" | |
| - name: Terraform Init | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform init -input=false | |
| - name: Terraform Validate | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform validate | |
| - name: Terraform Format | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform fmt -recursive | |
| - name: Terraform Plan | |
| id: plan | |
| if: steps.changes.outputs.has_infra_changes == 'true' | |
| run: scripts/run-plan.sh "${{ env.TF_ROOT }}" -lock-timeout=5m | |
| - name: Upload plan and output to S3 | |
| id: upload | |
| if: steps.plan.outputs.has_changes == 'true' | |
| run: scripts/upload-plan.sh "${{ env.TF_ROOT }}" | |
| - name: Upload Lambda ZIPs as artifact | |
| if: steps.plan.outputs.has_changes == 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: lambda-zips | |
| path: ${{ env.TF_ROOT }}/lambdas/builds/ | |
| retention-days: 1 | |
| # ---------------------------------------------------------------- | |
| # LLM Plan Review (runs before PR comment so both are combined) | |
| # ---------------------------------------------------------------- | |
| - name: Run LLM review | |
| id: review | |
| if: steps.plan.outputs.has_changes == 'true' | |
| env: | |
| REVIEW_RESULT_PATH: review-result.json | |
| run: sh scripts/extract-review-risk.sh scripts/review-plan.py "${{ env.TF_ROOT }}/plan-output.txt" | |
| - name: Post plan + review to PR | |
| if: github.event_name == 'pull_request' && steps.changes.outputs.has_infra_changes == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: sh scripts/post-plan-comment.sh "${{ env.TF_ROOT }}/plan-output.txt" "${{ steps.plan.outputs.has_changes }}" | |
| - name: Post blocked risk to Slack | |
| if: (steps.review.outputs.risk_level == 'HIGH' || steps.review.outputs.risk_level == 'FAILED') && github.ref == 'refs/heads/main' | |
| run: sh scripts/notify-high-risk.sh /javabin/slack/platform-override-alerts-webhook "https://github.com/javaBin/platform/actions/workflows/approve-override.yml" | |
| # -------------------------------------------------------------------------- | |
| # Apply — auto-apply on LOW/MEDIUM, block on HIGH | |
| # -------------------------------------------------------------------------- | |
| apply: | |
| name: Terraform Apply | |
| runs-on: ubuntu-latest | |
| needs: plan | |
| if: >- | |
| github.ref == 'refs/heads/main' && | |
| github.event_name == 'push' && | |
| needs.plan.outputs.has_changes == 'true' | |
| environment: production | |
| steps: | |
| - name: Set session name | |
| run: echo "SESSION_NAME=$(echo "${GITHUB_ACTOR}-${GITHUB_SHA:0:8}-${GITHUB_RUN_ID}" | head -c 64)" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| - uses: hashicorp/setup-terraform@v4 | |
| with: | |
| terraform_version: "1.7" | |
| terraform_wrapper: false | |
| - uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/javabin-ci-infra | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-session-name: ${{ env.SESSION_NAME }} | |
| - name: Check risk level | |
| env: | |
| RISK: ${{ needs.plan.outputs.risk_level }} | |
| run: sh scripts/check-risk-block.sh "$RISK" | |
| - name: Download Lambda ZIPs from artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: lambda-zips | |
| path: ${{ env.TF_ROOT }}/lambdas/builds/ | |
| - name: Download plan from S3 | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: aws s3 cp "s3://${PLAN_BUCKET}/${{ needs.plan.outputs.plan_key }}" tfplan | |
| - name: Verify plan integrity | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: sh "${{ github.workspace }}/scripts/verify-plan.sh" tfplan "${{ needs.plan.outputs.plan_sha256 }}" | |
| - name: Terraform Init | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform init -input=false | |
| - name: Terraform Apply | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform apply -auto-approve -lock-timeout=5m tfplan | |
| # -------------------------------------------------------------------------- | |
| # Drift Detection — scheduled weekly, plan-only | |
| # -------------------------------------------------------------------------- | |
| drift: | |
| name: Drift Detection | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'schedule' | |
| steps: | |
| - name: Set session name | |
| run: echo "SESSION_NAME=$(echo "${GITHUB_ACTOR}-${GITHUB_SHA:0:8}-${GITHUB_RUN_ID}" | head -c 64)" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@v6 | |
| - uses: hashicorp/setup-terraform@v4 | |
| with: | |
| terraform_version: "1.7" | |
| terraform_wrapper: false | |
| - uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/javabin-ci-infra | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-session-name: ${{ env.SESSION_NAME }} | |
| - name: Terraform Init | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: terraform init -input=false | |
| - name: Check for drift | |
| working-directory: ${{ env.TF_ROOT }} | |
| run: sh "${{ github.workspace }}/scripts/drift-check.sh" /javabin/slack/platform-resource-alerts-webhook "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" |