From 938697d819ccf82749b7551d6ded1071eb93015c Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 25 Sep 2026 14:01:09 +0200 Subject: [PATCH 1/5] 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 Assisted-by: Codex --- .github/workflows/auto-start-ci.yml | 18 +++++++++++++++--- tools/actions/start-ci.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index c8b090fdc04..41db2952013 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: 10) name: Auto Start CI on: @@ -30,16 +33,24 @@ jobs: steps: - name: Get Pull Requests id: get_prs_for_ci + shell: bash run: | + if ! [[ "$BATCH_SIZE" =~ ^(0|[1-9][0-9]*)$ ]]; then + echo '::error::AUTO_START_CI_BATCH_SIZE must be a non-negative 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 +89,4 @@ jobs: env: GH_TOKEN: ${{ github.token }} PULL_REQUESTS: ${{ needs.get-prs-for-ci.outputs.numbers }} + MAX_WORKLOAD: ${{ vars.AUTO_START_CI_MAX_WORKLOAD || '10' }} diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh index 4573b17761c..88b3cc316d7 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:-10} +case $max_workload in + *[!0-9]*) + echo '::error::AUTO_START_CI_MAX_WORKLOAD must be a non-negative integer' + exit 1 + ;; + *) ;; +esac escape_code_block_or_line() { case $1 in @@ -19,6 +27,27 @@ escape_code_block_or_line() { } for pr in "$@"; do + # 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 non-negative 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 From 16f8d11b5e54132f84c0b066b84225179db1aad2 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 25 Sep 2026 17:12:51 +0200 Subject: [PATCH 2/5] fixup! tools: check CI availability and workload --- .github/workflows/auto-start-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 41db2952013..31ab572109b 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -33,10 +33,11 @@ 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" =~ ^(0|[1-9][0-9]*)$ ]]; then - echo '::error::AUTO_START_CI_BATCH_SIZE must be a non-negative integer' + 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. From 36bbb97377edd13e8b416a1ea6f6b94b10dbba38 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 25 Sep 2026 17:21:46 +0200 Subject: [PATCH 3/5] fixup! tools: check CI availability and workload --- .github/workflows/auto-start-ci.yml | 4 ++-- tools/actions/start-ci.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 31ab572109b..85f3e92f2ff 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -3,7 +3,7 @@ # 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: 10) +# AUTO_START_CI_MAX_WORKLOAD: pause at this many running or queued PR jobs (default: 15) name: Auto Start CI on: @@ -90,4 +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 || '10' }} + MAX_WORKLOAD: ${{ vars.AUTO_START_CI_MAX_WORKLOAD || '15' }} diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh index 88b3cc316d7..d8e9792f612 100755 --- a/tools/actions/start-ci.sh +++ b/tools/actions/start-ci.sh @@ -3,7 +3,7 @@ set -xe cqurl="${GITHUB_SERVER_URL:?}/${GITHUB_REPOSITORY:?}/actions/runs/${GITHUB_RUN_ID:?}" -max_workload=${MAX_WORKLOAD:-10} +max_workload=${MAX_WORKLOAD:-15} case $max_workload in *[!0-9]*) echo '::error::AUTO_START_CI_MAX_WORKLOAD must be a non-negative integer' From fd3f7867bc10dcb7ae1ab22970c4418ccbf8bfc3 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 25 Sep 2026 17:55:07 +0200 Subject: [PATCH 4/5] Apply batched suggestions from code review Co-authored-by: Antoine du Hamel --- tools/actions/start-ci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh index d8e9792f612..c17d885cc53 100755 --- a/tools/actions/start-ci.sh +++ b/tools/actions/start-ci.sh @@ -6,7 +6,7 @@ cqurl="${GITHUB_SERVER_URL:?}/${GITHUB_REPOSITORY:?}/actions/runs/${GITHUB_RUN_I max_workload=${MAX_WORKLOAD:-15} case $max_workload in *[!0-9]*) - echo '::error::AUTO_START_CI_MAX_WORKLOAD must be a non-negative integer' + echo '::error::AUTO_START_CI_MAX_WORKLOAD must be a positive integer' exit 1 ;; *) ;; @@ -38,7 +38,7 @@ for pr in "$@"; do fi case $workload in ''|*[!0-9]*) - echo '::error::ncu-ci workload did not return a non-negative integer' + echo '::error::ncu-ci workload did not return a positive integer' exit 1 ;; *) ;; From a22862f99f0b5fac13148d6e208a92cb5d80e751 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 26 Sep 2026 09:29:01 +0200 Subject: [PATCH 5/5] fixup! tools: check CI availability and workload --- tools/actions/start-ci.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh index c17d885cc53..6482f366fa3 100755 --- a/tools/actions/start-ci.sh +++ b/tools/actions/start-ci.sh @@ -27,6 +27,9 @@ 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.'