mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
build: implement a Commit Queue in Actions
This is a (still experimental) implementation of a Commit Queue on GitHub Actions, using labels and the scheduler event to land Pull Requests. It uses `node-core-utils` to validate Pull Requests and to prepare the commit message, and then it uses a GitHub personal token to push changes back to the repository. If the Queue fails to land a Pull Request, that PR will be removed from the queue and the `node-core-utils` output will be pasted in the Pull Request. An overview of the implementation is provided in doc/guides/commit-queue.md, as well as current limitations. Ref: https://github.com/mmarchini-oss/automated-merge-test Ref: https://github.com/nodejs/build/issues/2201 PR-URL: https://github.com/nodejs/node/pull/34112 Refs: https://github.com/mmarchini-oss/automated-merge-test Refs: https://github.com/nodejs/build/issues/2201 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Denys Otrishko <shishugi@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
4 files changed
+285
-6
No files matched your search
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
|
||||
OWNER=$1
|
||||
REPOSITORY=$2
|
||||
GITHUB_TOKEN=$3
|
||||
shift 3
|
||||
|
||||
API_URL=https://api.github.com
|
||||
COMMIT_QUEUE_LABEL='commit-queue'
|
||||
COMMIT_QUEUE_FAILED_LABEL='commit-queue-failed'
|
||||
|
||||
function issueUrl() {
|
||||
echo "$API_URL/repos/${OWNER}/${REPOSITORY}/issues/${1}"
|
||||
}
|
||||
|
||||
function labelsUrl() {
|
||||
echo "$(issueUrl "${1}")/labels"
|
||||
}
|
||||
|
||||
function commentsUrl() {
|
||||
echo "$(issueUrl "${1}")/comments"
|
||||
}
|
||||
|
||||
function gitHubCurl() {
|
||||
url=$1
|
||||
method=$2
|
||||
shift 2
|
||||
|
||||
curl -fsL --request "$method" \
|
||||
--url "$url" \
|
||||
--header "authorization: Bearer ${GITHUB_TOKEN}" \
|
||||
--header 'content-type: application/json' "$@"
|
||||
}
|
||||
|
||||
|
||||
# TODO(mmarchini): should this be set with whoever added the label for each PR?
|
||||
git config --local user.email "github-bot@iojs.org"
|
||||
git config --local user.name "Node.js GitHub Bot"
|
||||
|
||||
for pr in "$@"; do
|
||||
# Skip PR if CI was requested
|
||||
if gitHubCurl "$(labelsUrl "$pr")" GET | jq -e 'map(.name) | index("request-ci")'; then
|
||||
echo "pr ${pr} skipped, waiting for CI to start"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip PR if CI is still running
|
||||
if ncu-ci url "https://github.com/${OWNER}/${REPOSITORY}/pull/${pr}" 2>&1 | grep "^Result *PENDING"; then
|
||||
echo "pr ${pr} skipped, CI still running"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Delete the commit queue label
|
||||
gitHubCurl "$(labelsUrl "$pr")"/"$COMMIT_QUEUE_LABEL" DELETE
|
||||
|
||||
git node land --yes "$pr" >output 2>&1 || echo "Failed to land #${pr}"
|
||||
# cat here otherwise we'll be supressing the output of git node land
|
||||
cat output
|
||||
|
||||
# TODO(mmarchini): workaround for ncu not returning the expected status code,
|
||||
# if the "Landed in..." message was not on the output we assume land failed
|
||||
if ! tail -n 10 output | grep '. Post "Landed in .*/pull/'"${pr}"; then
|
||||
gitHubCurl "$(labelsUrl "$pr")" POST --data '{"labels": ["'"${COMMIT_QUEUE_FAILED_LABEL}"'"]}'
|
||||
|
||||
jq -n --arg content "<details><summary>Commit Queue failed</summary><pre>$(cat output)</pre></details>" '{body: $content}' > output.json
|
||||
cat output.json
|
||||
|
||||
gitHubCurl "$(commentsUrl "$pr")" POST --data @output.json
|
||||
|
||||
rm output output.json
|
||||
# If `git node land --abort` fails, we're in unknown state. Better to stop
|
||||
# the script here, current PR was removed from the queue so it shouldn't
|
||||
# interfer again in the future
|
||||
git node land --abort --yes
|
||||
else
|
||||
rm output
|
||||
git push origin master
|
||||
|
||||
gitHubCurl "$(commentsUrl "$pr")" POST --data '{"body": "Landed in '"$(git rev-parse HEAD)"'"}'
|
||||
|
||||
gitHubCurl "$(issueUrl "$pr")" PATCH --data '{"state": "closed"}'
|
||||
fi
|
||||
done
|
||||
Reference in new issue
Block a user