`setup-uv` currently ignores the `sha256` supplied by the default
`astral-sh/versions` manifest when a selected artifact is newer than its
bundled checksum table, allowing that download to proceed without
validation. Use the manifest checksum as a fallback after explicit and
bundled checksums, and reject manifest entries that do not provide one.
This preserves the stronger pinned hashes for known releases while
verifying newer releases without requiring an action update. Part of
#1032.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
Co-authored-by: William Woodruff <william@yossarian.net>
Co-authored-by: Kevin Stillhammer <kevin.stillhammer@gmail.com>
CI already disables npm lifecycle scripts, but ordinary installs from
the repository still run them. Set `ignore-scripts = true` in `.npmrc`
so developer and maintenance installs use the same default. Keep the
existing seven-day `min-release-age` policy for new resolutions. Require
`npm>=11.10.0` through `engines.npm` and `engine-strict`, while
retaining `devEngines` for newer clients; older installers can otherwise
ignore `devEngines` and the age setting. Pin the build and checksum
workflows to Node.js `24.19.0` so their bundled `npm` supports the
policy. Explicit project commands such as `npm run package` remain
available.
Related: astral-sh/ruff-action#401 applies the matching `npm` defaults,
and astral-sh/ruff-action#411 adds the same legacy-aware version floor.
astral-sh/ruff#27837 applies the install-script default to Ruff's
JavaScript projects. astral-sh/setup-uv#1027 separately adds
registry-signature and provenance verification.
---------
Co-authored-by: zaniebot <242828183+zaniebot@users.noreply.github.com>
With the self-repo syntax, we also shouldn't need any of these
`actions/checkout` calls.
Signed-off-by: William Woodruff <william@yossarian.net>
---------
Signed-off-by: William Woodruff <william@yossarian.net>
This just adds some pins to the action tests; these tests don't rely on
the packages under test being unpinned.
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
This does two things:
- Bumps our Dependabot-side cooldowns to 30d
- Adds an NPM-side 7d cooldown
The idea is to give automated cooldowns a longer period, whereas humans
doing maintenance/manual bumps can opt into a newer package as needed.
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
## Summary
- remove direct pushes to `main` from the docs update workflow
- remove the same dead push path from the known-checksums workflow
- create update pull requests directly when changes exist
Direct pushes cannot satisfy the repository rule requiring changes
through pull requests.
## Validation
- `npm ci --ignore-scripts`
- `npm run all`
- `actionlint .github/workflows/update-docs.yml
.github/workflows/update-known-checksums.yml`
- `uvx zizmor .github/workflows/update-docs.yml
.github/workflows/update-known-checksums.yml`
Refs: pi-session 019fff9d-7357-783c-8529-65bc5bf562c2
Transient timeout fetching manifests have increased significantly
recently, especially with private runners.
```
Fetching manifest data from https://raw.githubusercontent.com/astral-sh/versions/main/v1/uv.ndjson ...
Error: The operation was aborted due to timeout
```
Retry transient manifest network failures up to three times with a
progressive backoff (not exponential), keeping the total wait bounded
while making setup resilient to short network blips.
Co-authored-by: Raymond <arguile-@users.noreply.github.com>
## Summary
- reject path-like uv versions from `.tool-versions`
- reject path-like Python versions from `.tool-versions`
- document the restriction and cover Unix and Windows paths in tests
## Testing
- `npm ci --ignore-scripts`
- `npm run all`
Refs: pi-session 019ff4bb-8b7c-7c4b-8bdf-7c188dfa2e3f
## Summary
- require the Dependabot rollup skill to commit and push validated
changes
- always create a pull request with the `dependencies` label
- report the created PR and label confirmation
## Testing
- `git diff --check`
Refs: pi-session 019ff0f1-1aee-7691-8a2c-7c708812f7b0
## Summary
Roll up the remaining dependency changes from Dependabot PRs #997, #998,
#999, #1000, #1001, #1002, and #1003:
- update `github/codeql-action` to 4.37.6
- update `zizmorcore/zizmor-action` to 0.6.2
- update `undici` to 8.10.0
- update `smol-toml` to 1.7.1
- update `@biomejs/biome` and its schema to 2.5.6
- regenerate the published bundles
PRs #905 and #907 were excluded because their requested Jest and pep440
versions are already present on `main`.
## Validation
- `npm run all`
- `actionlint .github/workflows/codeql-analysis.yml
.github/workflows/test.yml`
- `uvx zizmor .github/workflows/codeql-analysis.yml
.github/workflows/test.yml`
- `git diff --check`
Refs: pi-session 019ff0c9-8e00-72d3-99ad-d4383a4c57d4
## Summary
Roll up the remaining net changes from the open Dependabot updates:
- release-drafter/release-drafter 7.7.0 (#990)
- github/codeql-action 4.37.4 (#987, #988, #989)
- zizmorcore/zizmor-action 0.6.1 (#986)
- @actions/cache 6.2.0 (#975)
- @biomejs/biome 2.5.4 (#974)
- undici 8.7.0 (#973)
The Jest 30.4.2 (#905) and @renovatebot/pep440 5.0.0 (#907) updates are
already present on main and require no additional changes.
This also updates the Biome schema, applies the formatter changes from
Biome 2.5.4, and regenerates the published bundles.
## Testing
- `npm run all`
- `actionlint`
- `git diff --check`
Refs: pi-session 019ff01b-f917-73c1-950e-2966956f263c
## Summary
- add `latest-known` as an explicit version selector
- resolve it locally to the newest version in the bundled checksum table
- preserve existing default and `latest` behavior
- document custom-manifest checksum semantics and update published
bundles
## Testing
- `npm ci --ignore-scripts`
- `npm run all` (99 tests passed)
Closes#919
Refs: pi-session 019fed0e-6019-7504-911b-bd9955cbbd49
## Summary
- disable `enable-cache: auto` for `pull_request_target`,
`workflow_run`, and `release` events
- disable automatic caching for tag pushes while leaving branch pushes
unchanged
- preserve explicit `enable-cache: true` as an override
- run a `workflow_run` integration fixture with `act` in pull request CI
and verify caching is disabled
- document the behavior and update the published bundles
## Testing
- `npm run all`
- `actionlint .github/workflows/test.yml
__tests__/workflows/workflow-run.yml`
- `uvx zizmor __tests__/workflows/workflow-run.yml`
Closes#984
Refs: pi-session 019fec42-9b26-714e-a359-830ac4401ecd
## Summary
Roll up the remaining dependency changes from Dependabot PRs:
- #966: update `actions/setup-node` from 6.4.0 to 7.0.0
- #965: update `js-yaml` from 4.1.1 to 5.2.1
- #964: update `@types/node` from 26.0.1 to 26.1.1
- #963: update `esbuild` from 0.28.0 to 0.28.1
PRs #907 and #905 require no net changes because `@renovatebot/pep440`
5.0.0 and Jest 30.4.2 are already on `main`.
## Validation
- `npm run all`
Refs: pi-session 019f854e-4714-73ad-8de2-e79900f41b4d
## Summary
This changes the default for `prune-cache` from `true` to `false`,
motivated by [#745](https://github.com/astral-sh/setup-uv/issues/745).
Users that want the existing behavior can continue to set `prune-cache:
true` explicitly.
Some history: I originally added [`uv cache prune
--ci`](https://github.com/astral-sh/uv/pull/5391) after looking at a
workload where the uv cache was ~2.2 GB, almost entirely due to the
enormous pre-built `torch` and `nvidia_cudnn_cu12` wheels ([original
analysis](https://github.com/actions/setup-python/issues/822#issuecomment-2248728264)).
Persisting and restoring thousands of extracted files through the GitHub
Actions cache could be slower than downloading the wheels again. In
contrast, wheels built from source can be very expensive to recreate.
The intent was to remove pre-built wheels while retaining locally-built
wheels.
`setup-uv` subsequently made pruning configurable, but defaulted
`prune-cache` to `true`; it also later enabled caching by default on
GitHub-hosted runners. As a result, the default configuration repeatedly
downloads pre-built wheels from PyPI even on a cache hit. That tradeoff
has become more important as uv adoption has grown: [the PyPI analysis
in
#745](https://github.com/astral-sh/setup-uv/issues/745#issuecomment-3867334064)
estimates that uv accounts for roughly half of reported CI downloads
from PyPI, and roughly 65-75% for `boto3`.
I ran the comparison across a few different workloads:
| Workload | PR | Packages | Cache: keep / prune / prune-ci | Warm
restore+sync: keep / prune / prune-ci | Downloads: prune / prune-ci |
|---|---:|---:|---:|---:|---:|
| Tiny | [#1](https://github.com/astral-sh/setup-uv-benchmarks/pull/1) |
19 | 6 / 6 / 2 MB | 0.3-0.4 / 0.3 / 0.4-0.5 s | 0 / 2 |
| Web | [#2](https://github.com/astral-sh/setup-uv-benchmarks/pull/2) |
65 | 43 / 43 / 7 MB | 0.6-1.0 / 0.5-0.6 / 1.5-1.7 s | 0 / 6 |
| Scientific |
[#3](https://github.com/astral-sh/setup-uv-benchmarks/pull/3) | 118 |
586 / 586 / 8 MB | 8.2-16.0 / 7.0-8.2 / 8.9-12.1 s | 0 / 19 |
| PySpark |
[#4](https://github.com/astral-sh/setup-uv-benchmarks/pull/4) | 19 |
1820 / 1820 / 436 MB | 9.9-21.1 / 10.5-11.0 / 5.0-7.0 s | 0 / 4 |
| CPU PyTorch |
[#5](https://github.com/astral-sh/setup-uv-benchmarks/pull/5) | 14 | 182
/ 182 / 1 MB | 3.0-6.0 / 3.6-4.0 / 5.7-6.4 s | 0 / 6 |
| CPU-PyTorch ML |
[#6](https://github.com/astral-sh/setup-uv-benchmarks/pull/6) | 137 |
346 / 346 / 10 MB | 7.4-18.0 / 8.8-8.9 / 9.7-11.9 s | 0 / 20 |
| CUDA PyTorch |
[#7](https://github.com/astral-sh/setup-uv-benchmarks/pull/7) | 201 |
2316 / 2315 / 16 MB | 30.2-67.9 / 31.0-63.6 / 33.3-36.7 s | 0 / 40 |
The CUDA workload intentionally reproduces the original `torch==2.1.1`
example. Keeping wheels again produces a ~2.3 GB Actions cache. Across
nine warm runs, restoring that cache ranged from slightly faster than
re-downloading to roughly twice as slow; pruning consistently
re-downloaded 40 distributions in ~33-37 seconds ([original
runs](https://github.com/astral-sh/setup-uv-benchmarks/actions/runs/29750292738),
[additional
runs](https://github.com/astral-sh/setup-uv-benchmarks/actions/runs/29761705492)).
I also tried running `uv cache prune --force` without `--ci` across
every workload, to see if it provided a useful middle ground. It did not
meaningfully reduce any of the caches: plain prune took 11-21 ms and
left the extracted cache and file count unchanged, including PySpark. On
these fresh caches, there are no dangling entries to remove; without
`--ci`, the pre-built wheels and unpacked source/build artifacts are
retained. The per-workload runs are linked in the table above.
So the original motivation still holds for very large CUDA or
source-heavy workloads, but it is not representative of the common case.
For smaller workloads, keeping pre-built wheels is generally faster and
avoids repeated PyPI traffic. This changes the default accordingly,
while retaining `prune-cache: true` as an opt-in for workloads where the
smaller cache is worthwhile.
Closes https://github.com/astral-sh/setup-uv/issues/745.
## Summary
- update all CodeQL actions from 4.36.2 to 4.37.0
- update `smol-toml` from 1.6.1 to 1.7.0
- update `@types/node` from 25.5.0 to 26.0.1
- update `@vercel/ncc` from 0.44.0 to 0.44.1
- regenerate bundled action artifacts
Supersedes #950, #951, #952, #957, #958, and #959. The updates from #905
and #907 are already present on `main`.
Refs: pi-session 019f796d-a374-7a76-a8e4-1699b89ec8e6
## Summary
`getLinuxOSNameVersion()` throws `Failed to determine Linux
distribution. Could not read /etc/os-release or /usr/lib/os-release` on
distributions whose os-release is readable but contains **no version
field at all** — no `VERSION_ID`, no `VERSION_CODENAME`, no `BUILD_ID`.
The error message is misleading in that case, and the action fails even
though the distribution is perfectly identifiable.
Void Linux is such a distribution. Its os-release is:
```sh
$ cat /etc/os-release
NAME="Void"
ID="void"
PRETTY_NAME="Void Linux"
HOME_URL="https://voidlinux.org/"
DOCUMENTATION_URL="https://docs.voidlinux.org/"
LOGO="void-logo"
ANSI_COLOR="0;38;2;71;128;97"
DISTRIB_ID="void"
```
Unlike Arch (fixed by #912 via `BUILD_ID`) and debian:unstable (fixed
via `VERSION_CODENAME`, #773), Void ships only `ID`, so both existing
fallbacks miss it. This breaks any workflow using `container:
ghcr.io/void-linux/void-glibc-full` with caching enabled — e.g.
SageMath's CI started failing after bumping to v8:
https://github.com/sagemath/sage/actions/runs/29456228986/job/87489892141
(worked around downstream in https://github.com/sagemath/sage/pull/42547
by injecting a fake `BUILD_ID` into the container's os-release).
This PR adds a last-resort fallback: if `ID` is present but no version
field is, return the plain `ID` (`void`), following the same reasoning
as #912 — a stable cache key for a rolling release is better than
crashing. Distributions with a version field are unaffected, and files
without even an `ID` still raise the existing error.
## Summary
- roll up remaining open Dependabot updates for zizmor-action,
@actions/cache, @biomejs/biome, and @vercel/ncc
- update Biome schema and migrate recommended rules to the new preset
field
- regenerate dist bundles
## Validation
- npm run check
- npm run all
Refs: pi-session 019f4055-b39c-778f-9d9f-092115939c33
## Summary
- strip PEP 508 environment markers before extracting uv versions from
dependency entries
- cover dependency-group pins with and without whitespace before the
marker
- cover requirements-style pins with markers
Fixes#920
## Validation
- npm ci --ignore-scripts
- npm run all
Refs: pi-session 019f316a-4108-7975-892f-ee5bf8abc7c3
## Summary
- URL-encode the Python version component before adding it to the cache
key
- URL-encode the user-provided cache suffix for the same reason
- Add cache key tests for Python ranges, comma-containing suffixes, and
unchanged simple inputs
Fixes#914
Refs: pi-session 019f3164-85e7-7817-bffd-501d89b3a1fd
## Tests
- npm run all
## Summary
- Roll up open Dependabot npm and GitHub Actions updates
- Update Biome schema to 2.4.16
- Regenerate bundled dist artifacts
## Validation
- npm run all
Refs: pi-session 019f3160-c4af-7606-b4be-648e0abff131