## 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.
Adds `uv.lock` as a supported `version-file` source. When `uv` is locked
as a
dependency in `uv.lock`, the action now installs the exact pinned
version,
closing the gap reported in #682.
This is useful for deterministic CI: the same uv version is used until
the
lockfile is updated, which avoids "CI worked yesterday, fails today"
drift and
reduces supply-chain exposure from auto-installing the latest release.
The implementation mirrors the existing `version-file` parsers — a new
`uv.lock`
entry in the parser registry reads the `[[package]]` whose `name = "uv"`
and
returns its locked `version`. Scoped to explicit `version-file:
uv.lock`;
workspace auto-detection is left as a possible follow-up to avoid
precedence
ambiguity with `uv.toml` / `pyproject.toml`.
Validation (local, Node 23; dist build is esbuild-deterministic):
- `npm run all` → build clean, biome clean, package clean, jest 77/77
- New tests: 3 unit (`uv-lock-file.test.ts`) + 1 integration — exact pin
resolves
through the full pipeline (`uv.lock` → `0.8.17`)
- dist rebuilt + committed (single bundle, no spurious churn)
related: #682
## Summary
Adds a new `quiet` input (default: `false`) that suppresses `info`-level
log output when set to `true`. Only warnings and errors are shown.
Contributes to: #868
## Summary
Add a new boolean input `download-from-astral-mirror` (default: `true`)
that controls whether uv is downloaded from the Astral mirror or
directly from GitHub Releases.
When set to `false`, the mirror rewrite is skipped entirely and the
download goes straight to GitHub Releases.
Closes: #870
This commit splits up the "normal" cache containing the dependencies and
the "python" cache containing the python binaries. This will lead to a
one-time invalidation of caches.
Closes: #713
## Summary
- Adds OS name and version (e.g., `ubuntu-22.04`, `macos-14`,
`windows-2022`) to cache keys to prevent binary incompatibility when
GitHub updates runner images
- Fixes issue where cached uv binaries compiled against older
glibc/library versions fail on newer runner OS versions
## Changes
- Added `getOSNameVersion()` function to `src/utils/platforms.ts` with
OS-specific detection for Linux (via `/etc/os-release`), macOS (Darwin
kernel version mapping), and Windows
- Updated cache key format to include OS version, bumped `CACHE_VERSION`
to `"2"`
- Added `cache-key` output to expose the generated cache key for
debugging
- Added `test-cache-key-os-version` job testing across multiple OS
versions
- Updated `docs/caching.md` with cache key documentation
Closes#703
Adds a new `resolution-strategy` input that allows users to choose
between installing the highest (default) or lowest compatible version
when resolving version ranges.
This pull request introduces support for caching Python installs in the
GitHub Action, allowing users to cache not only dependencies but also
the Python interpreter itself.
This works by setting the `UV_PYTHON_INSTALL_DIR` to a subdirectory of
the dependency cache path so that Python installs are directed there.
Fixes#135
---------
Co-authored-by: Kevin Stillhammer <kevin.stillhammer@gmail.com>
To support more users by default we should support popular dependency
file formats. A quick GitHub search shows ~40k uses of `constraint.txt`
and ~16k uses of `requirements.in`.
Closes: #261
venv activation was implicit when python-version was supplied. This now
only happens when activate-environment is true. working-directory
controls where we work and thus also where the .venv will be created
Closes: #351Closes: #271Closes: #251Closes: #211
1. If defined use version input
2. If defined use uv-file input
3. If defined use pyproject-file input
4. Search for required-version in uv.toml in repo root
5. Search for required-version in pyproject.toml in repo root
6. Use latest
Closes: #215
We should aim for a solution with sane defaults that work as most users
would expect it.
The current default leads to a cache that is never invalidated and thus
never updated.
This also mirrors the default behaviors for setup-python which use
`**/requirements.txt`, `**/Pipfile.lock` or `**/poetry.lock`
Also make it clear that the uv cache on the filesystem can be uploaded to the GitHub Actions cache, but they are distinct things.
Also make it clear that the local cache path can be changed without using `enable-cache: true`
This PR adjusts the action so that it is no longer necessary to
explicitly specify the GitHub token to circumvent the API rate limit.
To this end, it simply passes the repository's GitHub token (available
via `${{ github.token }}`) as a default for the `github_token` action
input.
This is similar to how this is handled in, e.g.,
https://github.com/peter-evans/create-pull-request; specifically
[here](5354f85616/action.yml (L4-L6)).