chore(deps): bump the github-actions group with 2 updates #79
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: Deploy Complete Coder Environment | |
| # Set minimal required permissions for security | |
| permissions: | |
| contents: read # Access repository code | |
| issues: write # Create deployment failure issues | |
| pull-requests: write # Comment on PRs with deployment status | |
| actions: read # Download/upload artifacts | |
| id-token: write # For OIDC authentication if needed | |
| security-events: write # Upload SARIF security scan results | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| bucket_name: | |
| description: 'Name of the bucket in object store that will hold Terraform state' | |
| required: false | |
| type: string | |
| environment: | |
| description: 'Target environment' | |
| required: true | |
| type: choice | |
| options: | |
| - dev | |
| - staging | |
| - prod | |
| region: | |
| description: 'Scaleway region' | |
| required: true | |
| type: choice | |
| options: | |
| - fr-par | |
| - nl-ams | |
| - pl-waw | |
| default: 'fr-par' | |
| availability_zone: | |
| description: 'Scaleway availibility zone (which should be within region)' | |
| required: true | |
| type: choice | |
| options: | |
| - fr-par-1 | |
| - fr-par-2 | |
| - fr-par-3 | |
| - nl-ams-1 | |
| - nl-ams-2 | |
| - nl-ams-3 | |
| - pl-waw-1 | |
| - pl-waw-2 | |
| - pl-waw-3 | |
| default: 'fr-par-1' | |
| template: | |
| description: 'Workspace template to deploy (leave empty to skip)' | |
| required: false | |
| type: string | |
| domain_name: | |
| description: 'Domain name for SSL certificates (leave empty for IP-based access)' | |
| required: false | |
| type: string | |
| subdomain: | |
| description: 'Subdomain prefix (defaults: dev=coder-dev, staging=coder-staging, prod=coder)' | |
| required: false | |
| type: string | |
| dry_run: | |
| description: 'Preview changes without applying' | |
| required: false | |
| type: boolean | |
| default: false | |
| skip_coder_deployment: | |
| description: 'Deploy infrastructure only (skip Coder application)' | |
| required: false | |
| type: boolean | |
| default: false | |
| advanced_config: | |
| description: 'Advanced configuration as JSON (see docs/ADVANCED_CONFIG.md for schema)' | |
| required: false | |
| type: string | |
| default: '{}' | |
| # Allow manual PR triggers for staging deployments | |
| pull_request: | |
| types: [opened, synchronize, labeled] | |
| paths: | |
| - 'environments/**' | |
| - 'modules/**' | |
| - 'templates/**' | |
| - 'scripts/**' | |
| - '.github/workflows/deploy-*.yml' | |
| # Auto-deploy on push to main for staging | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'environments/staging/**' | |
| - 'modules/**' | |
| jobs: | |
| # Parallel validation jobs for faster feedback | |
| pre-validate: | |
| name: Pre-validate Configuration | |
| runs-on: ubuntu-latest | |
| outputs: | |
| validation_passed: ${{ steps.validate.outputs.passed }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v5 | |
| - name: Cache Tools and Dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.terraform.d/plugin-cache | |
| /usr/local/bin/kubectl | |
| /usr/local/bin/helm | |
| key: tools-${{ runner.os }}-terraform-1.13.0-kubectl-1.32.0-helm-3.12.0 | |
| - name: Quick Syntax Validation | |
| id: validate | |
| run: | | |
| echo "🔍 Running quick syntax validation..." | |
| # Check for basic syntax issues | |
| if find . -name "*.tf" -exec terraform fmt -check {} \; 2>/dev/null; then | |
| echo "✅ Terraform syntax check passed" | |
| else | |
| echo "⚠️ Terraform formatting issues detected (will be checked in detail later)" | |
| fi | |
| # Check for basic YAML syntax | |
| if command -v yamllint >/dev/null 2>&1; then | |
| yamllint .github/workflows/ || echo "⚠️ YAML formatting issues detected" | |
| fi | |
| echo "passed=true" >> $GITHUB_OUTPUT | |
| determine-strategy: | |
| name: Determine Deployment Strategy | |
| runs-on: ubuntu-latest | |
| outputs: | |
| deploy_env: ${{ steps.determine-env.outputs.environment }} | |
| deploy_template: ${{ steps.determine-env.outputs.template }} | |
| deploy_domain: ${{ steps.determine-env.outputs.domain_name }} | |
| deploy_subdomain: ${{ steps.determine-env.outputs.subdomain }} | |
| enable_monitoring: ${{ steps.determine-env.outputs.enable_monitoring }} | |
| skip_coder: ${{ steps.determine-env.outputs.skip_coder }} | |
| dry_run: ${{ steps.determine-env.outputs.dry_run }} | |
| deploy_region: ${{ steps.determine-env.outputs.region }} | |
| deploy_zone: ${{ steps.determine-env.outputs.availability_zone }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v5 | |
| - name: Parse Advanced Configuration | |
| id: parse-config | |
| run: | | |
| # Parse advanced configuration JSON | |
| advanced_config='${{ github.event.inputs.advanced_config || '{}' }}' | |
| echo "📋 Parsing advanced configuration..." | |
| echo "Raw config: $advanced_config" | |
| # Extract monitoring configuration with fallback | |
| enable_monitoring=$(echo "$advanced_config" | jq -r '.monitoring.enabled // false') | |
| # Extract security configuration | |
| management_cidr=$(echo "$advanced_config" | jq -r '.security.management_cidr // ""') | |
| trusted_cidr=$(echo "$advanced_config" | jq -r '.security.trusted_cidr // ""') | |
| pod_security_standard=$(echo "$advanced_config" | jq -r '.security.pod_security_standard // "baseline"') | |
| enable_pod_security_standards=$(echo "$advanced_config" | jq -r '.security.enable_pod_security_standards // true') | |
| enable_network_policies=$(echo "$advanced_config" | jq -r '.security.enable_network_policies // true') | |
| # Extract secret management configuration | |
| use_external_secrets=$(echo "$advanced_config" | jq -r '.secrets.use_external_secrets // false') | |
| # Extract cost optimization configuration | |
| cost_optimization_enabled=$(echo "$advanced_config" | jq -r '.cost_optimization.enabled // false') | |
| volume_type=$(echo "$advanced_config" | jq -r '.cost_optimization.volume_type // "lssd"') | |
| # Set outputs | |
| echo "enable_monitoring=$enable_monitoring" >> $GITHUB_OUTPUT | |
| echo "management_cidr=$management_cidr" >> $GITHUB_OUTPUT | |
| echo "trusted_cidr=$trusted_cidr" >> $GITHUB_OUTPUT | |
| echo "pod_security_standard=$pod_security_standard" >> $GITHUB_OUTPUT | |
| echo "enable_pod_security_standards=$enable_pod_security_standards" >> $GITHUB_OUTPUT | |
| echo "enable_network_policies=$enable_network_policies" >> $GITHUB_OUTPUT | |
| echo "use_external_secrets=$use_external_secrets" >> $GITHUB_OUTPUT | |
| echo "cost_optimization_enabled=$cost_optimization_enabled" >> $GITHUB_OUTPUT | |
| echo "volume_type=$volume_type" >> $GITHUB_OUTPUT | |
| - name: Determine Deployment Strategy | |
| id: determine-env | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| echo "🎯 Manual workflow dispatch detected" | |
| echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT | |
| echo "template=${{ github.event.inputs.template }}" >> $GITHUB_OUTPUT | |
| echo "domain_name=${{ github.event.inputs.domain_name }}" >> $GITHUB_OUTPUT | |
| echo "subdomain=${{ github.event.inputs.subdomain }}" >> $GITHUB_OUTPUT | |
| echo "enable_monitoring=${{ steps.parse-config.outputs.enable_monitoring }}" >> $GITHUB_OUTPUT | |
| echo "skip_coder=${{ github.event.inputs.skip_coder_deployment }}" >> $GITHUB_OUTPUT | |
| echo "dry_run=${{ github.event.inputs.dry_run }}" >> $GITHUB_OUTPUT | |
| echo "region=${{ github.event.inputs.region }}" >> $GITHUB_OUTPUT | |
| echo "availability_zone=${{ github.event.inputs.availability_zone }}" >> $GITHUB_OUTPUT | |
| elif [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| echo "🔄 Pull request event detected" | |
| if [[ "${{ contains(github.event.pull_request.labels.*.name, 'deploy-staging') }}" == "true" ]]; then | |
| # Check if auto staging deployment is enabled | |
| if [[ "${{ secrets.ENABLE_AUTO_STAGING_DEPLOY }}" == "true" ]]; then | |
| echo "🚀 Auto staging deployment ENABLED for PR with 'deploy-staging' label" | |
| echo "📋 Deployment triggered by: pull request with deploy-staging label" | |
| echo "environment=staging" >> $GITHUB_OUTPUT | |
| echo "template=" >> $GITHUB_OUTPUT | |
| echo "domain_name=" >> $GITHUB_OUTPUT | |
| echo "subdomain=" >> $GITHUB_OUTPUT | |
| echo "enable_monitoring=false" >> $GITHUB_OUTPUT | |
| echo "skip_coder=false" >> $GITHUB_OUTPUT | |
| echo "dry_run=false" >> $GITHUB_OUTPUT | |
| echo "region=fr-par" >> $GITHUB_OUTPUT | |
| echo "availability_zone=fr-par-1" >> $GITHUB_OUTPUT | |
| else | |
| echo "⏸️ Auto staging deployment DISABLED - skipping PR deployment" | |
| echo "💡 Set ENABLE_AUTO_STAGING_DEPLOY secret to 'true' to enable automatic deployments" | |
| echo "environment=" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| else | |
| echo "ℹ️ PR does not have 'deploy-staging' label - skipping deployment" | |
| exit 0 | |
| fi | |
| elif [[ "${{ github.event_name }}" == "push" ]]; then | |
| echo "📤 Push event detected on branch: ${{ github.ref_name }}" | |
| # Check if auto staging deployment is enabled | |
| if [[ "${{ secrets.ENABLE_AUTO_STAGING_DEPLOY }}" == "true" ]]; then | |
| echo "🚀 Auto staging deployment ENABLED - proceeding with deployment" | |
| echo "📋 Deployment triggered by: push to ${{ github.ref_name }} branch" | |
| echo "environment=staging" >> $GITHUB_OUTPUT | |
| echo "template=" >> $GITHUB_OUTPUT | |
| echo "domain_name=" >> $GITHUB_OUTPUT | |
| echo "subdomain=" >> $GITHUB_OUTPUT | |
| echo "enable_monitoring=true" >> $GITHUB_OUTPUT | |
| echo "skip_coder=false" >> $GITHUB_OUTPUT | |
| echo "dry_run=false" >> $GITHUB_OUTPUT | |
| echo "region=fr-par" >> $GITHUB_OUTPUT | |
| echo "availability_zone=fr-par-1" >> $GITHUB_OUTPUT | |
| else | |
| echo "⏸️ Auto staging deployment DISABLED - skipping deployment" | |
| echo "💡 Set ENABLE_AUTO_STAGING_DEPLOY secret to 'true' to enable automatic deployments" | |
| echo "📝 To deploy manually, use the 'Deploy Complete Coder Environment' workflow" | |
| echo "environment=" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| fi | |
| - name: Display Deployment Plan | |
| run: | | |
| echo "🚀 Complete Environment Deployment Plan" | |
| echo "========================================" | |
| echo "" | |
| echo "📋 Deployment Configuration:" | |
| echo " Environment: ${{ steps.determine-env.outputs.environment }}" | |
| echo " Template: ${{ steps.determine-env.outputs.template || 'None specified' }}" | |
| echo " Domain: ${{ steps.determine-env.outputs.domain_name || 'IP-based access' }}" | |
| echo " Subdomain: ${{ steps.determine-env.outputs.subdomain || 'Auto-generated' }}" | |
| echo " Monitoring: ${{ steps.determine-env.outputs.enable_monitoring }}" | |
| echo " Skip Coder: ${{ steps.determine-env.outputs.skip_coder }}" | |
| echo " Dry Run: ${{ steps.determine-env.outputs.dry_run }}" | |
| echo "" | |
| echo "🔄 Deployment Phases:" | |
| echo " Phase 1: Infrastructure (cluster, database, networking, security)" | |
| echo " Phase 2: Coder Application ${{ steps.determine-env.outputs.skip_coder == 'true' && '⏭️ SKIPPED' || '✅ INCLUDED' }}" | |
| echo "" | |
| echo "⚡ Benefits of Two-Phase Deployment:" | |
| echo " • Infrastructure failures don't block cluster access" | |
| echo " • Coder deployment can be retried independently" | |
| echo " • Better troubleshooting with immediate kubeconfig access" | |
| echo " • Cleaner separation of concerns" | |
| security-scan: | |
| name: Security Scan Environment Config | |
| needs: [determine-strategy, pre-validate] | |
| if: needs.determine-strategy.outputs.deploy_env != '' | |
| uses: ./.github/workflows/security-scan.yml | |
| with: | |
| scan_scope: full | |
| environment: ${{ needs.determine-strategy.outputs.deploy_env }} | |
| severity_threshold: MEDIUM | |
| fail_on_findings: false | |
| deploy-infrastructure: | |
| name: Deploy Infrastructure (Phase 1) | |
| needs: [determine-strategy, pre-validate, security-scan] | |
| if: needs.determine-strategy.outputs.deploy_env != '' | |
| uses: ./.github/workflows/deploy-infrastructure.yml | |
| with: | |
| bucket_name: ${{ github.event.inputs.bucket_name }} | |
| environment: ${{ needs.determine-strategy.outputs.deploy_env }} | |
| region: ${{ needs.determine-strategy.outputs.deploy_region || github.event.inputs.region }} | |
| availability_zone: ${{ needs.determine-strategy.outputs.deploy_zone || github.event.inputs.availability_zone }} | |
| domain_name: ${{ needs.determine-strategy.outputs.deploy_domain }} | |
| subdomain: ${{ needs.determine-strategy.outputs.deploy_subdomain }} | |
| auto_approve: true | |
| dry_run: ${{ needs.determine-strategy.outputs.dry_run == 'true' }} | |
| advanced_config: ${{ github.event.inputs.advanced_config || '{}' }} | |
| secrets: inherit | |
| deploy-coder: | |
| name: Deploy Coder Application (Phase 2) | |
| needs: [determine-strategy, deploy-infrastructure] | |
| if: needs.determine-strategy.outputs.deploy_env != '' && needs.determine-strategy.outputs.skip_coder != 'true' && needs.deploy-infrastructure.result == 'success' | |
| uses: ./.github/workflows/deploy-coder.yml | |
| with: | |
| bucket_name: ${{ github.event.inputs.bucket_name }} | |
| environment: ${{ needs.determine-strategy.outputs.deploy_env }} | |
| region: ${{ needs.determine-strategy.outputs.deploy_region || github.event.inputs.region }} | |
| availability_zone: ${{ needs.determine-strategy.outputs.deploy_zone || github.event.inputs.availability_zone }} | |
| template: ${{ needs.determine-strategy.outputs.deploy_template }} | |
| kubeconfig_source: 'from_infrastructure_run' | |
| infrastructure_run_id: ${{ github.run_id }} | |
| auto_approve: true | |
| dry_run: ${{ needs.determine-strategy.outputs.dry_run == 'true' }} | |
| secrets: inherit | |
| deployment-summary: | |
| name: Deployment Summary | |
| runs-on: ubuntu-latest | |
| needs: [determine-strategy, deploy-infrastructure, deploy-coder] | |
| if: always() && needs.determine-strategy.outputs.deploy_env != '' | |
| permissions: | |
| contents: read # Read repository information | |
| pull-requests: write # Comment on PRs with deployment status | |
| issues: write # Create issues on deployment failure | |
| steps: | |
| - name: Evaluate Deployment Results | |
| id: evaluate | |
| run: | | |
| infrastructure_result="${{ needs.deploy-infrastructure.result }}" | |
| coder_result="${{ needs.deploy-coder.result }}" | |
| skip_coder="${{ needs.determine-strategy.outputs.skip_coder }}" | |
| echo "🔍 Evaluating deployment results..." | |
| echo "Infrastructure (Phase 1): $infrastructure_result" | |
| echo "Coder (Phase 2): $coder_result" | |
| echo "Skip Coder: $skip_coder" | |
| # Determine overall status | |
| if [[ "$infrastructure_result" == "success" ]]; then | |
| if [[ "$skip_coder" == "true" ]]; then | |
| overall_status="success" | |
| deployment_type="Infrastructure Only" | |
| status_emoji="🏗️" | |
| status_message="Infrastructure deployment completed successfully" | |
| elif [[ "$coder_result" == "success" ]]; then | |
| overall_status="success" | |
| deployment_type="Complete Environment" | |
| status_emoji="🎉" | |
| status_message="Complete environment deployment successful" | |
| elif [[ "$coder_result" == "failure" ]]; then | |
| overall_status="partial" | |
| deployment_type="Infrastructure Only (Coder Failed)" | |
| status_emoji="⚠️" | |
| status_message="Infrastructure deployed, but Coder application failed" | |
| else | |
| overall_status="partial" | |
| deployment_type="Infrastructure Only (Coder Skipped/Cancelled)" | |
| status_emoji="🏗️" | |
| status_message="Infrastructure deployed, Coder deployment not completed" | |
| fi | |
| else | |
| overall_status="failure" | |
| deployment_type="Failed" | |
| status_emoji="❌" | |
| status_message="Infrastructure deployment failed" | |
| fi | |
| echo "overall_status=$overall_status" >> $GITHUB_OUTPUT | |
| echo "deployment_type=$deployment_type" >> $GITHUB_OUTPUT | |
| echo "status_emoji=$status_emoji" >> $GITHUB_OUTPUT | |
| echo "status_message=$status_message" >> $GITHUB_OUTPUT | |
| - name: Display Deployment Summary | |
| run: | | |
| echo "${{ steps.evaluate.outputs.status_emoji }} Deployment Summary" | |
| echo "==============================" | |
| echo "" | |
| echo "📋 Final Status: ${{ steps.evaluate.outputs.status_message }}" | |
| echo "🏷️ Deployment Type: ${{ steps.evaluate.outputs.deployment_type }}" | |
| echo "🌍 Environment: ${{ needs.determine-strategy.outputs.deploy_env }}" | |
| echo "" | |
| echo "📊 Phase Results:" | |
| echo " Phase 1 (Infrastructure): ${{ needs.deploy-infrastructure.result }}" | |
| echo " Phase 2 (Coder): ${{ needs.deploy-coder.result || 'skipped' }}" | |
| echo "" | |
| if [[ "${{ steps.evaluate.outputs.overall_status }}" == "success" ]]; then | |
| if [[ "${{ needs.determine-strategy.outputs.skip_coder }}" == "true" ]]; then | |
| echo "🎯 Infrastructure Ready!" | |
| echo " • Kubernetes cluster deployed and accessible" | |
| echo " • Database and networking configured" | |
| echo " • Security policies applied" | |
| echo " • Kubeconfig available for Coder deployment" | |
| echo "" | |
| echo "📝 Next Steps:" | |
| echo " • Run 'Deploy Coder Application' workflow to complete setup" | |
| echo " • Or deploy manually using kubectl with provided kubeconfig" | |
| else | |
| echo "🎉 Complete Environment Ready!" | |
| echo " • Full infrastructure deployed" | |
| echo " • Coder application running" | |
| echo " • Ready for workspace creation" | |
| echo "" | |
| echo "🔗 Access Information:" | |
| echo " • Coder URL: ${{ needs.deploy-coder.outputs.coder_url || 'Check deployment logs' }}" | |
| echo " • Admin User: ${{ needs.deploy-coder.outputs.admin_username || 'admin' }}" | |
| fi | |
| elif [[ "${{ steps.evaluate.outputs.overall_status }}" == "partial" ]]; then | |
| echo "⚠️ Partial Deployment" | |
| echo " • Infrastructure deployed successfully" | |
| echo " • Coder application deployment issues" | |
| echo " • Cluster accessible via kubeconfig" | |
| echo "" | |
| echo "🔧 Troubleshooting Options:" | |
| echo " • Use kubeconfig to investigate cluster state" | |
| echo " • Retry Coder deployment independently" | |
| echo " • Check storage classes and resource availability" | |
| else | |
| echo "❌ Deployment Failed" | |
| echo " • Infrastructure deployment failed" | |
| echo " • Check workflow logs for specific errors" | |
| echo " • Verify Scaleway credentials and quotas" | |
| fi | |
| - name: Comment Deployment Summary on PR | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const overallStatus = '${{ steps.evaluate.outputs.overall_status }}'; | |
| const deploymentType = '${{ steps.evaluate.outputs.deployment_type }}'; | |
| const statusEmoji = '${{ steps.evaluate.outputs.status_emoji }}'; | |
| const statusMessage = '${{ steps.evaluate.outputs.status_message }}'; | |
| const environment = '${{ needs.determine-strategy.outputs.deploy_env }}'; | |
| const infraResult = '${{ needs.deploy-infrastructure.result }}'; | |
| const coderResult = '${{ needs.deploy-coder.result || 'skipped' }}'; | |
| let body = `## ${statusEmoji} Complete Environment Deployment Results | |
| **Status:** ${statusMessage} | |
| **Environment:** \`${environment}\` | |
| **Deployment Type:** ${deploymentType} | |
| ### 📊 Phase Results | |
| - **Phase 1 (Infrastructure):** ${infraResult} | |
| - **Phase 2 (Coder Application):** ${coderResult} | |
| ### 🔍 Deployment Details | |
| - **Template:** ${{ needs.determine-strategy.outputs.deploy_template || 'None specified' }} | |
| - **Domain:** ${{ needs.determine-strategy.outputs.deploy_domain || 'IP-based access' }} | |
| - **Monitoring:** ${{ needs.determine-strategy.outputs.enable_monitoring }}`; | |
| if (overallStatus === 'success') { | |
| if ('${{ needs.determine-strategy.outputs.skip_coder }}' === 'true') { | |
| body += ` | |
| ### 🏗️ Infrastructure Ready | |
| - ✅ Kubernetes cluster deployed and accessible | |
| - ✅ Database and networking configured | |
| - ✅ Security policies applied | |
| - ✅ Kubeconfig available for Coder deployment | |
| **Next Steps:** Run 'Deploy Coder Application' workflow to complete setup.`; | |
| } else { | |
| body += ` | |
| ### 🎉 Complete Environment Ready | |
| - ✅ Full infrastructure deployed | |
| - ✅ Coder application running | |
| - ✅ Ready for workspace creation | |
| **Access URL:** ${{ needs.deploy-coder.outputs.coder_url || 'Check deployment outputs' }}`; | |
| } | |
| } else if (overallStatus === 'partial') { | |
| body += ` | |
| ### ⚠️ Partial Deployment | |
| - ✅ Infrastructure deployed successfully | |
| - ❌ Coder application deployment issues | |
| - 🔧 Cluster accessible via kubeconfig for troubleshooting | |
| **Recovery:** Retry Coder deployment independently or investigate using kubeconfig.`; | |
| } else { | |
| body += ` | |
| ### ❌ Deployment Failed | |
| - ❌ Infrastructure deployment failed | |
| - 🔍 Check workflow logs for specific errors | |
| - 🔧 Verify Scaleway credentials and quotas`; | |
| } | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: body | |
| }); | |
| notify: | |
| name: Notify Teams | |
| runs-on: ubuntu-latest | |
| needs: [determine-strategy, deploy-infrastructure, deploy-coder, deployment-summary] | |
| if: always() && needs.determine-strategy.outputs.deploy_env != '' | |
| permissions: | |
| contents: read # Read repository information | |
| issues: write # Create issues on deployment failure | |
| steps: | |
| - name: Notify Slack (if configured) | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| run: | | |
| if [[ -n "$SLACK_WEBHOOK_URL" ]]; then | |
| infrastructure_result="${{ needs.deploy-infrastructure.result }}" | |
| coder_result="${{ needs.deploy-coder.result }}" | |
| environment="${{ needs.determine-strategy.outputs.deploy_env }}" | |
| skip_coder="${{ needs.determine-strategy.outputs.skip_coder }}" | |
| # Determine notification details | |
| if [[ "$infrastructure_result" == "success" ]]; then | |
| if [[ "$skip_coder" == "true" ]]; then | |
| color="good" | |
| emoji="🏗️" | |
| text="Infrastructure deployment succeeded (Coder skipped)" | |
| elif [[ "$coder_result" == "success" ]]; then | |
| color="good" | |
| emoji="🎉" | |
| text="Complete environment deployment succeeded" | |
| else | |
| color="warning" | |
| emoji="⚠️" | |
| text="Infrastructure succeeded, Coder failed" | |
| fi | |
| else | |
| color="danger" | |
| emoji="❌" | |
| text="Environment deployment failed" | |
| fi | |
| payload="{ | |
| \"attachments\": [{ | |
| \"color\": \"$color\", | |
| \"text\": \"$emoji $text\", | |
| \"fields\": [ | |
| {\"title\": \"Environment\", \"value\": \"$environment\", \"short\": true}, | |
| {\"title\": \"Infrastructure\", \"value\": \"$infrastructure_result\", \"short\": true}, | |
| {\"title\": \"Coder App\", \"value\": \"${coder_result:-skipped}\", \"short\": true}, | |
| {\"title\": \"Template\", \"value\": \"${{ needs.determine-strategy.outputs.deploy_template || 'None' }}\", \"short\": true}, | |
| {\"title\": \"Triggered by\", \"value\": \"${{ github.actor }}\", \"short\": true}, | |
| {\"title\": \"Repository\", \"value\": \"${{ github.repository }}\", \"short\": true} | |
| ] | |
| }] | |
| }" | |
| curl -X POST -H 'Content-type: application/json' \ | |
| --data "$payload" "$SLACK_WEBHOOK_URL" | |
| else | |
| echo "Slack webhook not configured, skipping notification" | |
| fi | |
| - name: Create GitHub Issue on Complete Failure | |
| if: needs.deploy-infrastructure.result == 'failure' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| // Import the issue management helper | |
| const { handleDeploymentFailureIssue } = require('./.github/scripts/issue-manager.js'); | |
| // Handle the deployment failure issue (create or update) | |
| const issue = await handleDeploymentFailureIssue(github, context, { | |
| environment: '${{ needs.determine-strategy.outputs.deploy_env }}', | |
| deploymentType: 'Two-Phase (Infrastructure + Coder)', | |
| failurePoint: 'Phase 1 (Infrastructure)', | |
| workflowRun: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}', | |
| commit: '${{ github.sha }}', | |
| triggeredBy: '${{ github.actor }}', | |
| status: { | |
| 'Phase 1 (Infrastructure)': 'failed', | |
| 'Phase 2 (Coder Application)': 'not attempted (dependency failed)' | |
| } | |
| }); | |
| console.log(`Infrastructure failure issue handled: #${issue.number} - ${issue.title}`); | |
| - name: Create GitHub Issue on Partial Failure | |
| if: needs.deploy-infrastructure.result == 'success' && needs.deploy-coder.result == 'failure' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| // Import the issue management helper | |
| const { handleDeploymentFailureIssue } = require('./.github/scripts/issue-manager.js'); | |
| // Handle the Coder deployment failure issue (create or update) | |
| const issue = await handleDeploymentFailureIssue(github, context, { | |
| environment: '${{ needs.determine-strategy.outputs.deploy_env }}', | |
| deploymentType: 'Two-Phase (Infrastructure + Coder)', | |
| failurePoint: 'Phase 2 (Coder Application)', | |
| workflowRun: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}', | |
| commit: '${{ github.sha }}', | |
| triggeredBy: '${{ github.actor }}', | |
| status: { | |
| 'Phase 1 (Infrastructure)': 'success', | |
| 'Phase 2 (Coder Application)': 'failed' | |
| } | |
| }); | |
| console.log(`Coder deployment failure issue handled: #${issue.number} - ${issue.title}`); |