Skip to content

Default GitHub team members to member role, not maintainer (#80) #165

Default GitHub team members to member role, not maintainer (#80)

Default GitHub team members to member role, not maintainer (#80) #165

Workflow file for this run

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 }}"