forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
171 lines (152 loc) Β· 6.26 KB
/
Copy pathcommit-queue.yml
File metadata and controls
171 lines (152 loc) Β· 6.26 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
# This action requires the following secrets to be set on the repository:
# GH_USER_TOKEN: GitHub user token, to be used by ncu and to push changes
# JENKINS_USER: GitHub user whose Jenkins token is defined below
# JENKINS_TOKEN: Jenkins token, to be used to check CI status
name: Commit Queue
on:
# `schedule` event is used instead of `pull_request` because when a
# `pull_request` event is triggered on a PR from a fork, GITHUB_TOKEN will
# be read-only, and the Action won't have access to any other repository
# secrets, which it needs to access Jenkins API.
schedule:
- cron: '*/5 * * * *'
concurrency: ${{ github.workflow }}
env:
NODE_VERSION: lts/*
permissions:
contents: read
jobs:
get_candidate_prs:
permissions:
pull-requests: read
if: github.repository == 'nodejs/node'
runs-on: ubuntu-slim
outputs:
candidates: ${{ steps.get_candidate_prs.outputs.candidates }}
steps:
- name: Get Pull Request Candidates
id: get_candidate_prs
run: |
list_prs() {
gh pr list \
--repo "$GITHUB_REPOSITORY" \
--base "$GITHUB_REF_NAME" \
--label 'commit-queue' \
"$@" \
--json 'number' \
-t '{{ range . }}{{ .number }} {{ end }}' \
--limit 100
}
aged_prs=$(list_prs \
--search "created:<=$(date --date="2 days ago" +"%Y-%m-%dT%H:%M:%S%z") -label:blocked")
fast_track_prs=$(list_prs \
--label 'fast-track' \
--search "-label:blocked")
queued_prs=$(list_prs \
--search "-label:blocked")
candidates=$(printf '%s %s %s\n' "$aged_prs" "$fast_track_prs" "$queued_prs" |
jq -r -s 'reduce .[] as $pr ([]; if index($pr) then . else . + [$pr] end) | join(" ")')
echo "candidates=$candidates" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
commitQueue:
needs: get_candidate_prs
if: needs.get_candidate_prs.outputs.candidates != ''
runs-on: ubuntu-slim
steps:
# Install dependencies
- name: Install Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install @node-core/utils
run: npm install -g @node-core/utils
- name: Set variables
run: |
echo "REPOSITORY=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f2)" >> "$GITHUB_ENV"
- name: Configure @node-core/utils
run: |
ncu-config set branch "${GITHUB_REF_NAME}"
ncu-config set upstream origin
ncu-config set username "$USERNAME"
ncu-config set token "$GITHUB_TOKEN"
ncu-config set jenkins_token "$JENKINS_TOKEN"
ncu-config set repo "${REPOSITORY}"
ncu-config set owner "${GITHUB_REPOSITORY_OWNER}"
env:
USERNAME: ${{ secrets.JENKINS_USER }}
GITHUB_TOKEN: ${{ secrets.GH_USER_TOKEN }}
JENKINS_TOKEN: ${{ secrets.JENKINS_TOKEN }}
- name: Filter Pull Requests
id: get_mergeable_prs
run: |
readme="${RUNNER_TEMP}/README.md"
curl -fsSLo "$readme" "https://github.com/${GITHUB_REPOSITORY}/raw/${GITHUB_SHA}/README.md"
numbers=
# shellcheck disable=SC2086
for pr in $CANDIDATES; do
metadata="${RUNNER_TEMP}/metadata-${pr}.json"
output="${RUNNER_TEMP}/metadata-${pr}.txt"
if git node metadata "$pr" \
--owner "$GITHUB_REPOSITORY_OWNER" \
--repo "$REPOSITORY" \
--readme "$readme" \
--json > "$metadata" 2> "$output"; then
metadata_status=0
else
metadata_status=$?
fi
if [ -s "$output" ]; then
cat "$output"
fi
case "$metadata_status" in
0|2[0-9]|4[0-9]) ;;
*)
echo "git node metadata failed for pr ${pr} with exit code ${metadata_status}"
exit 1
;;
esac
metadata_exit_code=$(jq -r '.exitCode' "$metadata") || {
echo "failed to parse metadata JSON for pr ${pr}"
exit 1
}
if [ "$metadata_exit_code" != "$metadata_status" ]; then
echo "metadata JSON exitCode mismatch for pr ${pr}"
exit 1
fi
metadata_reason_codes=$(jq -r '.reasonCodes | join(", ")' "$metadata") || {
echo "failed to parse metadata reason codes for pr ${pr}"
exit 1
}
if [ "$metadata_status" -eq 0 ]; then
echo "pr ${pr} is ready for the commit queue"
numbers="$numbers $pr"
continue
fi
if [ "$metadata_status" -ge 20 ] && [ "$metadata_status" -le 29 ]; then
echo "pr ${pr} skipped, not ready to land"
echo "reason codes: ${metadata_reason_codes}"
continue
fi
echo "pr ${pr} will be handled by the commit queue"
echo "reason codes: ${metadata_reason_codes}"
numbers="$numbers $pr"
done
numbers=$(echo "$numbers" | xargs)
echo "numbers=$numbers" >> "$GITHUB_OUTPUT"
env:
CANDIDATES: ${{ needs.get_candidate_prs.outputs.candidates }}
GITHUB_TOKEN: ${{ secrets.GH_USER_TOKEN }}
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
if: steps.get_mergeable_prs.outputs.numbers != ''
with:
# A personal token is required because pushing with GITHUB_TOKEN will
# prevent commits from running CI after they land. It needs
# to be set here because `checkout` configures GitHub authentication
# for push as well.
token: ${{ secrets.GH_USER_TOKEN }}
- name: Start the Commit Queue
if: steps.get_mergeable_prs.outputs.numbers != ''
run: ./tools/actions/commit-queue.sh "${GITHUB_REPOSITORY_OWNER}" "${REPOSITORY}" ${{ steps.get_mergeable_prs.outputs.numbers }}
env:
GITHUB_TOKEN: ${{ secrets.GH_USER_TOKEN }}