Skip to content

ci: move the large file check into a script shared with rust_lint.sh - #25440

Merged
kumarUjjawal merged 2 commits into
apache:mainfrom
akashjainn:ci-large-files-local-script
Sep 20, 2026
Merged

kumarUjjawal merged 2 commits into
apache:mainfrom
akashjainn:ci-large-files-local-script

Conversation

@akashjainn

@akashjainn akashjainn commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

The "Large files PR check" workflow rejects pull requests that commit a file larger than 1.5 MB, but its logic lives inline in the workflow YAML, so a contributor cannot run it before pushing and only learns about an oversized file from CI. This moves the check into a script that CI and the local lint suite share, so the "Large file check" item in #21048 is covered the same way #25359 covered the security audit.

What changes are included in this PR?

  • ci/scripts/check_large_files.sh is a new executable script. It lists the objects committed between a base ref and a head ref and fails if any blob is larger than the limit. --base defaults to the merge base of the head and apache/datafusion, --head defaults to HEAD, and --max-bytes defaults to the 1.5 MB the workflow used. Both refs are validated before the range is listed. The ::error annotation is only printed when GITHUB_ACTIONS is set, so local runs get the plain message on stderr.
  • .github/workflows/large_files.yml keeps the same job, step name, triggers, permissions, runner and checkout, and its run step now passes the PR or merge-queue SHAs it already computed to the script. The size limit and its comment move from the step's env: block into the script.
  • dev/rust_lint.sh runs the script as a read-only step after the ASF status check validation. The --write and --allow-dirty flags never reach it.
  • docs/source/contributor-guide/testing.md documents the standalone command and the range flags.

One difference from the inline version: the script sizes objects with a single git cat-file --batch-check instead of one git cat-file -s per object, and skips commits and trees by object type rather than by an empty path. On a 2000 commit range with 29,214 objects, the inline loop took 11 min 20 s locally and the script took 0.8 s, with identical output.

What is the testing strategy for this PR?

  • The old inline loop and the new script were run on the same four ranges of this repository's history, including the commit that added the 3.7 MB docs/logos/Datafusion_Branding_Guideline.pdf. Exit codes and stderr were identical for all four: three passing ranges and the PDF commit failing with the same message.
  • In a throwaway worktree, a 2 MB file was committed on a branch off origin/main and the script was run with no arguments. It picked the merge base as the default and failed on the new file. --max-bytes 20000 on a small range fails on the expected files, and an unknown --base or --head exits 1 with a message naming the ref.
  • With GITHUB_ACTIONS=true the ::error file= line is printed; without it, nothing is printed to stdout.
  • The script runs under bash 3.2 (macOS /bin/bash) and bash 5, and passes shellcheck. typos, prettier, check_asf_yaml_status_checks.py and check_no_cargo_install_in_workflows.sh pass on the changed files. The workflow file parses and still has the single check-files job with the Check size of new Git objects step.

Are there any user-facing changes?

No. Contributors get a new local check via ./dev/rust_lint.sh or ./ci/scripts/check_large_files.sh.

@github-actions github-actions Bot added documentation Improvements or additions to documentation development-process Related to development process of DataFusion labels Sep 17, 2026
@codecov-commenter

codecov-commenter commented Sep 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.36%. Comparing base (98b26c5) to head (3389473).
⚠️ Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #25440      +/-   ##
==========================================
+ Coverage   82.33%   82.36%   +0.02%     
==========================================
  Files        1137     1137              
  Lines      432049   432937     +888     
  Branches   432049   432937     +888     
==========================================
+ Hits       355723   356577     +854     
- Misses      54826    54829       +3     
- Partials    21500    21531      +31     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kumarUjjawal kumarUjjawal left a comment

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.

Thank you @akashjainn for working on this. Left few comments please take a look.

Comment thread ci/scripts/check_large_files.sh Outdated
echo "[${SCRIPT_NAME}] origin/main is not available; pass --base <ref> to choose the start of the range" >&2
exit 1
fi
BASE_REF="$(git merge-base "${HEAD_REF}" origin/main)"

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.

For most contributors, origin is their fork, so origin/main is not the upstream branch. Then the check covers commits they did not write, or it fails when origin/main does not exist. Would it work to use the remote that points at apache/datafusion, and use origin only when there is no such remote?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for pointing this out! The default base now uses main on the remote whose URL points at apache/datafusion, and falls back to origin only when there is no such remote.

