Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 0 additions & 75 deletions .github/workflows/commit-terraform.yml

This file was deleted.

21 changes: 4 additions & 17 deletions .github/workflows/javabin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,14 @@ jobs:
# 3. Docker build + ECR push (main only, after builds pass)
# --------------------------------------------------------------------------
docker-build:
needs: [detect, build-jvm, build-ts, tf-plan, plan-review, tf-apply]
needs: [detect, build-jvm, build-ts, tf-plan, tf-apply]
if: |
always() &&
github.ref == 'refs/heads/main' &&
needs.detect.outputs.has_docker == 'true' &&
(needs.build-jvm.result == 'success' || needs.build-jvm.result == 'skipped') &&
(needs.build-ts.result == 'success' || needs.build-ts.result == 'skipped') &&
needs.tf-plan.result != 'failure' &&
needs.plan-review.result != 'failure' &&
(needs.tf-apply.result == 'success' || needs.tf-apply.result == 'skipped')
uses: javaBin/platform/.github/workflows/docker-build.yml@main
secrets: inherit
Expand All @@ -79,25 +78,13 @@ jobs:
secrets: inherit

# --------------------------------------------------------------------------
# 5. LLM plan review (only when plan has changes)
# --------------------------------------------------------------------------
plan-review:
needs: tf-plan
if: needs.tf-plan.outputs.has_changes == 'true'
uses: javaBin/platform/.github/workflows/plan-review.yml@main
with:
plan_key: ${{ needs.tf-plan.outputs.plan_key }}
secrets: inherit

# --------------------------------------------------------------------------
# 6. Terraform apply (main only, after review — blocked on HIGH risk)
# 6. Terraform apply (main only, after plan + review — blocked on HIGH risk)
# --------------------------------------------------------------------------
tf-apply:
needs: [tf-plan, plan-review]
needs: tf-plan
if: >-
github.ref == 'refs/heads/main' &&
needs.tf-plan.outputs.has_changes == 'true' &&
needs.plan-review.result == 'success'
needs.tf-plan.outputs.has_changes == 'true'
uses: javaBin/platform/.github/workflows/tf-apply.yml@main
with:
plan_key: ${{ needs.tf-plan.outputs.plan_key }}
Expand Down
90 changes: 0 additions & 90 deletions .github/workflows/plan-review.yml

This file was deleted.

38 changes: 10 additions & 28 deletions .github/workflows/platform-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:
outputs:
has_changes: ${{ steps.plan.outputs.has_changes }}
plan_key: ${{ steps.upload.outputs.plan_key }}
plan_text_key: ${{ steps.upload.outputs.plan_text_key }}
plan_sha256: ${{ steps.upload.outputs.plan_sha256 }}
risk_level: ${{ steps.review.outputs.risk_level }}
steps:
- uses: actions/checkout@v5

Expand Down Expand Up @@ -97,52 +97,34 @@ jobs:
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 }}"

# --------------------------------------------------------------------------
# Review — LLM risk analysis via Bedrock
# --------------------------------------------------------------------------
review:
name: LLM Plan Review
runs-on: ubuntu-latest
needs: plan
if: needs.plan.outputs.has_changes == 'true'
outputs:
risk_level: ${{ steps.review.outputs.risk_level }}
steps:
- uses: actions/checkout@v5

- uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/javabin-ci-infra
aws-region: ${{ env.AWS_REGION }}
role-session-name: javabin-review-${{ github.run_id }}

- name: Download plan text from S3
run: mkdir -p "${{ env.TF_ROOT }}" && aws s3 cp "s3://${PLAN_BUCKET}/${{ needs.plan.outputs.plan_text_key }}" "${{ env.TF_ROOT }}/plan-output.txt"

# ----------------------------------------------------------------
# LLM Plan Review (inline — plan-output.txt already in workspace)
# ----------------------------------------------------------------
- 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 review to PR
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && steps.plan.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: sh scripts/post-review-comment.sh

- name: Post HIGH risk to Slack
if: steps.review.outputs.risk_level == 'HIGH' && github.ref == 'refs/heads/main'
run: sh scripts/notify-high-risk.sh /javabin/slack/platform-resource-alerts-webhook "https://github.com/javaBin/platform/actions/workflows/approve-override.yml"
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, review]
needs: plan
if: >-
github.ref == 'refs/heads/main' &&
github.event_name == 'push' &&
Expand All @@ -164,8 +146,8 @@ jobs:

