forked from Ikalus1988/MisakaNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.yml
More file actions
131 lines (113 loc) 路 3.58 KB
/
Copy pathaction.yml
File metadata and controls
131 lines (113 loc) 路 3.58 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
name: 'Classify Failure'
description: 'Analyze failure logs and classify root cause. Pure Python, no dependencies.'
inputs:
log_file:
description: 'Path to the failure log file'
required: true
exit_code:
description: 'Exit code of the failed command'
required: false
default: '1'
outputs:
failure_class:
description: 'Classification: flaky_test, network_timeout, race_condition, permission_denied, real_bug, unknown'
value: ${{ steps.classify.outputs.failure_class }}
failure_summary:
description: 'One-line summary of the failure'
value: ${{ steps.classify.outputs.failure_summary }}
should_retry:
description: 'Whether to retry (true/false)'
value: ${{ steps.classify.outputs.should_retry }}
runs:
using: 'composite'
steps:
- name: Classify failure
id: classify
shell: bash
run: |
LOG_FILE="${{ inputs.log_file }}"
EXIT_CODE="${{ inputs.exit_code }}"
export LOG_FILE EXIT_CODE
CLASS=$(python3 <<'PY'
import os
import sys
log = ""
try:
with open(os.environ.get("LOG_FILE", ""), encoding="utf-8", errors="replace") as f:
log = f.read()
except OSError:
log = ""
exit_code_raw = os.environ.get("EXIT_CODE", "1")
exit_code = int(exit_code_raw) if exit_code_raw.isdigit() else 1
log_lower = log.lower()
if any(p in log_lower for p in [
"timeout", "timed out", "connection refused", "name resolution",
"ssl", "tls", "network", "dns", "errno", "etimedout",
"econnrefused", "econnreset", "httperror", "502", "503", "504",
]):
print("network_timeout")
sys.exit(0)
if any(p in log_lower for p in [
"permission denied", "forbidden", "401", "403",
"authentication failed", "token expired", "unauthorized",
"secret", "not allowed",
]):
print("permission_denied")
sys.exit(0)
if any(p in log_lower for p in [
"conflict", "409", "race", "concurrent",
"another process", "locked", "busy",
"already exists", "duplicate",
]):
print("race_condition")
sys.exit(0)
if any(p in log_lower for p in [
"flaky", "intermittent", "sometimes fails",
"passed on retry", "random", "unstable",
]):
print("flaky_test")
sys.exit(0)
if any(p in log_lower for p in [
"assertionerror", "assert", "test failed",
"pytest", "unittest", "coverage",
]):
print("flaky_test")
sys.exit(0)
if any(p in log_lower for p in [
"syntaxerror", "typeerror", "nameerror", "attributeerror",
"importerror", "modulenotfounderror", "keyerror", "indexerror",
"valueerror", "zerodivisionerror", "segmentation fault",
"core dumped", "fatal", "panic",
]):
print("real_bug")
sys.exit(0)
print("unknown")
PY
)
# Generate summary
SUMMARY=$(python3 <<'PY'
import os
try:
with open(os.environ.get("LOG_FILE", ""), encoding="utf-8", errors="replace") as f:
lines = f.readlines()
relevant = [line.strip() for line in lines if line.strip()][-3:]
summary = " | ".join(relevant)[:200]
print(summary if summary else "No log content available")
except OSError:
print("Could not read log file")
PY
)
# Determine should_retry
if [ "$CLASS" = "real_bug" ]; then
RETRY="false"
elif [ "$CLASS" = "permission_denied" ]; then
RETRY="false"
else
RETRY="true"
fi
echo "failure_class=$CLASS" >> "$GITHUB_OUTPUT"
echo "failure_summary=$SUMMARY" >> "$GITHUB_OUTPUT"
echo "should_retry=$RETRY" >> "$GITHUB_OUTPUT"
echo "馃搵 Classification: $CLASS"
echo "馃摑 Summary: $SUMMARY"
echo "馃攧 Should retry: $RETRY"