@@ -13,87 +13,102 @@ jobs:
1313 runs-on : ubuntu-latest
1414
1515 steps :
16- - name : Verify webhook signature
17- id : verify
18- env :
19- PAYLOAD : ${{ toJson(github.event.client_payload) }}
20- WEBHOOK_SECRET : ${{ secrets.ARGOCD_WEBHOOK_SECRET }}
21- run : |
22- # This is a placeholder - GitHub repository_dispatch doesn't include signatures
23- # The security comes from the GitHub token scope limitation
24- echo "Webhook received from ArgoCD"
25- echo "App: ${{ github.event.client_payload.app_name }}"
26- echo "Status: ${{ github.event.client_payload.operation_phase }}"
27-
28- - name : Extract deployment info
29- id : deployment_info
30- run : |
31- APP_NAME="${{ github.event.client_payload.app_name }}"
32- HEALTH_STATUS="${{ github.event.client_payload.health_status }}"
33- SYNC_STATUS="${{ github.event.client_payload.sync_status }}"
34- REVISION="${{ github.event.client_payload.revision }}"
35- MESSAGE="${{ github.event.client_payload.message }}"
36- REPO_URL="${{ github.event.client_payload.repo_url }}"
37- TIMESTAMP="${{ github.event.client_payload.timestamp }}"
38-
39- echo "app_name=${APP_NAME}" >> $GITHUB_OUTPUT
40- echo "health_status=${HEALTH_STATUS}" >> $GITHUB_OUTPUT
41- echo "sync_status=${SYNC_STATUS}" >> $GITHUB_OUTPUT
42- echo "revision=${REVISION}" >> $GITHUB_OUTPUT
43-
4416 - name : Create GitHub Issue
4517 uses : actions/github-script@v7
4618 with :
4719 script : |
48- const appName = '${{ github.event.client_payload.app_name }}';
49- const healthStatus = '${{ github.event.client_payload.health_status }}';
50- const syncStatus = '${{ github.event.client_payload.sync_status }}';
51- const operationPhase = '${{ github.event.client_payload.operation_phase }}';
52- const message = '${{ github.event.client_payload.message }}';
53- const revision = '${{ github.event.client_payload.revision }}';
54- const repoUrl = '${{ github.event.client_payload.repo_url }}';
55- const timestamp = '${{ github.event.client_payload.timestamp }}';
56- const clusterName = '${{ github.event.client_payload.cluster_name }}';
57- const clusterServer = '${{ github.event.client_payload.cluster_server }}';
58- const destNamespace = '${{ github.event.client_payload.destination_namespace }}';
20+ const payload = context.payload.client_payload || {};
21+ const appName = payload.app_name || 'unknown';
22+ const clusterName = payload.cluster || 'in-cluster';
23+ const namespace = payload.namespace || 'default';
24+ const healthStatus = payload.health_status || 'unknown';
25+ const syncStatus = payload.sync_status || 'unknown';
26+ const message = payload.message || 'No error message available';
27+ const revision = payload.revision || 'unknown';
28+ const repoUrl = payload.repo_url || '';
29+ const timestamp = payload.timestamp || new Date().toISOString();
30+ const resources = payload.resources || [];
31+
32+ // Build degraded resources section
33+ let degradedDetails = '';
34+ const degradedResources = resources.filter(r =>
35+ r.health && (r.health.status === 'Degraded' || r.health.status === 'Missing' || r.health.status === 'Unknown')
36+ );
37+
38+ if (degradedResources.length > 0) {
39+ degradedDetails = '\n### 🔴 Degraded Resources\n\n';
40+
41+ for (const resource of degradedResources) {
42+ const kind = resource.kind || 'Unknown';
43+ const name = resource.name || 'unknown';
44+ const resourceNamespace = resource.namespace || namespace;
45+ const healthStatus = resource.health?.status || 'Unknown';
46+ const healthMessage = resource.health?.message || 'No message';
47+ const syncStatus = resource.status || 'Unknown';
48+
49+ degradedDetails += `#### ${kind}: \`${name}\`\n\n`;
50+ degradedDetails += `- **Namespace:** ${resourceNamespace}\n`;
51+ degradedDetails += `- **Health Status:** ${healthStatus}\n`;
52+ degradedDetails += `- **Sync Status:** ${syncStatus}\n`;
53+ degradedDetails += `- **Message:** ${healthMessage}\n\n`;
54+
55+ // Add kubectl command for this specific resource
56+ degradedDetails += `**Troubleshoot:**\n\`\`\`bash\n`;
57+ degradedDetails += `kubectl describe ${kind.toLowerCase()} ${name} -n ${resourceNamespace}\n`;
58+ if (kind === 'Pod' || kind === 'Deployment' || kind === 'StatefulSet' || kind === 'DaemonSet') {
59+ degradedDetails += `kubectl logs ${kind.toLowerCase()}/${name} -n ${resourceNamespace}\n`;
60+ }
61+ degradedDetails += `\`\`\`\n\n`;
62+ }
63+ }
5964
6065 const issueTitle = `🚨 ArgoCD Deployment Failed: ${appName}`;
6166
6267 const issueBody = `## ArgoCD Deployment Failure
6368
6469 **Application:** \`${appName}\`
65- **Status:** ${operationPhase}
6670 **Timestamp:** ${timestamp}
6771
68- ### Details
72+ ### Cluster Information
73+
74+ | Field | Value |
75+ |-------|-------|
76+ | Cluster Name | \`${clusterName}\` |
77+ | Namespace | \`${namespace}\` |
78+
79+ ### Application Status
6980
7081 | Field | Value |
7182 |-------|-------|
72- | Cluster | \`${clusterName || clusterServer}\` |
73- | Namespace | \`${destNamespace}\` |
7483 | Health Status | \`${healthStatus}\` |
7584 | Sync Status | \`${syncStatus}\` |
7685 | Revision | \`${revision}\` |
7786 | Repository | ${repoUrl} |
7887
79- ### Raw payload
80- \`\`\`json
81- ${JSON.stringify(github.event.client_payload, null, 2)}
82- \`\`\`
83-
8488 ### Error Message
8589
8690 \`\`\`
87- ${message || 'No error message available' }
91+ ${message}
8892 \`\`\`
93+ ${degradedDetails}
94+ ### Troubleshooting Commands
95+
96+ \`\`\`bash
97+ # Check application status in ArgoCD
98+ argocd app get ${appName}
8999
90- ### Recommended Actions
100+ # Check pods in namespace
101+ kubectl get pods -n ${namespace}
91102
92- 1. Check the ArgoCD UI for detailed error logs
93- 2. Review the application manifest for syntax errors
94- 3. Verify resource quotas and limits
95- 4. Check for image pull errors or missing secrets
96- 5. Review recent commits to the source repository
103+ # Describe failed pods
104+ kubectl describe pods -n ${namespace}
105+
106+ # Get pod logs
107+ kubectl logs -n ${namespace} <pod-name>
108+
109+ # Check events
110+ kubectl get events -n ${namespace} --sort-by='.lastTimestamp'
111+ \`\`\`
97112
98113 ### Quick Links
99114
0 commit comments