forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathretryable.groovy
78 lines (64 loc) · 1.73 KB
/
retryable.groovy
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
import groovy.transform.Field
public static @Field GLOBAL_RETRIES_ENABLED = false
public static @Field MAX_GLOBAL_RETRIES = 1
public static @Field CURRENT_GLOBAL_RETRIES = 0
public static @Field FLAKY_FAILURES = []
def setMax(max) {
retryable.MAX_GLOBAL_RETRIES = max
}
def enable() {
retryable.GLOBAL_RETRIES_ENABLED = true
}
def enable(max) {
enable()
setMax(max)
}
def haveReachedMaxRetries() {
return retryable.CURRENT_GLOBAL_RETRIES >= retryable.MAX_GLOBAL_RETRIES
}
def getFlakyFailures() {
return retryable.FLAKY_FAILURES
}
def printFlakyFailures() {
catchErrors {
def failures = getFlakyFailures()
if (failures && failures.size() > 0) {
print "This build had the following flaky failures:"
failures.each {
print "\n${it.label}"
buildUtils.printStacktrace(it.exception)
}
}
}
}
def call(label, Closure closure) {
if (!retryable.GLOBAL_RETRIES_ENABLED) {
closure()
return
}
try {
closure()
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException ex) {
// If the build was aborted, don't retry the step
throw ex
} catch (Exception ex) {
if (haveReachedMaxRetries()) {
print "Couldn't retry '${label}', have already reached the max number of retries for this build."
throw ex
}
retryable.CURRENT_GLOBAL_RETRIES++
buildUtils.printStacktrace(ex)
unstable "${label} failed but is retryable, trying a second time..."
def JOB = env.JOB ? "${env.JOB}-retry" : ""
withEnv([
"JOB=${JOB}",
]) {
closure()
}
retryable.FLAKY_FAILURES << [
label: label,
exception: ex,
]
unstable "${label} failed on the first attempt, but succeeded on the second. Marking it as flaky."
}
}