Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions .github/workflows/auto-start-ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This action uses the following secrets:
# JENKINS_USER: GitHub user whose Jenkins token is defined below
# JENKINS_TOKEN: Jenkins token, to be used to start CI
# JENKINS_TOKEN: Jenkins token, to be used to start or resume CI
name: Auto Start CI

on:
Expand All @@ -27,17 +27,25 @@ jobs:
runs-on: ubuntu-slim
outputs:
numbers: ${{ steps.get_prs_for_ci.outputs.numbers }}
resume_numbers: ${{ steps.get_prs_for_ci.outputs.resume_numbers }}
steps:
- name: Get Pull Requests
id: get_prs_for_ci
run: >
run: |
echo "numbers=$(gh pr list \
--repo "$GITHUB_REPOSITORY" \
--label 'request-ci' \
--json 'number' \
--search 'review:approved' \
-t '{{ range . }}{{ .number }} {{ end }}' \
--limit 5)" >> "$GITHUB_OUTPUT"
echo "resume_numbers=$(gh pr list \
--repo "$GITHUB_REPOSITORY" \
--label 'resume-ci' \
--json 'number' \
--search 'review:approved' \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't yet looked into the details but a question: I assume that resume-ci will fail if new commits have been added since the last run?

No it won't be picked up until it's approved

@panva panva Sep 9, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if an approval for the latest commit is there and [resume-ci] is still present then it will fail to start and report such.

-t '{{ range . }}{{ .number }} {{ end }}' \
--limit 5)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
start-ci:
Expand All @@ -47,7 +55,9 @@ jobs:
pull-requests: write
statuses: read
needs: get-prs-for-ci
if: needs.get-prs-for-ci.outputs.numbers != ''
if: >-
needs.get-prs-for-ci.outputs.numbers != '' ||
needs.get-prs-for-ci.outputs.resume_numbers != ''
runs-on: ubuntu-slim
steps:
- name: Install Node.js
Expand All @@ -71,8 +81,17 @@ jobs:
JENKINS_TOKEN: ${{ secrets.JENKINS_TOKEN }}

- name: Start the CI
if: needs.get-prs-for-ci.outputs.numbers != ''
run: |
curl -fsSL "https://github.com/${GITHUB_REPOSITORY}/raw/${GITHUB_SHA}/tools/actions/start-ci.sh" \
| sh -s -- ${{ needs.get-prs-for-ci.outputs.numbers }}
env:
GH_TOKEN: ${{ github.token }}

- name: Resume the CI
if: needs.get-prs-for-ci.outputs.resume_numbers != ''
run: |
curl -fsSL "https://github.com/${GITHUB_REPOSITORY}/raw/${GITHUB_SHA}/tools/actions/resume-ci.sh" \
| sh -s -- ${{ needs.get-prs-for-ci.outputs.resume_numbers }}
env:
GH_TOKEN: ${{ github.token }}
17 changes: 17 additions & 0 deletions doc/contributing/collaborator-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,21 @@ Once this label is added, `github-actions bot` will start
the `node-test-pull-request` automatically. If the `github-actions bot`
is unable to start the job, it will update the label with `request-ci-failed`.

To resume an existing CI run, add the `resume-ci` label to the pull request.
As with `request-ci`, the pull request must have an approving review. The bot
removes `resume-ci` when processing the request. If it cannot resume the job, it
adds `resume-ci-failed` and posts the command output with a link to the workflow
run.

Do not combine `request-ci` and `resume-ci`. Each script checks the current labels
and reports a failure if the other request label is present, without starting or
resuming CI.

The job must be failed or aborted and resumable, and its CI-approved commit must
still match the pull request's HEAD. Resuming is refused when available failure
diagnostics reference files changed by the pull request. Use `request-ci` when a
fresh CI run is needed instead.

### Internal vs. public API

All functionality in the official Node.js documentation is part of the public
Expand Down Expand Up @@ -1011,6 +1026,8 @@ If you cannot find who to cc for a file, `git shortlog -n -s <file>` can help.
* `never-stale`: Issues and pull requests exempt from automatic stale handling
* `request-ci`: When this label is added to a PR, CI will be started
automatically. See [Starting a Jenkins CI job](#starting-a-jenkins-ci-job)
* `resume-ci`: When this label is added to a PR, the latest linked CI run will be
resumed if eligible. See [Starting a Jenkins CI job](#starting-a-jenkins-ci-job)
* `stale`: Issues and pull requests with no activity for 90 days. See
[Stale issues and pull requests](#stale-issues-and-pull-requests)
* `tsc-agenda`: Open issues and pull requests with this label will be added to
Expand Down
34 changes: 34 additions & 0 deletions tools/actions/resume-ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh

set -xe

RESUME_CI_LABEL="resume-ci"
RESUME_CI_FAILED_LABEL="resume-ci-failed"
cqurl="${GITHUB_SERVER_URL:?}/${GITHUB_REPOSITORY:?}/actions/runs/${GITHUB_RUN_ID:?}"

for pr in "$@"; do
start_requested=$(gh -R "$GITHUB_REPOSITORY" pr view "$pr" --json labels \
--jq 'any(.labels[]; .name == "request-ci")')
gh -R "$GITHUB_REPOSITORY" pr edit "$pr" --remove-label "$RESUME_CI_LABEL"

ci_resumed=yes
rm -f output;
if [ "$start_requested" = "true" ]; then
echo 'Refusing to resume CI while the request-ci label is present' >output
ci_resumed=no
else
ncu-ci resume "$pr" >output 2>&1 || ci_resumed=no
fi
cat output

if [ "$ci_resumed" = "no" ]; then
gh -R "$GITHUB_REPOSITORY" pr edit "$pr" --add-label "$RESUME_CI_FAILED_LABEL"

body="<details><summary>Failed to resume CI</summary><pre>$(cat output)</pre><a href='$cqurl'>$cqurl</a></details>"
echo "$body"

gh -R "$GITHUB_REPOSITORY" pr comment "$pr" --body "$body"

rm output
fi
done;
9 changes: 8 additions & 1 deletion tools/actions/start-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ REQUEST_CI_FAILED_LABEL="request-ci-failed"
cqurl="${GITHUB_SERVER_URL:?}/${GITHUB_REPOSITORY:?}/actions/runs/${GITHUB_RUN_ID:?}"

for pr in "$@"; do
resume_requested=$(gh -R "$GITHUB_REPOSITORY" pr view "$pr" --json labels \
--jq 'any(.labels[]; .name == "resume-ci")')
gh -R "$GITHUB_REPOSITORY" pr edit "$pr" --remove-label "$REQUEST_CI_LABEL"

ci_started=yes
rm -f output;
ncu-ci run --check-for-duplicates "$pr" >output 2>&1 || ci_started=no
if [ "$resume_requested" = "true" ]; then
echo 'Refusing to start CI while the resume-ci label is present' >output
ci_started=no
else
ncu-ci run --check-for-duplicates "$pr" >output 2>&1 || ci_started=no
fi
cat output

if [ "$ci_started" = "no" ]; then
Expand Down
Loading