ci: reject git-ref dependencies in pyproject.toml - #104
Merged
Conversation
The temporary git pin added in a44da63 (SLS-360) referenced branch deanquinanola/sls-360-local-module-bundling, which was deleted when runpod/flash#352 merged. Any uv lock/sync on main has failed since with "couldn't find remote ref", breaking the scheduled Bump Runtime Dependencies workflow. runpod-flash 1.19.0 is the first release containing runpod_flash.runtime.module_loader, so the pin can now be replaced with the released constraint the original comment called for. - pyproject.toml: git ref -> runpod-flash>=1.19.0 - uv.lock: runpod-flash 1.18.0 (git) -> 1.19.0 (registry) - uv.lock: runpod 1.10.2.dev1 (runpod-python git main) -> 1.10.1 (registry); the git source was pulled in transitively by the flash branch pin and is not intended
A git-ref dependency carries no version, so the Bump Runtime Dependencies workflow has nothing to bump and silently stops tracking that package. The ref is also mutable: when the referenced branch is deleted, every uv lock and uv sync on main hard-fails with "couldn't find remote ref". Both failure modes happened for real. A temporary pin to a flash feature branch (a44da63) silently defeated the bump workflow, then broke main for two weeks once the branch was deleted post-merge. Adds scripts/check_git_deps.py, covering the four places a git ref can enter a uv project: project dependencies, optional-dependency extras, PEP 735 dependency groups, and [tool.uv.sources]. Wired into make quality-check and the CI lint job, so it blocks locally and on PRs. Verified against the offending commit: the checker exits 1 and names the runpod-flash git pin from a44da63's pyproject.toml.
jhcipar
approved these changes
Jul 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #103 — review/merge that first. Base retargets to
mainautomatically once #103 lands.Problem
A git-ref dependency in
pyproject.tomlfails in two distinct ways, and #103 hit both:Bump Runtime Dependenciesbumps by diffing versions out ofuv.lock. A git source has no version to bump, so the package quietly stops being tracked — no error, no signal.uv lock/uv synconmainstarted failing withcouldn't find remote ref.mainwas broken for two weeks before anyone noticed, because the only thing exercising it was a scheduled job.The temporary pin in
a44da63had a comment saying to revert it after release. The comment was correct and got missed anyway — a comment is not an enforcement mechanism.Fix
scripts/check_git_deps.pyfails if any dependency comes from a git ref, covering the four places one can enter a uv project:project.dependenciesproject.optional-dependencies.<extra>dependency-groups.<group>(PEP 735)[tool.uv.sources]entries with agitkeyWired into
make quality-check(so the pre-commit hook catches it locally) and the CIlintjob (so it blocks PRs).Test plan
Built test-first — the checker did not exist when the tests were written, and they failed on the missing module before implementation.
main()exit codes, missing/unparseable file handlingpyproject.tomlis clean, so the guard is self-checkinga44da63'spyproject.toml, the checker exits 1 and names therunpod-flashgit pin. Against the fixed tree it exits 0.make quality-check: 293 passed (283 existing + 10 new), coverage 81.52%, ruff + mypy cleanNote on the escape hatch
This blocks a legitimate pattern: the temporary pin during a coordinated cross-repo release, which is exactly what
a44da63was doing. There is deliberately no bypass flag — the module docstring directs you to land an explicit, time-boxed exception rather than delete the check. If that friction proves wrong in practice, an allowlist keyed to an expiry date would be the better shape, but I would not add it before there is a second real instance to design against.