Skip to content

Commit 7d62fba

Browse files
committed
fix(ci): label-pr reads the paginated PR file list
gh pr diff --name-only fetches the whole diff, which GitHub refuses for a PR of more than 300 files (HTTP 406, "the diff exceeded the maximum number of files (300)"; reproduced on nodejs/node#66546 with gh 2.93.0). The labeling job would fail on such a PR and skip the board step after it. The legacy actions/labeler read the file list. label-pr now reads repos/{repo}/pulls/{n}/files with --paginate and fails closed (VARIABLES-0002) when the list is shorter than the event's changed_files, since that API stops at 3000 files.
1 parent a479273 commit 7d62fba

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

‎.github/scripts/ci.bats‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,22 +2446,32 @@ _fixture_harden_state() {
24462446
[ "${status}" -eq 2 ]
24472447
}
24482448

2449-
# What: Labels PR 5, whose diff touches one workflow file.
2449+
# What: Labels PR 5 (one workflow file), then a short list.
24502450
# Why: The board and release notes read these labels.
24512451
# From: Issue #479, PR #544
24522452
@test "label-pr applies path labels and the title category" {
24532453
local ev="${BATS_TEST_TMPDIR}/ev.json"
2454-
printf '{"pull_request":{"number":5}}' > "${ev}"
2454+
printf '{"pull_request":{"number":5,"changed_files":1}}' > "${ev}"
24552455
_fixture_manifest 'labels:' ' ci:' ' paths: [".github/workflows/**"]'
2456-
# What: Stub gh: a workflow diff; echo pr edit.
2456+
# What: Stub gh: one workflow file; echo pr edit.
24572457
# Why: Labels must come from the SOT path map.
2458-
gh() { case "$1 $2" in "pr diff") echo .github/workflows/v.yml ;; "pr edit") echo "edit $*" ;; esac; }
2458+
gh() {
2459+
case "$1 $2" in
2460+
"api --paginate") [ "$3" = "repos/o/r/pulls/5/files" ] && echo .github/workflows/v.yml ;;
2461+
"pr edit") echo "edit $*" ;;
2462+
esac
2463+
}
24592464
# What: Stub live PR data with a fix(ci) title.
24602465
# Why: The title sets the category label offline.
24612466
_ci_metadata_fetch_live() { export PR_TITLE="fix(ci): x"; }
24622467
GITHUB_REPOSITORY=o/r GITHUB_EVENT_PATH="${ev}" run _ci_variables_label_pr
24632468
[ "${status}" -eq 0 ]
24642469
[[ "${output}" == *"--add-label ci,bug"* ]]
2470+
printf '{"pull_request":{"number":5,"changed_files":3001}}' > "${ev}"
2471+
GITHUB_REPOSITORY=o/r GITHUB_EVENT_PATH="${ev}" run _ci_variables_label_pr
2472+
[ "${status}" -eq 1 ]
2473+
[[ "${output}" == *"CI-ERROR-VARIABLES-0002"*"lists 1 of 3001"* ]]
2474+
[[ "${output}" != *"edit "* ]]
24652475
}
24662476

24672477
# What: Maps a feat, fix, docs and security title.

‎.github/scripts/ci.sh‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,9 +2601,22 @@ _ci_pr_category_label() {
26012601
# From: Issue #479, PR #544
26022602
_ci_variables_label_pr() {
26032603
: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY required}"
2604-
local files hits labels=() category PR_NUMBER
2604+
local files hits labels=() category PR_NUMBER want got
26052605
PR_NUMBER="$(_ci_event_value .pull_request.number)" || return 2
2606-
files="$(gh pr diff "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --name-only)" || return 1
2606+
want="$(_ci_event_value .pull_request.changed_files)" || return 2
2607+
# What: Read the PR file list page by page, not the diff.
2608+
# Why: The diff API refuses a PR of over 300 files (HTTP 406).
2609+
# From: Issue #479, PR #544
2610+
files="$(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" \
2611+
--jq '.[].filename')" || return 1
2612+
got="$(awk 'NF { n++ } END { print n + 0 }' <<< "${files}")"
2613+
# What: Fail on a list shorter than the PR's file count.
2614+
# Why: The files API stops at 3000; no partial labels.
2615+
# From: Issue #479, PR #544
2616+
if [ "${got}" != "${want}" ]; then
2617+
ci_log "[CI-ERROR-VARIABLES-0002]" "PR #${PR_NUMBER} lists ${got} of ${want} changed files"
2618+
return 1
2619+
fi
26072620
hits="$(_ci_classify_paths labels <<< "${files}")" || return 2
26082621
_ci_mapfile labels printf '%s' "${hits}" || return 2
26092622
_ci_metadata_fetch_live || return 2

0 commit comments

Comments
 (0)