From 5ebc144f828b24156fe18dbb34eeb1fa2ab17ec1 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Fri, 17 Jul 2026 17:41:12 -0700 Subject: [PATCH] fix(ci): diff pre-commit changed files against the live base, cap the env payload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit github.event.pull_request.base.sha is frozen at PR creation, so the changed-files detection on a long-lived PR diffs against the original branch point and picks up all of master's churn since then. This week that list crossed the kernel's per-env-var size limit (MAX_ARG_STRLEN), killing the pre-commit step with "Argument list too long" before bash could start — observed on #41127, where the frozen base predated the antd v6 upgrade and the i18n catalog canonicalization. Diff against HEAD^1 instead: HEAD is the PR merge commit, so its first parent is the current base-branch tip and the diff is exactly the PR's own files. Also fall back to --all-files when the computed list exceeds 100KB, so a PR that legitimately touches thousands of files degrades to a full sweep instead of an unstartable step. Co-Authored-By: Claude Fable 5 --- .github/workflows/pre-commit.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 11ad48f4b3e..ab95614b8a5 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -81,7 +81,6 @@ jobs: id: changed_files env: EVENT_NAME: ${{ github.event_name }} - BASE_SHA: ${{ github.event.pull_request.base.sha }} BEFORE_SHA: ${{ github.event.before }} run: | set -euo pipefail @@ -95,7 +94,15 @@ jobs: # Resolve the commit to diff against. base="" if [ "${EVENT_NAME}" = "pull_request" ]; then - base="${BASE_SHA}" + # HEAD is the PR merge commit, so its first parent is the current + # tip of the base branch. github.event.pull_request.base.sha is + # NOT that: GitHub freezes it at PR creation, so on a long-lived + # PR it points at the original branch point and the diff picks up + # all of the base branch's churn since then — thousands of paths, + # enough for the CHANGED_FILES env var below to exceed the + # kernel's per-variable size limit and kill the step with + # "Argument list too long" before bash even starts. + base="$(git rev-parse HEAD^1 2>/dev/null || true)" elif [ -n "${BEFORE_SHA:-}" ] && \ [ "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ]; then base="${BEFORE_SHA}" @@ -114,6 +121,15 @@ jobs: # Files present in HEAD that changed since the base (drop deletions). files="$(git diff --name-only --diff-filter=ACMRT "${base}...HEAD")" + # Env vars have a hard per-variable size limit (E2BIG at step + # start). A PR that legitimately touches thousands of files is + # better served by --all-files anyway. + if [ "$(printf '%s' "${files}" | wc -c)" -gt 100000 ]; then + echo "::notice::Changed-file list too large to pass via env; falling back to --all-files." + echo "mode=all" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [ -z "${files}" ]; then echo "mode=none" >> "$GITHUB_OUTPUT" else