- name: Check risk level
env:
RISK: ${{ needs.review.outputs.risk_level }}
run: sh scripts/check-risk-block.sh "$RISK" /javabin/slack/platform-override-alerts-webhook "https://github.com/${{ github.repository }}/actions/workflows/approve-override.yml"
RISK: ${{ needs.plan.outputs.risk_level }}
run: sh scripts/check-risk-block.sh "$RISK"

- name: Download Lambda ZIPs from artifact
uses: actions/download-artifact@v5
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/tf-plan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ on:
plan_sha256:
description: "SHA256 hash of the plan artifact"
value: ${{ jobs.plan.outputs.plan_sha256 }}
risk_level:
description: "Risk level from LLM review (LOW, MEDIUM, HIGH, FAILED)"
value: ${{ jobs.plan.outputs.risk_level }}

permissions:
id-token: write
Expand All @@ -38,6 +41,7 @@ jobs:
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 }}
env:
PLAN_BUCKET: javabin-ci-plan-artifacts-${{ inputs.aws_account_id }}
steps:
Expand Down Expand Up @@ -99,3 +103,31 @@ jobs:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: sh .platform/scripts/post-plan-comment.sh "${{ inputs.tf_root }}/plan-output.txt" "${{ steps.plan.outputs.has_changes }}"

# ----------------------------------------------------------------
# LLM Plan Review (runs in same job — plan-output.txt already here)
# ----------------------------------------------------------------
- name: Run LLM review
id: review
if: steps.plan.outputs.has_changes == 'true'
env:
REVIEW_RESULT_PATH: review-result.json
run: sh .platform/scripts/extract-review-risk.sh .platform/scripts/review-plan.py "${{ inputs.tf_root }}/plan-output.txt"

- name: Upload risk assessment to S3
if: steps.plan.outputs.has_changes == 'true' && steps.review.outputs.risk_level != ''
run: |
PLAN_DIR=$(dirname "${{ steps.upload.outputs.plan_key }}")
echo '{"level":"${{ steps.review.outputs.risk_level }}","reviewed_at":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}' | \
aws s3 cp - "s3://${PLAN_BUCKET}/${PLAN_DIR}/risk.json" --content-type application/json

- name: Post review to PR
if: github.event_name == 'pull_request' && steps.plan.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: sh .platform/scripts/post-review-comment.sh

- name: Alert Slack on HIGH risk
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.review.outputs.risk_level == 'HIGH'
run: sh .platform/scripts/notify-high-risk.sh /javabin/slack/platform-override-alerts-webhook "https://github.com/javaBin/platform/actions/workflows/approve-override.yml"
17 changes: 4 additions & 13 deletions scripts/check-risk-block.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
#!/bin/sh
# Block apply if risk is HIGH or FAILED. Notify Slack with override link.
# Block apply if risk is HIGH or FAILED.
#
# Usage: check-risk-block.sh <risk_level> <ssm_param> <override_url>
# Usage: check-risk-block.sh <risk_level>
#
# Exits 0 if safe to apply, 1 if blocked.
# Slack notification is handled by notify-high-risk.sh in the review step —
# no duplicate alert here.

set -e

RISK="$1"
SSM_PARAM="$2"
OVERRIDE_URL="$3"
SCRIPT_DIR=$(dirname "$0")

echo "LLM review risk: ${RISK}"

Expand All @@ -19,12 +18,4 @@ if [ "$RISK" != "HIGH" ] && [ "$RISK" != "FAILED" ] && [ -n "$RISK" ]; then
fi

echo "Auto-apply blocked (risk=${RISK})."

export SSM_WEBHOOK_PARAM="$SSM_PARAM"
sh "$SCRIPT_DIR/notify-slack.sh" \
"Deploy Blocked — ${RISK} Risk" \
"*Repo:* ${GITHUB_REPOSITORY}\n*SHA:* \`$(echo "$GITHUB_SHA" | cut -c1-8)\`\n*Actor:* ${GITHUB_ACTOR}" \
"$OVERRIDE_URL" \
"Approve Override" || true

exit 1
Loading
Loading