Skip to content

feat: add NodePool + Class configs #42

feat: add NodePool + Class configs

feat: add NodePool + Class configs #42

Workflow file for this run

name: "Terraform Validation"
on:
pull_request:
branches:
- main
paths:
- 'infra/**'
- '.github/workflows/terraform-*.yml'
permissions:
contents: read
pull-requests: write
id-token: write # Required for AWS OIDC
concurrency:
group: terraform-validate-${{ github.ref }}
cancel-in-progress: true
env:
TERRAFORM_VERSION: "1.15.8"
TERRAGRUNT_VERSION: "0.99.1"
jobs:
discover-changes:
name: Discover Changed Directories
runs-on: ubuntu-latest
outputs:
changed_dirs: ${{ steps.find-changes.outputs.changed_dirs }}
filter_args: ${{ steps.build-filters.outputs.filter_args }}
has_changes: ${{ steps.find-changes.outputs.has_changes }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find changed directories
id: find-changes
shell: bash
run: |
# Get the base branch
BASE_REF="${{ github.event.pull_request.base.sha }}"
HEAD_REF="${{ github.sha }}"
# Find all changed files in infra/
changed_files=$(git diff --name-only "$BASE_REF" "$HEAD_REF" -- infra/ || echo "")
if [ -z "$changed_files" ]; then
echo "No changes detected in infra/"
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "changed_dirs=[]" >> $GITHUB_OUTPUT
exit 0
fi
echo "Changed files:"
echo "$changed_files"
echo ""
# Find directories containing terragrunt.hcl files
terragrunt_dirs=$(find infra -type f -name "terragrunt.hcl" -not -path "*/.terraform/*" | sed 's|/terragrunt.hcl||' | sort -u)
# Identify which Terragrunt directories were affected
changed_dirs=""
while IFS= read -r file; do
file_dir=$(dirname "$file")
# Find the closest parent directory that contains a terragrunt.hcl
while [ "$file_dir" != "." ] && [ "$file_dir" != "infra" ]; do
if echo "$terragrunt_dirs" | grep -q "^$file_dir$"; then
changed_dirs="${changed_dirs}${file_dir}"$'\n'
break
fi
file_dir=$(dirname "$file_dir")
done
done <<< "$changed_files"
# Remove duplicates and sort
changed_dirs=$(echo "$changed_dirs" | sort -u | grep -v '^$' || echo "")
if [ -z "$changed_dirs" ]; then
# Changes were in infra but not in any terragrunt module directory
echo "Changes detected but not in terragrunt module directories"
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "changed_dirs=[]" >> $GITHUB_OUTPUT
else
echo "Changed Terragrunt directories:"
echo "$changed_dirs"
# Strip "infra/" prefix since terragrunt commands run from within infra/
changed_dirs_relative=$(echo "$changed_dirs" | sed 's|^infra/||')
echo "Relative paths (for filters):"
echo "$changed_dirs_relative"
# Convert to JSON array
changed_dirs_json=$(echo "$changed_dirs_relative" | jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "changed_dirs=$changed_dirs_json" >> $GITHUB_OUTPUT
fi
- name: Build filter arguments
id: build-filters
shell: bash
run: |
changed_dirs='${{ steps.find-changes.outputs.changed_dirs }}'
if [ "$changed_dirs" = "[]" ] || [ -z "$changed_dirs" ]; then
echo "filter_args=" >> $GITHUB_OUTPUT
exit 0
fi
# Build --filter arguments for each changed directory
filter_args=""
for dir in $(echo "$changed_dirs" | jq -r '.[]'); do
filter_args="${filter_args} --filter=${dir}"
done
# Trim leading space
filter_args=$(echo "$filter_args" | sed 's/^ //')
echo "Filter arguments: $filter_args"
echo "filter_args=$filter_args" >> $GITHUB_OUTPUT
validate:
name: Validate Infrastructure
needs: discover-changes
runs-on: ubuntu-latest
env:
# Repository Variables
TERRAGRUNT_ARGS: ${{ vars.TERRAGRUNT_ARGS }}
TERRAFORM_INIT_ARGS: ${{ vars.TERRAFORM_INIT_ARGS }}
TERRAFORM_VALIDATE_ARGS: ${{ vars.TERRAFORM_VALIDATE_ARGS }}
TERRAFORM_APPLY_ARGS: ${{ vars.TERRAFORM_APPLY_ARGS }}
CODER_TF_BACKEND_AWS_BUCKET_NAME: ${{ vars.CODER_TF_BACKEND_AWS_BUCKET_NAME }}
CODER_TF_BACKEND_AWS_REGION: ${{ vars.CODER_TF_BACKEND_AWS_REGION }}
CODER_TF_BACKEND_AWS_PROFILE: ${{ vars.CODER_TF_BACKEND_AWS_PROFILE }}
CODER_TF_BACKEND_ENCRYPT: ${{ vars.CODER_TF_BACKEND_ENCRYPT }}
CODER_AWS_PROFILE: ${{ vars.CODER_AWS_PROFILE }}
CODER_AWS_REGION: ${{ vars.CODER_AWS_REGION }}
CODER_AWS_AZS: ${{ vars.CODER_AWS_AZS }}
CODER_CLUSTER_NAME: ${{ vars.CODER_CLUSTER_NAME }}
CODER_CLUSTER_VERSION: ${{ vars.CODER_CLUSTER_VERSION }}
CODER_CLUSTER_INSTANCE_TYPE: ${{ vars.CODER_CLUSTER_INSTANCE_TYPE }}
CODER_VPC_NAME: ${{ vars.CODER_VPC_NAME }}
CODER_VPC_CIDR: ${{ vars.CODER_VPC_CIDR }}
CODER_VPC_AZS: ${{ vars.CODER_VPC_AZS }}
CODER_VPC_NAT_NAME: ${{ vars.CODER_VPC_NAT_NAME }}
CODER_DB_SUBNET_GROUP_NAME: ${{ vars.CODER_DB_SUBNET_GROUP_NAME }}
CODER_PUBLIC_SUBNET_SUFFIX: ${{ vars.CODER_PUBLIC_SUBNET_SUFFIX }}
CODER_PRIVATE_SUBNET_SUFFIX: ${{ vars.CODER_PRIVATE_SUBNET_SUFFIX }}
CODER_DB_RDS_ID: ${{ vars.CODER_DB_RDS_ID }}
CODER_DB_USERNAME: ${{ vars.CODER_DB_USERNAME }}
CODER_DB_NAME: ${{ vars.CODER_DB_NAME }}
CODER_IMAGE_REPO: ${{ vars.CODER_IMAGE_REPO }}
CODER_IMAGE_TAG: ${{ vars.CODER_IMAGE_TAG }}
LOKI_S3_BUCKET_NAME: ${{ vars.LOKI_S3_BUCKET_NAME }}
LOKI_S3_BUCKET_REGION: ${{ vars.LOKI_S3_BUCKET_REGION }}
GRAFANA_DOMAIN_NAME: ${{ vars.GRAFANA_DOMAIN_NAME }}
GRAFANA_DB_USERNAME: ${{ vars.GRAFANA_DB_USERNAME }}
CODER_DOMAIN_NAME: ${{ vars.CODER_DOMAIN_NAME }}
CODER_WILDCARD_URL: ${{ vars.CODER_WILDCARD_URL }}
CODER_LICENSE: ${{ vars.CODER_LICENSE }}
CODER_EXPERIMENTS: ${{ vars.CODER_EXPERIMENTS }}
CODER_BUILT_IN_PROVISIONER_COUNT: ${{ vars.CODER_BUILT_IN_PROVISIONER_COUNT }}
CODER_OIDC_SIGN_IN_TEXT: ${{ vars.CODER_OIDC_SIGN_IN_TEXT }}
CODER_OIDC_ICON_URL: ${{ vars.CODER_OIDC_ICON_URL }}
CODER_OIDC_SCOPES: ${{ vars.CODER_OIDC_SCOPES }}
CODER_OIDC_EMAIL_DOMAIN: ${{ vars.CODER_OIDC_EMAIL_DOMAIN }}
CODER_OIDC_ISSUER_URL: ${{ vars.CODER_OIDC_ISSUER_URL }}
# Secrets
CF_EMAIL: ${{ secrets.CF_EMAIL }}
CF_TOKEN: ${{ secrets.CF_TOKEN }}
CODER_GITHUB_EXTERN_AUTH_CLIENT_ID: ${{ secrets.CODER_GITHUB_EXTERN_AUTH_CLIENT_ID }}
CODER_GITHUB_EXTERN_AUTH_CLIENT_SECRET: ${{ secrets.CODER_GITHUB_EXTERN_AUTH_CLIENT_SECRET }}
CODER_GITHUB_OAUTH_CLIENT_ID: ${{ secrets.CODER_GITHUB_OAUTH_CLIENT_ID }}
CODER_GITHUB_OAUTH_CLIENT_SECRET: ${{ secrets.CODER_GITHUB_OAUTH_CLIENT_SECRET }}
CODER_OIDC_CLIENT_ID: ${{ secrets.CODER_OIDC_CLIENT_ID }}
CODER_OIDC_CLIENT_SECRET: ${{ secrets.CODER_OIDC_CLIENT_SECRET }}
CODER_RUNNER_TOKEN: ${{ secrets.CODER_RUNNER_TOKEN }}
GRAFANA_USER_PASSWORD: ${{ secrets.GRAFANA_USER_PASSWORD }}
VANTAGE_API_TOKEN: ${{ secrets.VANTAGE_API_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
- name: Setup Terragrunt
uses: gruntwork-io/terragrunt-action@v3
with:
tf_path: "terraform"
tg_version: ${{ env.TERRAGRUNT_VERSION }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6.2.3
with:
role-to-assume: ${{ vars.AWS_RUNNER_ROLE_ARN }}
aws-region: ${{ vars.AWS_RUNNER_REGION }}
aws-profile: ${{ vars.CODER_AWS_PROFILE }}
- name: Terragrunt hclfmt check
shell: bash
working-directory: infra
run: |
echo "::group::Checking Terragrunt formatting"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
echo "Filter args: $FILTER_ARGS"
if ! terragrunt hcl format --exclude-dir=.terraform --check; then
echo ""
echo "::error::Terragrunt files are not formatted."
echo "::error::Run 'terragrunt hclfmt' in the infra directory before pushing."
exit 1
fi
echo "✓ Terragrunt formatting is correct"
echo "::endgroup::"
- name: Terraform fmt check
shell: bash
working-directory: infra
run: |
echo "::group::Checking Terraform formatting"
if ! terraform fmt -check -recursive; then
echo ""
echo "::error::Terraform files are not formatted."
echo "::error::Run 'terraform fmt -recursive' in the infra directory before pushing."
exit 1
fi
echo "✓ Terraform formatting is correct"
echo "::endgroup::"
- name: Terragrunt validate-inputs
shell: bash
working-directory: infra
run: |
echo "::group::Validating Terragrunt inputs"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
# Build the full command with filters
CMD="terragrunt hcl validate --inputs"
if [ -n "$FILTER_ARGS" ]; then
CMD="$CMD $FILTER_ARGS"
fi
if [ -n "${TERRAGRUNT_ARGS}" ]; then
CMD="$CMD ${TERRAGRUNT_ARGS}"
fi
echo "Running: $CMD"
if ! eval "$CMD"; then
echo ""
echo "::error::Terragrunt inputs are not valid."
echo "::error::[View Full Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) to see what failed."
exit 1
fi
echo "✓ Terragrunt inputs are valid"
echo "::endgroup::"
- name: Terragrunt init
shell: bash
working-directory: infra
run: |
echo "::group::Initializing all modules"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
# Build the full command with filters
CMD="terragrunt run --all --queue-exclude-dir='./' --provider-cache"
if [ -n "$FILTER_ARGS" ]; then
CMD="$CMD $FILTER_ARGS"
fi
if [ -n "${TERRAGRUNT_ARGS}" ]; then
CMD="$CMD ${TERRAGRUNT_ARGS}"
fi
CMD="$CMD -- init -input=false -reconfigure -upgrade"
if [ -n "${TERRAFORM_INIT_ARGS}" ]; then
CMD="$CMD ${TERRAFORM_INIT_ARGS}"
fi
echo "Running: $CMD"
eval "$CMD"
echo "✓ Initialization successful"
echo "::endgroup::"
- name: Terragrunt validate
shell: bash
working-directory: infra
run: |
echo "::group::Validating Terraform configuration"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
# Build the full command with filters
CMD="terragrunt run --all --queue-exclude-dir='./' --provider-cache"
if [ -n "$FILTER_ARGS" ]; then
CMD="$CMD $FILTER_ARGS"
fi
if [ -n "${TERRAGRUNT_ARGS}" ]; then
CMD="$CMD ${TERRAGRUNT_ARGS}"
fi
CMD="$CMD -- validate"
if [ -n "${TERRAFORM_VALIDATE_ARGS}" ]; then
CMD="$CMD ${TERRAFORM_VALIDATE_ARGS}"
fi
echo "Running: $CMD"
eval "$CMD"
echo "✓ Terraform configuration is valid"
echo "::endgroup::"
plan:
name: Plan Infrastructure
needs: [validate, discover-changes]
runs-on: ubuntu-latest
env:
# Repository Variables
TERRAGRUNT_ARGS: ${{ vars.TERRAGRUNT_ARGS }}
TERRAFORM_PLAN_ARGS: ${{ vars.TERRAFORM_PLAN_ARGS }}
TERRAFORM_INIT_ARGS: ${{ vars.TERRAFORM_INIT_ARGS }}
CODER_TF_BACKEND_AWS_BUCKET_NAME: ${{ vars.CODER_TF_BACKEND_AWS_BUCKET_NAME }}
CODER_TF_BACKEND_AWS_REGION: ${{ vars.CODER_TF_BACKEND_AWS_REGION }}
CODER_TF_BACKEND_AWS_PROFILE: ${{ vars.CODER_TF_BACKEND_AWS_PROFILE }}
CODER_TF_BACKEND_ENCRYPT: ${{ vars.CODER_TF_BACKEND_ENCRYPT }}
CODER_AWS_PROFILE: ${{ vars.CODER_AWS_PROFILE }}
CODER_AWS_REGION: ${{ vars.CODER_AWS_REGION }}
CODER_AWS_AZS: ${{ vars.CODER_AWS_AZS }}
CODER_CLUSTER_NAME: ${{ vars.CODER_CLUSTER_NAME }}
CODER_CLUSTER_VERSION: ${{ vars.CODER_CLUSTER_VERSION }}
CODER_CLUSTER_INSTANCE_TYPE: ${{ vars.CODER_CLUSTER_INSTANCE_TYPE }}
CODER_VPC_NAME: ${{ vars.CODER_VPC_NAME }}
CODER_VPC_CIDR: ${{ vars.CODER_VPC_CIDR }}
CODER_VPC_AZS: ${{ vars.CODER_VPC_AZS }}
CODER_VPC_NAT_NAME: ${{ vars.CODER_VPC_NAT_NAME }}
CODER_DB_SUBNET_GROUP_NAME: ${{ vars.CODER_DB_SUBNET_GROUP_NAME }}
CODER_PUBLIC_SUBNET_SUFFIX: ${{ vars.CODER_PUBLIC_SUBNET_SUFFIX }}
CODER_PRIVATE_SUBNET_SUFFIX: ${{ vars.CODER_PRIVATE_SUBNET_SUFFIX }}
CODER_DB_RDS_ID: ${{ vars.CODER_DB_RDS_ID }}
CODER_DB_USERNAME: ${{ vars.CODER_DB_USERNAME }}
CODER_DB_NAME: ${{ vars.CODER_DB_NAME }}
CODER_IMAGE_REPO: ${{ vars.CODER_IMAGE_REPO }}
CODER_IMAGE_TAG: ${{ vars.CODER_IMAGE_TAG }}
LOKI_S3_BUCKET_NAME: ${{ vars.LOKI_S3_BUCKET_NAME }}
LOKI_S3_BUCKET_REGION: ${{ vars.LOKI_S3_BUCKET_REGION }}
GRAFANA_DOMAIN_NAME: ${{ vars.GRAFANA_DOMAIN_NAME }}
GRAFANA_DB_USERNAME: ${{ vars.GRAFANA_DB_USERNAME }}
CODER_DOMAIN_NAME: ${{ vars.CODER_DOMAIN_NAME }}
CODER_WILDCARD_URL: ${{ vars.CODER_WILDCARD_URL }}
CODER_LICENSE: ${{ vars.CODER_LICENSE }}
CODER_EXPERIMENTS: ${{ vars.CODER_EXPERIMENTS }}
CODER_BUILT_IN_PROVISIONER_COUNT: ${{ vars.CODER_BUILT_IN_PROVISIONER_COUNT }}
CODER_OIDC_SIGN_IN_TEXT: ${{ vars.CODER_OIDC_SIGN_IN_TEXT }}
CODER_OIDC_ICON_URL: ${{ vars.CODER_OIDC_ICON_URL }}
CODER_OIDC_SCOPES: ${{ vars.CODER_OIDC_SCOPES }}
CODER_OIDC_EMAIL_DOMAIN: ${{ vars.CODER_OIDC_EMAIL_DOMAIN }}
CODER_OIDC_ISSUER_URL: ${{ vars.CODER_OIDC_ISSUER_URL }}
# Secrets
CF_EMAIL: ${{ secrets.CF_EMAIL }}
CF_TOKEN: ${{ secrets.CF_TOKEN }}
CODER_GITHUB_EXTERN_AUTH_CLIENT_ID: ${{ secrets.CODER_GITHUB_EXTERN_AUTH_CLIENT_ID }}
CODER_GITHUB_EXTERN_AUTH_CLIENT_SECRET: ${{ secrets.CODER_GITHUB_EXTERN_AUTH_CLIENT_SECRET }}
CODER_GITHUB_OAUTH_CLIENT_ID: ${{ secrets.CODER_GITHUB_OAUTH_CLIENT_ID }}
CODER_GITHUB_OAUTH_CLIENT_SECRET: ${{ secrets.CODER_GITHUB_OAUTH_CLIENT_SECRET }}
CODER_OIDC_CLIENT_ID: ${{ secrets.CODER_OIDC_CLIENT_ID }}
CODER_OIDC_CLIENT_SECRET: ${{ secrets.CODER_OIDC_CLIENT_SECRET }}
CODER_RUNNER_TOKEN: ${{ secrets.CODER_RUNNER_TOKEN }}
GRAFANA_USER_PASSWORD: ${{ secrets.GRAFANA_USER_PASSWORD }}
VANTAGE_API_TOKEN: ${{ secrets.VANTAGE_API_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
terraform_wrapper: false
- name: Setup Terragrunt
uses: gruntwork-io/terragrunt-action@v3
with:
tf_path: "terraform"
tg_version: ${{ env.TERRAGRUNT_VERSION }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6.2.3
with:
role-to-assume: ${{ vars.AWS_RUNNER_ROLE_ARN }}
aws-region: ${{ vars.AWS_RUNNER_REGION }}
aws-profile: ${{ vars.CODER_AWS_PROFILE }}
- name: Terragrunt init
shell: bash
working-directory: infra
run: |
echo "::group::Initializing all modules"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
# Build the full command with filters
CMD="terragrunt run --all --queue-exclude-dir='./' --provider-cache"
if [ -n "$FILTER_ARGS" ]; then
CMD="$CMD $FILTER_ARGS"
fi
if [ -n "${TERRAGRUNT_ARGS}" ]; then
CMD="$CMD ${TERRAGRUNT_ARGS}"
fi
CMD="$CMD -- init -input=false -reconfigure -upgrade"
if [ -n "${TERRAFORM_INIT_ARGS}" ]; then
CMD="$CMD ${TERRAFORM_INIT_ARGS}"
fi
echo "Running: $CMD"
eval "$CMD"
echo "✓ Initialization successful"
echo "::endgroup::"
- name: Terragrunt plan
id: plan
shell: bash
working-directory: infra
run: |
echo "::group::Running Terragrunt plan on all modules"
FILTER_ARGS="${{ needs.discover-changes.outputs.filter_args }}"
# Build the full command with filters
CMD="terragrunt run --all --queue-exclude-dir='./' --provider-cache"
if [ -n "$FILTER_ARGS" ]; then
CMD="$CMD $FILTER_ARGS"
fi
if [ -n "${TERRAGRUNT_ARGS}" ]; then
CMD="$CMD ${TERRAGRUNT_ARGS}"
fi
CMD="$CMD -- plan -input=false -no-color -detailed-exitcode"
if [ -n "${TERRAFORM_PLAN_ARGS}" ]; then
CMD="$CMD ${TERRAFORM_PLAN_ARGS}"
fi
# Run plan and capture output
set +e
echo "Running: $CMD"
eval "$CMD" 2>&1 | tee plan.log
EXIT_CODE=${PIPESTATUS[0]}
set -e
echo "::endgroup::"
# Exit code meanings:
# 0 = succeeded with no changes
# 1 = error
# 2 = succeeded with changes
if [[ $EXIT_CODE -eq 0 ]]; then
echo "summary=No changes detected" >> "$GITHUB_OUTPUT"
echo "status=success" >> "$GITHUB_OUTPUT"
echo "✓ Plan succeeded with no changes"
elif [[ $EXIT_CODE -eq 2 ]]; then
echo "summary=Changes detected" >> "$GITHUB_OUTPUT"
echo "status=success" >> "$GITHUB_OUTPUT"
echo "✓ Plan succeeded with changes"
exit 0
else
echo "summary=Plan failed" >> "$GITHUB_OUTPUT"
echo "status=failure" >> "$GITHUB_OUTPUT"
echo "::error::Terraform plan failed"
exit 1
fi
- name: Upload plan log
if: always()
uses: actions/upload-artifact@v4
with:
name: plan-log
path: infra/plan.log
retention-days: 30
summary:
name: Validation Summary
needs: [discover-changes, validate, plan]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check validation results
shell: bash
run: |
echo "## Terraform Validation Summary"
echo ""
changed_dirs='${{ needs.discover-changes.outputs.changed_dirs }}'
has_changes="${{ needs.discover-changes.outputs.has_changes }}"
validate_result="${{ needs.validate.result }}"
plan_result="${{ needs.plan.result }}"
# Display changed directories
if [ "$has_changes" = "true" ] && [ "$changed_dirs" != "[]" ]; then
echo "Changed Terragrunt directories:"
echo "$changed_dirs" | jq -r '.[]' | sed 's/^/ - /'
echo ""
elif [ "$has_changes" = "true" ]; then
echo "Changes detected in infra/ but not in terragrunt module directories"
echo ""
else
echo "No changes detected in infra/"
echo ""
fi
echo "Validation result: $validate_result"
echo "Plan result: $plan_result"
echo ""
if [[ "$validate_result" == "success" ]] && [[ "$plan_result" == "success" ]]; then
echo "✅ All checks passed!"
echo "- Formatting is correct"
echo "- Configuration is valid"
echo "- Plan succeeded"
echo ""
echo "This PR is ready to merge."
exit 0
else
echo "❌ Validation or planning failed"
echo ""
if [[ "$validate_result" != "success" ]]; then
echo "- Validation failed: Check formatting and configuration"
fi
if [[ "$plan_result" != "success" ]]; then
echo "- Planning failed: Check plan output in job logs"
fi
echo ""
echo "Please fix the issues before merging."
exit 1
fi
- name: Post summary comment
if: always()
uses: actions/github-script@v7
with:
script: |
const changedDirs = JSON.parse('${{ needs.discover-changes.outputs.changed_dirs }}' || '[]');
const hasChanges = '${{ needs.discover-changes.outputs.has_changes }}' === 'true';
const validateResult = '${{ needs.validate.result }}';
const planResult = '${{ needs.plan.result }}';
let body = '## 🔍 Terraform Validation Summary\n\n';
// Show changed directories
if (hasChanges && changedDirs.length > 0) {
body += '### 📁 Changed Directories\n\n';
body += 'The following Terragrunt modules were affected:\n\n';
changedDirs.forEach(dir => {
body += `- \`${dir}\`\n`;
});
body += '\n';
} else if (hasChanges) {
body += '### ℹ️ Changes detected in `infra/` but not in terragrunt module directories\n\n';
} else {
body += '### ℹ️ No changes detected in `infra/`\n\n';
}
const allPassed = validateResult === 'success' && planResult === 'success';
if (allPassed) {
body += '### ✅ All validation checks passed!\n\n';
body += '- ✅ Formatting is correct\n';
body += '- ✅ Configuration is valid\n';
body += '- ✅ Plan succeeded\n\n';
body += '🚀 This PR is **ready to merge**. Infrastructure changes will be applied automatically after merge.\n';
} else {
body += '### ❌ Validation checks failed\n\n';
if (validateResult !== 'success') {
body += '- ❌ **Validation failed**: Check formatting and configuration errors in job logs\n';
}
if (planResult !== 'success') {
body += '- ❌ **Planning failed**: Review the plan output in job logs\n';
}
body += '\n⚠️ Please fix the issues before merging.\n';
}
body += `\n---\n*[View Full Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})*`;
// Find existing summary comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const summaryComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('🔍 Terraform Validation Summary')
);
if (summaryComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: summaryComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}