Commit 51376380627 for nodejs
commit 51376380627ef1ec1db20fb53a0547e2a23995f0
Author: Filip Skokan <panva.ip@gmail.com>
Date: Sun Sep 27 14:34:10 2026 +0200
tools: check CI availability and workload
Select mergeable PRs and check Jenkins availability and workload before
removing request labels. Leave requests for a later run when Jenkins is
unavailable or the workload has reached the configured limit.
Make the batch size and workload limit repository variables, defaulting
to 5 and 10 respectively.
Refs: https://github.com/nodejs/node-core-utils/pull/1204
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/66280
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml
index c8b090fdc04..85f3e92f2ff 100644
--- a/.github/workflows/auto-start-ci.yml
+++ b/.github/workflows/auto-start-ci.yml
@@ -1,6 +1,9 @@
# 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 or resume CI
+# Optional repository variables:
+# AUTO_START_CI_BATCH_SIZE: maximum PRs to process per run (default: 5)
+# AUTO_START_CI_MAX_WORKLOAD: pause at this many running or queued PR jobs (default: 15)
name: Auto Start CI
on:
@@ -30,16 +33,25 @@ jobs:
steps:
- name: Get Pull Requests
id: get_prs_for_ci
+ # Explicit bash enables pipefail so jq cannot hide a failed gh query.
+ shell: bash
run: |
+ if ! [[ "$BATCH_SIZE" =~ ^[1-9][0-9]*$ ]]; then
+ echo '::error::AUTO_START_CI_BATCH_SIZE must be a strictly positive integer'
+ exit 1
+ fi
+ # Filter before selecting the batch; UNKNOWN mergeability is retried later.
numbers=$(gh pr list \
--repo "$GITHUB_REPOSITORY" \
- --json 'number' \
+ --json 'number,mergeable' \
--search 'review:approved label:request-ci,resume-ci' \
- -t '{{ range . }}{{ .number }} {{ end }}' \
- --limit 5)
+ --limit 100 \
+ | jq --argjson limit "$BATCH_SIZE" \
+ '[.[] | select(.mergeable == "MERGEABLE") | .number] | .[:$limit] | map(tostring) | join(" ")' -r)
echo "numbers=$numbers" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ github.token }}
+ BATCH_SIZE: ${{ vars.AUTO_START_CI_BATCH_SIZE || '5' }}
start-ci:
permissions:
checks: read
@@ -78,3 +90,4 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
PULL_REQUESTS: ${{ needs.get-prs-for-ci.outputs.numbers }}
+ MAX_WORKLOAD: ${{ vars.AUTO_START_CI_MAX_WORKLOAD || '15' }}
diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh
index 4573b17761c..6482f366fa3 100755
--- a/tools/actions/start-ci.sh
+++ b/tools/actions/start-ci.sh
@@ -3,6 +3,14 @@
set -xe
cqurl="${GITHUB_SERVER_URL:?}/${GITHUB_REPOSITORY:?}/actions/runs/${GITHUB_RUN_ID:?}"
+max_workload=${MAX_WORKLOAD:-15}
+case $max_workload in
+ *[!0-9]*)
+ echo '::error::AUTO_START_CI_MAX_WORKLOAD must be a positive integer'
+ exit 1
+ ;;
+ *) ;;
+esac
escape_code_block_or_line() {
case $1 in
@@ -19,6 +27,30 @@ escape_code_block_or_line() {
}
for pr in "$@"; do
+ # Sleep in between.
+ [ "$pr" = "$1" ] || sleep 20
+
+ # Keep request labels until Jenkins is ready to accept more work.
+ if ! ncu-ci available; then
+ echo '::notice::CI is unavailable; leaving CI requests for a later run.'
+ break
+ fi
+ if ! workload=$(ncu-ci workload); then
+ echo '::notice::CI workload could not be checked; leaving CI requests for a later run.'
+ break
+ fi
+ case $workload in
+ ''|*[!0-9]*)
+ echo '::error::ncu-ci workload did not return a positive integer'
+ exit 1
+ ;;
+ *) ;;
+ esac
+ if ! [ "$workload" -lt "$max_workload" ]; then
+ echo "::notice::CI workload is $workload (limit: $max_workload); leaving CI requests for a later run."
+ break
+ fi
+
request_labels=$(gh -R "$GITHUB_REPOSITORY" pr view "$pr" --json labels \
--jq '[.labels[].name | select(. == "request-ci" or . == "resume-ci")] | sort | join(",")')
case "$request_labels" in