forked from flagos-ai/FlagScale
-
Notifications
You must be signed in to change notification settings - Fork 0
237 lines (198 loc) · 9.98 KB
/
Copy pathtest_failure_analysis.yml
File metadata and controls
237 lines (198 loc) · 9.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
name: Failure Analysis and Auto-Retry Flaky Tests
# This example demonstrates using structured outputs to detect flaky test failures
# and automatically retry them, reducing noise from intermittent failures.
#
# Use case: When CI fails, automatically determine if it's likely flaky and retry if so.
on:
workflow_run:
workflows:
- ascend_tests
- cuda_tests
- metax_c500_tests
- format_check
types: [completed]
permissions:
contents: read
actions: write
pull-requests: write
id-token: write
jobs:
detect-flaky:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'failure'}}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Debug gh access to run logs
env:
GH_TOKEN: ${{ github.token }}
RUN_ID: ${{ github.event.workflow_run.id }}
run: |
gh auth status
gh run view "$RUN_ID" --json databaseId,status,conclusion,workflowName
gh run view "$RUN_ID" --log-failed >/tmp/failed.log
echo "Fetched failed log bytes: $(wc -c </tmp/failed.log)"
- name: Detect flaky test failures
id: detect
uses: anthropics/claude-code-action@v1
env:
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
GH_TOKEN: ${{ github.token }}
with:
claude_code_oauth_token: ${{ secrets.ANTHROPIC_AUTH_TOKEN }}
prompt: |
The CI workflow "${{ github.event.workflow_run.name }}" failed: ${{ github.event.workflow_run.html_url }}
IMPORTANT: You are in READ-ONLY analysis mode. Do NOT modify any files, do NOT use gh to push commits, create branches, or make any changes to the repository. Only read logs and analyze.
Check the logs: gh run view ${{ github.event.workflow_run.id }} --log-failed
Determine if this looks like a flaky test failure by checking for:
- Timeout errors
- Race conditions
- Network errors
- "Expected X but got Y" intermittent failures
- Tests that passed in previous commits
Return:
- is_flaky: true if likely flaky, false if real bug
- confidence: number 0-1 indicating confidence level
- summary: brief one-sentence explanation
claude_args: |
--json-schema '{"type":"object","properties":{"is_flaky":{"type":"boolean","description":"Whether this appears to be a flaky test failure"},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"Confidence level in the determination"},"summary":{"type":"string","description":"One-sentence explanation of the failure"}},"required":["is_flaky","confidence","summary"]}'
--model ${{ vars.CLAUDE_MODEL }}
--allowedTools 'Bash(gh *)' 'Read' 'Glob' 'Grep'
--max-turns 30
- name: Debug detect output
if: always()
run: |
cat > /tmp/debug_structured.json <<'EOJSON'
${{ steps.detect.outputs.structured_output }}
EOJSON
cat > /tmp/debug_result.json <<'EOJSON'
${{ steps.detect.outputs.result }}
EOJSON
echo "structured_output:"
cat /tmp/debug_structured.json
echo "result:"
cat /tmp/debug_result.json
# Auto-retry only if flaky AND high confidence (>= 0.7)
- name: Retry flaky tests
if: |
fromJSON(steps.detect.outputs.structured_output).is_flaky == true &&
fromJSON(steps.detect.outputs.structured_output).confidence >= 0.7
env:
GH_TOKEN: ${{ github.token }}
RUN_ID: ${{ github.event.workflow_run.id }}
run: |
OUTPUT='${{ steps.detect.outputs.structured_output }}'
CONFIDENCE=$(echo "$OUTPUT" | jq -r '.confidence')
SUMMARY=$(echo "$OUTPUT" | jq -r '.summary')
echo "Flaky test detected (confidence: $CONFIDENCE)"
echo "Summary: $SUMMARY"
echo "Re-running original workflow run: $RUN_ID"
gh run rerun "$RUN_ID"
# Low confidence flaky detection - skip retry
- name: Low confidence detection
if: |
fromJSON(steps.detect.outputs.structured_output).is_flaky == true &&
fromJSON(steps.detect.outputs.structured_output).confidence < 0.7
run: |
OUTPUT='${{ steps.detect.outputs.structured_output }}'
CONFIDENCE=$(echo "$OUTPUT" | jq -r '.confidence')
echo "Possible flaky test but confidence too low ($CONFIDENCE)"
echo "Not retrying automatically - manual review recommended"
# Deep analysis for real bug failures
- name: Analyze failure and suggest fix
id: analyze
if: |
fromJSON(steps.detect.outputs.structured_output).is_flaky == false &&
github.event.workflow_run.event == 'pull_request'
uses: anthropics/claude-code-action@v1
env:
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
GH_TOKEN: ${{ github.token }}
with:
claude_code_oauth_token: ${{ secrets.ANTHROPIC_AUTH_TOKEN }}
prompt: |
CI workflow failed and this is NOT a flaky test — it's a real bug.
IMPORTANT: You are in READ-ONLY analysis mode. Do NOT modify any files, do NOT use gh to push commits, create branches, or make any changes to the repository. Only read logs, read code, and analyze.
Workflow run: ${{ github.event.workflow_run.html_url }}
Step 1: Get the failed logs:
gh run view ${{ github.event.workflow_run.id }} --log-failed
Step 2: Get the PR diff to understand what changed:
BRANCH="${{ github.event.workflow_run.head_branch }}"
PR_NUMBER=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number')
if [ -n "$PR_NUMBER" ]; then
gh pr diff "$PR_NUMBER"
fi
Step 3: Analyze the error logs together with the code changes. Focus on:
- The exact error messages and stack traces
- Which test cases failed and why
- How the PR's code changes relate to the failures
- Root cause analysis
Step 4: Provide actionable fix suggestions:
- Specific code changes needed (with file paths and line references)
- If multiple issues exist, list them separately
- Provide code snippets showing the suggested fix
Return your analysis in this format:
- failed_tests: list of failed test names
- root_cause: detailed root cause analysis
- suggestions: list of actionable fix suggestions, each with file_path, description, and code_snippet
- severity: "critical" | "major" | "minor"
claude_args: |
--json-schema '{"type":"object","properties":{"failed_tests":{"type":"array","items":{"type":"string"},"description":"List of failed test names"},"root_cause":{"type":"string","description":"Detailed root cause analysis"},"suggestions":{"type":"array","items":{"type":"object","properties":{"file_path":{"type":"string"},"description":{"type":"string"},"code_snippet":{"type":"string"}},"required":["description"]},"description":"Actionable fix suggestions"},"severity":{"type":"string","enum":["critical","major","minor"],"description":"Severity level"}},"required":["failed_tests","root_cause","suggestions","severity"]}'
--model ${{ vars.CLAUDE_MODEL }}
--allowedTools 'Bash(gh *)' 'Read' 'Glob' 'Grep'
--max-turns 10
# Comment on PR with analysis results
- name: Comment on PR
if: |
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.pull_requests[0].number != null
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
run: |
[ -z "$PR_NUMBER" ] && exit 0
cat > /tmp/detect_output.json <<'EOJSON'
${{ steps.detect.outputs.structured_output }}
EOJSON
IS_FLAKY=$(jq -r '.is_flaky' /tmp/detect_output.json)
CONFIDENCE=$(jq -r '.confidence' /tmp/detect_output.json)
SUMMARY=$(jq -r '.summary' /tmp/detect_output.json)
if [ "$IS_FLAKY" = "true" ]; then
gh pr comment "$PR_NUMBER" --body "$(cat <<EOF
## Flaky Test Detected
**Analysis**: ${SUMMARY}
**Confidence**: ${CONFIDENCE}
Automatically retrying the workflow.
[View workflow run](${{ github.event.workflow_run.html_url }})
EOF
)"
else
cat > /tmp/analyze_output.json <<'EOJSON'
${{ steps.analyze.outputs.structured_output }}
EOJSON
SEVERITY=$(jq -r '.severity' /tmp/analyze_output.json)
ROOT_CAUSE=$(jq -r '.root_cause' /tmp/analyze_output.json)
FAILED_TESTS=$(jq -r '.failed_tests | map("- `" + . + "`") | join("\n")' /tmp/analyze_output.json)
SUGGESTIONS=$(jq -r '.suggestions | to_entries | map(
"### " + ((.key + 1) | tostring) + ". " + .value.description +
(if .value.file_path then "\n**File**: `" + .value.file_path + "`" else "" end) +
(if .value.code_snippet then "\n```suggestion\n" + .value.code_snippet + "\n```" else "" end)
) | join("\n\n")' /tmp/analyze_output.json)
SEVERITY_ICON="[WARNING]"
[ "$SEVERITY" = "critical" ] && SEVERITY_ICON="[CRITICAL]"
[ "$SEVERITY" = "minor" ] && SEVERITY_ICON="[MINOR]"
gh pr comment "$PR_NUMBER" --body "$(cat <<EOF
## Test Failure Analysis
${SEVERITY_ICON} **Severity**: ${SEVERITY}
### Failed Tests
${FAILED_TESTS}
### Root Cause
${ROOT_CAUSE}
### Suggested Fixes
${SUGGESTIONS}
---
**Flaky Detection**: ${SUMMARY} (confidence: ${CONFIDENCE})
[View workflow run](${{ github.event.workflow_run.html_url }})
EOF
)"
fi