Fixed here: 3389473

Comment thread ci/scripts/check_large_files.sh Outdated
echo "::error file=${path}::File ${path} has size ${size}, exceeding ${MAX_FILE_SIZE_BYTES} limit."
fi
fi
done < <(

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.

If git rev-list or git cat-file fails here, the loop sees no lines and the check passes. An object listed as missing is skipped in the same way. I'd make both cases fail the check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The object list is now captured into a variable before the loop, so a failing git rev-list or git cat-file fails the check under set -e and pipefail.

Fixed here: 3389473

;;
--max-bytes)
[[ $# -ge 2 ]] || usage
MAX_FILE_SIZE_BYTES="$2"

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.

a value that is not a number is accepted here. Every size comparison then fails, so the check passes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a check for a valid limit value. Thank you for flagging that!

Fixed here: 3389473

@kumarUjjawal kumarUjjawal left a comment

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.

Looks good 👍

@kumarUjjawal

Copy link
Copy Markdown
Contributor

Thank you @akashjainn

@kumarUjjawal
kumarUjjawal added this pull request to the merge queue Sep 20, 2026
Merged via the queue into apache:main with commit b4a8c82 Sep 20, 2026
43 checks passed
Omega359 pushed a commit to Omega359/arrow-datafusion that referenced this pull request Oct 11, 2026
…pache#25440)

## Which issue does this PR close?

- Part of apache#21048. The issue stays open for the other checklist items.

## Rationale for this change

The "Large files PR check" workflow rejects pull requests that commit a
file larger than 1.5 MB, but its logic lives inline in the workflow
YAML, so a contributor cannot run it before pushing and only learns
about an oversized file from CI. This moves the check into a script that
CI and the local lint suite share, so the "Large file check" item in
apache#21048 is covered the same way apache#25359 covered the security audit.

## What changes are included in this PR?

- `ci/scripts/check_large_files.sh` is a new executable script. It lists
the objects committed between a base ref and a head ref and fails if any
blob is larger than the limit. `--base` defaults to the merge base of
the head and `apache/datafusion`, `--head` defaults to `HEAD`, and
`--max-bytes` defaults to the 1.5 MB the workflow used. Both refs are
validated before the range is listed. The `::error` annotation is only
printed when `GITHUB_ACTIONS` is set, so local runs get the plain
message on stderr.
- `.github/workflows/large_files.yml` keeps the same job, step name,
triggers, permissions, runner and checkout, and its run step now passes
the PR or merge-queue SHAs it already computed to the script. The size
limit and its comment move from the step's `env:` block into the script.
- `dev/rust_lint.sh` runs the script as a read-only step after the ASF
status check validation. The `--write` and `--allow-dirty` flags never
reach it.
- `docs/source/contributor-guide/testing.md` documents the standalone
command and the range flags.

One difference from the inline version: the script sizes objects with a
single `git cat-file --batch-check` instead of one `git cat-file -s` per
object, and skips commits and trees by object type rather than by an
empty path. On a 2000 commit range with 29,214 objects, the inline loop
took 11 min 20 s locally and the script took 0.8 s, with identical
output.

## What is the testing strategy for this PR?

- The old inline loop and the new script were run on the same four
ranges of this repository's history, including the commit that added the
3.7 MB `docs/logos/Datafusion_Branding_Guideline.pdf`. Exit codes and
stderr were identical for all four: three passing ranges and the PDF
commit failing with the same message.
- In a throwaway worktree, a 2 MB file was committed on a branch off
`origin/main` and the script was run with no arguments. It picked the
merge base as the default and failed on the new file. `--max-bytes
20000` on a small range fails on the expected files, and an unknown
`--base` or `--head` exits 1 with a message naming the ref.
- With `GITHUB_ACTIONS=true` the `::error file=` line is printed;
without it, nothing is printed to stdout.
- The script runs under bash 3.2 (macOS `/bin/bash`) and bash 5, and
passes `shellcheck`. `typos`, `prettier`,
`check_asf_yaml_status_checks.py` and
`check_no_cargo_install_in_workflows.sh` pass on the changed files. The
workflow file parses and still has the single `check-files` job with the
`Check size of new Git objects` step.

## Are there any user-facing changes?

No. Contributors get a new local check via `./dev/rust_lint.sh` or
`./ci/scripts/check_large_files.sh`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

development-process Related to development process of DataFusion documentation Improvements or additions to documentation v56.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants