Skip to content

Commit 468f9f2

Browse files
authored
Enhance ArgoCD deployment failure issue reporting
1 parent 70cb80e commit 468f9f2

File tree

1 file changed

+70
-55
lines changed

1 file changed

+70
-55
lines changed

.github/workflows/argocd-deployment-failure.yml

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)