-
Notifications
You must be signed in to change notification settings - Fork 30.6k
153 lines (140 loc) · 5.62 KB
/
retry_test.yml
File metadata and controls
153 lines (140 loc) · 5.62 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
name: retry-tests
on:
workflow_run:
# Make sure that required_job_conclusion knows what the name of the required
# job is in each workflow.
workflows: ['build-and-test', 'build-and-deploy']
branches: [canary]
types:
- completed
env:
SLACK_WEBHOOK_URL: ${{ secrets.BROKEN_CANARY_SLACK_WEBHOOK_URL }}
permissions:
actions: write
jobs:
retry-on-failure:
name: retry failed jobs
# Retry the build-and-test workflow up to 2 times
if: >-
${{
github.event.workflow_run.conclusion == 'failure' &&
github.repository == 'vercel/next.js' &&
github.event.workflow_run.run_attempt < 3
}}
runs-on: ubuntu-latest
steps:
- name: Check conclusion of required job
id: required_job_conclusion
uses: actions/github-script@v7
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
script: |
// See build-and-test.yml and build-and-deploy.yml for the required job names
const requiredJobName = {
'build-and-test': 'thank you, next',
'build-and-deploy': 'thank you, build',
}[context.payload.workflow_run.name]
async function rerunIfRequiredNotSuccessful() {
const result = await github.paginate.iterator(
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs',
{
attempt_number: context.payload.workflow_run.run_attempt,
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
}
)
for await (const { data: jobs } of result) {
for (const job of jobs) {
if (job.name === requiredJobName) {
console.log(
"Using conclusion '%s' from %s",
job.conclusion,
job.html_url
)
return job.conclusion
}
}
}
console.log("Couldn't find job with name '%s'", requiredJobName)
return null
}
return await rerunIfRequiredNotSuccessful()
- name: send retry request to GitHub API
if: ${{ steps.required_job_conclusion.outputs.result != '"success"' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/rerun-failed-jobs
report-failure:
name: report failure to slack
# Report the failure to Slack if the build-and-test workflow has failed 3 times
# build-and-deploy is not retried so we always report it
if: >-
${{
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.run_attempt >= 3 &&
!github.event.workflow_run.head_repository.fork
}}
runs-on: ubuntu-latest
steps:
- name: Check conclusion of required job
id: required_job_conclusion
uses: actions/github-script@v7
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
script: |
// See build-and-test.yml and build-and-deploy.yml for the required job names
const requiredJobName = {
'build-and-test': 'thank you, next',
'build-and-deploy': 'thank you, build',
}[context.payload.workflow_run.name]
async function rerunIfRequiredNotSuccessful() {
const result = await github.paginate.iterator(
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs',
{
attempt_number: context.payload.workflow_run.run_attempt,
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
}
)
for await (const { data: jobs } of result) {
for (const job of jobs) {
if (job.name === requiredJobName) {
console.log(
"Using conclusion '%s' from %s",
job.conclusion,
job.html_url
)
return job.conclusion
}
}
}
console.log("Couldn't find job with name '%s'", requiredJobName)
return null
}
return await rerunIfRequiredNotSuccessful()
- name: send webhook
if: ${{ steps.required_job_conclusion.outputs.result != '"success"' }}
uses: slackapi/slack-github-action@v1.25.0
with:
# These urls are intentionally missing the protocol,
# allowing them to be transformed into actual links in the Slack workflow
# (through slightly hacky means).
payload: |
{
"commit_title": ${{ toJSON(github.event.workflow_run.display_title) }},
"commit_url": "github.com/${{ github.repository }}/commit/${{ github.event.workflow_run.head_sha }}",
"workflow_run_url": "github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/attempts/${{ github.event.workflow_run.run_attempt }}"
}
env:
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}