Skip to content

chore(deps): bump the github-actions group with 2 updates #79

chore(deps): bump the github-actions group with 2 updates

chore(deps): bump the github-actions group with 2 updates #79

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}`);