Repository navigation
Remove uv version requirements in third-party tests - #800
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #800 +/- ##
=======================================
Coverage 97.26% 97.26%
=======================================
Files 3 3
Lines 7859 7859
=======================================
Hits 7644 7644
Misses 215 215
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
AlexWaygood
marked this pull request as ready for review
October 12, 2026 11:32
Member
Author
|
I expanded the PR description with some other alternative designs I considered here. I think this is probably the best route for now. |
JelleZijlstra
approved these changes
Oct 12, 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.
A third-party checkout can require a newer uv version than the one pinned in CI, causing the third-party tests to fail before they run.
Before running each third-party test suite, remove any uv
required-versionfrom the checkout's rootpyproject.tomloruv.toml, preserving other uv settings. The helper leaves files unchanged when there is no requirement and fails without updating either file if it cannot safely remove one as a single-line assignment.Fixes #798.
Related: hauntsaninja/mypy_primer#262.
Alternative design considered: a PEP-723 script
I initially tried making this helper script a PEP-723 script that used
tomlkit. That design is preserved as the first commit on this branch, and it would be more general and more robust. I decided against it, however, on YAGNI grounds. For our purposes, I think introducing a PEP-723 script -- which would require its own lockfile, which would need to be checked and updated in CI -- would be too much complexity for a CI helper that has a very specific, limited purpose.Alternative design considered: an off-the-shelf GitHub workflow
I also considered using
cssnr/toml-actionv2.0.0, which could be used to update thetool.uv.required-versionfields in pyproject.toml files to>=0.0.0, for example:Codex's comparison of the two approaches
If we used
cssnr/toml-actionv2.0.0, each job would need equivalent steps for its checkout. The conditions skip missing files; if a file exists but the key does not, the action creates the key. Neither approach guarantees that the pinned uv actually supports every feature a checkout needs, so a checkout could still fail later for compatibility reasons.Current checkouts. I tested both approaches against root configuration snapshots from the nine repositories in the workflow, including both SQLAlchemy branches. Only pydantic had a root uv requirement,
>=0.13.0. The helper succeeded on all ten snapshots and changed only pydantic’s file. The action succeeded on the nine existingpyproject.tomlfiles, with no changes to parsed values or their types except for the intended requirement. It rewrote all nine files, removed their comments, and added the requirement to the other eight. The remaining checkout,typing_inspect, had neither root configuration file; none had a rootuv.toml.Preserving configuration. The action parses and serializes the whole file, so it can silently change unrelated values. In a synthetic example, it changed the TOML float
1.0to the integer1and shortened the timestamp1979-05-27T07:32:00.123456Zto1979-05-27T07:32:00.123Z. Formatting and comment changes alone are unlikely to matter in these temporary CI checkouts, but changed values could matter if uv, the build, or the tests use them. I found no such value changes in the current snapshots.The helper removes a single line and checks that the parsed configuration otherwise matches. It prepares changes to both files before writing them, so an unsupported requirement in either file causes it to stop without changing either. An I/O error during the later writes could still leave a partial update.
Supported layouts. The action handled an inline table such as:
The helper intentionally supports standalone single-line assignments and stops if it cannot safely remove the requirement. Thus the action handles more valid layouts, while the helper can make a job fail if a checkout changes to an unsupported layout.
Configuration discovery. Adding a previously absent
[tool.uv]table can change which configuration uv discovers. In a synthetic hierarchy, uv initially honored a parentuv.toml; after the action created[tool.uv]in the checkout’spyproject.toml, uv no longer discovered that parent file. I have not established that the actual runner workspace has an affected parent configuration. See uv’s configuration discovery rules.Supply chain. The helper uses Python’s standard library and introduces no additional Python package. The action adds a separate third-party code supply chain: the example pins its approximately 1.1 MB JavaScript bundle to a full commit SHA, and it does not install npm packages at runtime. Pinning prevents the referenced bundle from changing, but the action and its bundled dependencies still need to be trusted and reviewed.
Parser availability. The action’s bundle contains smol-toml
1.7.1, which is affected by a quadratic-time parsing advisory; the fix is in1.9.0. In a local probe, files with 32,000, 64,000 and 128,000 synthetic keys took approximately 0.18, 0.46 and 1.56 seconds respectively. The current configuration snapshots are at most 510 lines. A sufficiently large TOML file could stall a job until its existing 10- or 60-minute timeout. This is an availability issue, not evidence of code execution.Runner commands in logs. The action prints the original selected value without escaping it. I verified locally that a multiline
required-versioncan put::warning::...at the start of an output line. GitHub processes such lines as workflow commands, so spoofed annotations or other supported log commands are plausible; I did not test runner interpretation. The helper rejects that multiline assignment without printing the value. The workflow already executes code from the checked-out repositories, so this does not establish a new isolation boundary against a compromised checkout.The PR’s third-party CI run passed all 43 matrix jobs. My action probes ran locally under Node 26, rather than the action’s Node 24 runtime, and did not run the full third-party test suites. The workflow clones moving branches, so the snapshots can change.
I would keep the helper: the action handles more TOML layouts, but it can silently change unrelated values and adds a separate code supply chain. Those drawbacks have not caused a failure in the current snapshots, so this is a tradeoff rather than evidence that the action would break the present workflow.