-
Notifications
You must be signed in to change notification settings - Fork 9
131 lines (122 loc) · 5.98 KB
/
Copy pathupdate_build_status.yml
File metadata and controls
131 lines (122 loc) · 5.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
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
name: Update build status workflow
on:
schedule:
- cron: "*/15 * * * *"
jobs:
update:
name: Update build status
runs-on: ubuntu-slim
permissions:
actions: read
checks: write
steps:
- name: "Update build status"
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const endpoint = 'GET /repos/:owner/:repo/pulls?state=:state'
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
}
// See https://docs.github.com/en/graphql/reference/enums#mergestatestatus
const maybeReady = ['behind', 'clean', 'draft', 'has_hooks', 'unknown', 'unstable'];
// Iterate open PRs
for await (const prs of github.paginate.iterator(endpoint,params)) {
// Each page
for await (const pr of prs.data) {
console.log('SHA: ' + pr.head.sha)
console.log(' Mergeable status: ' + pr.mergeable_state)
if (pr.mergeable_state == null || maybeReady.includes(pr.mergeable_state)) {
// Paginate with per_page=100 to match notify_test_workflow.yml. The default
// page size is 30, and a SHA can accumulate more check-runs than that (CI
// matrix, external checks, duplicate Build checks from reopened PRs), which
// could push the target Build check off the first page and leave the PR
// stuck in 'queued' forever.
const checkRuns = await github.paginate(
'GET /repos/{owner}/{repo}/commits/{ref}/check-runs',
{
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha,
per_page: 100
}
)
// Iterator GitHub Checks in the PR
for await (const cr of checkRuns) {
if (cr.name == 'Build' && cr.conclusion != "action_required") {
// text contains parameters to make request in JSON. A Build check
// created by something other than notify_test_workflow.yml (an older
// version, a manual run, or another app) may have empty or malformed
// output text; skip it instead of aborting the whole scheduled run,
// which would block updates for every PR queued behind it.
let params
try {
params = JSON.parse(cr.output.text)
} catch (error) {
console.error('Skipping Build check ' + cr.id + ' with unparseable output text')
console.error(error)
continue
}
// Get the workflow run in the forked repository
let run
try {
run = await github.request('GET /repos/{owner}/{repo}/actions/runs/{run_id}', params)
} catch (error) {
console.error(error)
// Run not found. This can happen when the PR author removes GitHub Actions runs or
// disables GitHub Actions.
continue
}
// Keep syncing the status of the checks
if (run.data.status == 'completed') {
console.log(' Run ' + cr.id + ': set status (' + run.data.status + ') and conclusion (' + run.data.conclusion + ')')
const response = await github.request('PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}', {
owner: context.repo.owner,
repo: context.repo.repo,
check_run_id: cr.id,
output: cr.output,
status: run.data.status,
conclusion: run.data.conclusion,
details_url: run.data.details_url
})
} else {
// PATCH /check-runs accepts only queued | in_progress | completed,
// but workflow_run may also report requested / waiting / pending.
const status = run.data.status == 'in_progress' ? 'in_progress' : 'queued'
console.log(' Run ' + cr.id + ': set status (' + run.data.status + ' -> ' + status + ')')
const response = await github.request('PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}', {
owner: context.repo.owner,
repo: context.repo.repo,
check_run_id: cr.id,
output: cr.output,
status: status,
details_url: run.data.details_url
})
}
break
}
}
}
}
}