Skip to content

[CI] Run pip-compile pre-commit hooks only when requirements change - #59526

Merged
khluu merged 6 commits into
vllm-project:mainfrom
tahsintunan:ci/pip-compile-only-on-requirements-change
Nov 4, 2026
Merged

khluu merged 6 commits into
vllm-project:mainfrom
tahsintunan:ci/pip-compile-only-on-requirements-change

Conversation

@tahsintunan

@tahsintunan tahsintunan commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Problem: CI runs pre-commit with --all-files, so the 5 pip-compile hooks re-resolve every lockfile against PyPI and download.pytorch.org on every run, even when nothing in requirements/ changed. When those indexes return a 502/503, pre-commit fails for changes that have nothing to do with dependencies.
  • Impact: During a burst of 502s from files.pythonhosted.org (Aug 15–19), 57 PR pre-commit runs failed inside these hooks. Main went red 18 times from May to Sep for the same reason (see Examples).
  • Fix: skip pip-compile in the --all-files run, and run it separately on only the files the commit changed. The hooks' existing files: filters then decide whether they need to run, so they only touch the network when requirements change.
  • If .pre-commit-config.yaml changed, they still run on all files, because a uv bump or a hook-args edit can change the lockfiles without touching requirements/ (as in Update pre-commit hook versions #26591).

Examples

  • Jul 6, pip-compile-xpu, 503 from download.pytorch.org: run 28826483690
  • Jul 7, pip-compile-xpu, 503 from download.pytorch.org: run 28834611183
  • Jul 7, pip-compile-xpu, 503 from download.pytorch.org: run 28840983587
  • Jul 7, pip-compile-xpu, 503 from download.pytorch.org: run 28901713650
  • Jul 8, pip-compile-xpu, 503 from download.pytorch.org: run 28977448720
  • Aug 15, pip-compile-cpu, 502 from files.pythonhosted.org: run 31888326977
  • Aug 16, pip-compile-xpu and pip-compile-docs, 502 from files.pythonhosted.org: run 31935561992
  • Aug 16, pip-compile-rocm, 502 from files.pythonhosted.org: run 31938637047
  • Aug 17, pip-compile, pip-compile-rocm and pip-compile-xpu, 502 from files.pythonhosted.org: run 32012766971
  • Aug 17, pip-compile, pip-compile-xpu, pip-compile-cpu and pip-compile-docs, 502 from files.pythonhosted.org: run 32021711554
  • Aug 17, pip-compile-cpu, 502 from files.pythonhosted.org: run 32047339080
  • Aug 17, pip-compile-cpu, 502 from files.pythonhosted.org: run 32073834879
  • Aug 18, pip-compile and pip-compile-rocm, 502 from files.pythonhosted.org: run 32170751177
  • Aug 18, pip-compile-cpu, 502 from files.pythonhosted.org: run 32172635973
  • Aug 18, pip-compile-xpu, 502 from files.pythonhosted.org: run 32187315071
  • Aug 18, pip-compile-cpu, 502 from files.pythonhosted.org: run 32194198346
  • Aug 19, pip-compile and pip-compile-xpu, 502 from files.pythonhosted.org: run 32208700153
  • Sep 27, pip-compile-xpu, 503 from download.pytorch.org: run 36288536065

Tests

Real GitHub Actions runs on my fork. "Network blocked" means a dead proxy on the pip-compile step to simulate a 502 burst. Look at the pip-compile (only if its inputs changed) step: the jobs themselves are red because actionlint flags a line in the test harness, or because pre-commit hit a 504 while installing hook environments.

  • Unrelated change, network blocked: 5x "(no files to check)", passes (PR, push)
  • Control, old --all-files behavior with network blocked: all 5 fail with "Connection refused" (run)
  • Stale requirements/test/xpu.in: only pip-compile-xpu runs and fails with +toolz (PR, push)
  • Same change, relocked: pip-compile-xpu passes (run)
  • [tool.uv]-only change in pyproject.toml: cuda, rocm, xpu, cpu fail with +openai-harmony (PR, push)
  • Same change, relocked: all 5 pass (run)
  • pyproject.toml change outside [tool.uv]: all 5 run and pass (run)
  • Comment-only .pre-commit-config.yaml change: all 5 run and pass (run)
  • Ruff error plus stale lockfile: the main step fails on ruff, and the pip-compile step still runs and catches +toolz (run)

…mmit config change

Signed-off-by: Tahsin Tunan <tahsintunan@gmail.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@mergify mergify Bot added the ci/build label Oct 1, 2026

@khluu khluu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, this is a good fix. The 502/503 failures from these hooks have been painful. I checked how it works and it holds up: all five hooks share the pip-compile id, so SKIP and pre-commit run pip-compile cover all of them. On PRs, HEAD^1 of the merge ref is the base, so the diff is right. And every -r include sits inside the hooks' files: filters. Your own run shows the skip path working.

One gap I'd like closed before merging: uv pip compile also reads [tool.uv] from pyproject.toml, which this doesn't account for. Details are inline. The other comments are smaller.

Could you also link runs where the hooks actually execute? For example, a throwaway commit touching requirements/common.txt and one touching .pre-commit-config.yaml. The current run only shows the skip path, and a broken diff would look the same ("no files to check").

Comment thread .github/workflows/pre-commit.yml Resolved
Comment thread .github/workflows/pre-commit.yml Outdated
SKIP: ""
run: |
if git diff --quiet HEAD^1 HEAD -- .pre-commit-config.yaml; then
pre-commit run pip-compile --hook-stage manual --show-diff-on-failure --color=always --from-ref HEAD^1 --to-ref HEAD

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On push to main, HEAD^1 only covers the last commit, so if several commits land in one push, the earlier ones aren't checked. Using ${{ github.event.before }} as the from-ref for push events (with a deeper fetch) would cover the whole push. Low priority since we squash-merge.

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.

Yeah, decided to leave this out. HEAD^1 covers the whole push in practice, since every merge is a squash.

Comment thread .github/workflows/pre-commit.yml Resolved
Comment thread .github/workflows/pre-commit.yml Resolved
Comment thread .github/workflows/pre-commit.yml Resolved
…and even if other hooks fail

Signed-off-by: Tahsin Tunan <tahsintunan@gmail.com>
@tahsintunan
tahsintunan requested a review from hmellor as a code owner October 1, 2026 12:56
Signed-off-by: Tahsin Tunan <tahsintunan@gmail.com>
@tahsintunan

Copy link
Copy Markdown
Contributor Author

One gap I'd like closed before merging: uv pip compile also reads [tool.uv] from pyproject.toml, which this doesn't account for.

Done.

Could you also link runs where the hooks actually execute?

Description updated with throwaway test runs.

@khluu

@tahsintunan
tahsintunan requested a review from khluu October 1, 2026 14:20
Comment thread .github/workflows/pre-commit.yml Resolved
Comment thread .github/workflows/pip-compile-drift.yml Outdated
Comment on lines +23 to +37
- run: python -m pip install pre-commit
- name: Re-resolve all lockfiles (retries index errors)
run: |
for attempt in 1 2 3; do
if pre-commit run pip-compile --hook-stage manual --all-files --show-diff-on-failure --color=always; then
exit 0
fi
# A failed attempt may have rewritten the lockfiles; reset them so a
# retry cannot pass on files the previous attempt fixed up.
git checkout -- requirements
if [ "$attempt" -lt 3 ]; then
sleep 60
fi
done
exit 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment here, why not use the hook that already exists and specify only pip-compile?

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 loop is for retries. It reruns on a PyPI 502 and resets the lockfiles between attempts, so a nightly blip doesn't go red. The action has no built-in retry, so I kept the loop.

@tahsintunan
tahsintunan requested a review from hmellor October 14, 2026 17:06
@mergify

mergify Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @tahsintunan.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Oct 29, 2026
Signed-off-by: Tahsin Tunan <tahsintunan@gmail.com>
@tahsintunan
tahsintunan requested a review from a team November 4, 2026 16:15
@mergify mergify Bot removed the needs-rebase label Nov 4, 2026

@khluu khluu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Kevin's review agent: approve for CI changes only

@khluu
khluu merged commit 4527515 into vllm-project:main Nov 4, 2026
9 checks passed
@tahsintunan
tahsintunan deleted the ci/pip-compile-only-on-requirements-change branch November 5, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants