Persists snapshots as artifacts on test failure in CI and adds a script
to apply them locally
```
❯ ./scripts/apply-ci-snapshots.sh
Found pull request #18424 for branch 'zb/ci-snapshots'...
Found latest CI run 23022983761
Downloading pending snapshot artifacts...
Downloaded 3 artifacts
Applying 2 snapshot changes...
accepted:
crates/uv/tests/it/pip_install.rs:13679 (transitive_dependency_config_settings_invalidation-2)
crates/uv/tests/it/python_install.rs:1694 (python_install_default-5)
```
We infer the target run via the `gh` CLI. You may also provide the run
ID directly.
We'll merge snapshot artifacts from multiple platforms, so if there are
platform-specific failures on both Linux and Windows we'll apply both.
## Summary
Handle the case where too many hardlinks were created and thus
installing packages fails.
There are cases where the file system can have a hardlinks limit and
when it's hit `uv` fails,
for example AWS EFS that has a limit of 177 hard links (
https://docs.aws.amazon.com/efs/latest/ug/troubleshooting-efs-fileop-errors.html#hardlinkerror
)
This PR address this by resetting the hardlinks when the limit is
reached (it does this by replacing the file in the cache, so new
hardlinks can be made)
There can be race conditions over the limit, but those are ok, as the
links are reset atomically so in case of race conditions the worst case
will be that the limit is reset twice, but nothing will break.
## Test Plan
Add a `install_hardlink_after_emlink` function, it successfully
reproduced the issue on my system.
The issue is that it's expensive to run as it has to generate a lot of
hardlinks
---------
Co-authored-by: Tomasz Kramkowski <tom@astral.sh>
Copy of https://github.com/astral-sh/uv/pull/17753 which GitHub
auto-closed.
This adds test infrastructure for cross-device links and file systems
with reflink support. In short, we create a few extra file systems on
the CI runners then provide their paths to the test suite using
environment variables to ensure we have coverage. If the variables are
not set, the tests are skipped.
---------
Co-authored-by: Claude <noreply@anthropic.com>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [astral-sh/uv](https://redirect.github.com/astral-sh/uv) | uses-with |
minor | `0.9.28` → `0.10.1` |
---
### Release Notes
<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>
###
[`v0.10.1`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0101)
[Compare
Source](https://redirect.github.com/astral-sh/uv/compare/0.10.0...0.10.1)
Released on 2026-02-10.
##### Enhancements
- Don't panic on metadata read errors
([#​17904](https://redirect.github.com/astral-sh/uv/pull/17904))
- Skip empty workspace members instead of failing
([#​17901](https://redirect.github.com/astral-sh/uv/pull/17901))
- Don't fail creating a read-only `sdist-vX/.git` if it already exists
([#​17825](https://redirect.github.com/astral-sh/uv/pull/17825))
##### Documentation
- Suggest `uv python update-shell` over `uv tool update-shell` in Python
docs
([#​17941](https://redirect.github.com/astral-sh/uv/pull/17941))
###
[`v0.10.0`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0100)
[Compare
Source](https://redirect.github.com/astral-sh/uv/compare/0.9.30...0.10.0)
Since we released uv
[0.9.0](https://redirect.github.com/astral-sh/uv/releases/tag/0.9.0) in
October of 2025, we've accumulated various changes that improve
correctness and user experience, but could break some workflows. This
release contains those changes; many have been marked as breaking out of
an abundance of caution. We expect most users to be able to upgrade
without making changes.
This release also includes the stabilization of preview features. Python
upgrades are now stable, including the `uv python upgrade` command, `uv
python install --upgrade`, and automatically upgrading Python patch
versions in virtual environments when a new version is installed. The
`add-bounds` and `extra-build-dependencies` settings are now stable.
Finally, the `uv workspace dir` and `uv workspace list` utilities for
writing scripts against workspace members are now stable.
##### Breaking changes
- **Require `--clear` to remove existing virtual environments in `uv
venv`**
([#​17757](https://redirect.github.com/astral-sh/uv/pull/17757))
Previously, `uv venv` would prompt for confirmation before removing an
existing virtual environment in interactive contexts, and remove it
without confirmation in non-interactive contexts. Now, `uv venv`
requires the `--clear` flag to remove an existing virtual environment. A
warning for this change was added in [uv
0.8](https://redirect.github.com/astral-sh/uv/blob/main/changelogs/0.8.x.md#breaking-changes).
You can opt out of this behavior by passing the `--clear` flag or
setting `UV_VENV_CLEAR=1`.
- **Error if multiple indexes include `default = true`**
([#​17011](https://redirect.github.com/astral-sh/uv/pull/17011))
Previously, uv would silently accept multiple indexes with `default =
true` and use the first one. Now, uv will error if multiple indexes are
marked as the default.
You cannot opt out of this behavior. Remove `default = true` from all
but one index.
- **Error when an `explicit` index is unnamed**
([#​17777](https://redirect.github.com/astral-sh/uv/pull/17777))
Explicit indexes can only be used via the `[tool.uv.sources]` table,
which requires referencing the index by name. Previously, uv would
silently accept unnamed explicit indexes, which could never be
referenced. Now, uv will error if an explicit index does not have a
name.
You cannot opt out of this behavior. Add a `name` to the explicit index
or remove the entry.
- **Install alternative Python executables using their implementation
name**
([#​17756](https://redirect.github.com/astral-sh/uv/pull/17756),
[#​17760](https://redirect.github.com/astral-sh/uv/pull/17760))
Previously, `uv python install` would install PyPy, GraalPy, and Pyodide
executables with names like `python3.10` into the bin directory. Now,
these executables will be named using their implementation name, e.g.,
`pypy3.10`, `graalpy3.10`, and `pyodide3.12`, to avoid conflicting with
CPython installations.
You cannot opt out of this behavior.
- **Respect global Python version pins in `uv tool run` and `uv tool
install`**
([#​14112](https://redirect.github.com/astral-sh/uv/pull/14112))
Previously, `uv tool run` and `uv tool install` did not respect the
global Python version pin (set via `uv python pin --global`). Now, these
commands will use the global Python version when no explicit version is
requested.
For `uv tool install`, if the tool is already installed, the Python
version will not change unless `--reinstall` or `--python` is provided.
If the tool was previously installed with an explicit `--python` flag,
the global pin will not override it.
You can opt out of this behavior by providing an explicit `--python`
flag.
- **Remove Debian Bookworm, Alpine 3.21, and Python 3.8 Docker images**
([#​17755](https://redirect.github.com/astral-sh/uv/pull/17755))
The Debian Bookworm and Alpine 3.21 images were replaced by Debian
Trixie and Alpine 3.22 as defaults in [uv
0.9](https://redirect.github.com/astral-sh/uv/pull/15352). These older
images are now removed. Python 3.8 images are also removed, as Python
3.8 is no longer supported in the Trixie or Alpine base images.
The following image tags are no longer published:
- `uv:bookworm`, `uv:bookworm-slim`
- `uv:alpine3.21`
- `uv:python3.8-*`
Use `uv:debian` or `uv:trixie` instead of `uv:bookworm`, `uv:alpine` or
`uv:alpine3.22` instead of `uv:alpine3.21`, and a newer Python version
instead of `uv:python3.8-*`.
- **Drop PPC64 (big endian) builds**
([#​17626](https://redirect.github.com/astral-sh/uv/pull/17626))
uv no longer provides pre-built binaries for PPC64 (big endian). This
platform appears to be largely unused and is only supported on a single
manylinux version. PPC64LE (little endian) builds are unaffected.
Building uv from source is still supported for this platform.
- **Skip generating `activate.csh` for relocatable virtual
environments**
([#​17759](https://redirect.github.com/astral-sh/uv/pull/17759))
Previously, `uv venv --relocatable` would generate an `activate.csh`
script that contained hardcoded paths, making it incompatible with
relocation. Now, the `activate.csh` script is not generated for
relocatable virtual environments.
You cannot opt out of this behavior.
- **Require username when multiple credentials match a URL**
([#​16983](https://redirect.github.com/astral-sh/uv/pull/16983))
When using `uv auth login` to store credentials, you can register
multiple username and password combinations for the same host.
Previously, when uv needed to authenticate and multiple credentials
matched the URL (e.g., when retrieving a token with `uv auth token`), uv
would pick the first match. Now, uv will error instead.
You cannot opt out of this behavior. Include the username in the
request, e.g., `uv auth token --username foo example.com`.
- **Avoid invalidating the lockfile versions after an `exclude-newer`
change**
([#​17721](https://redirect.github.com/astral-sh/uv/pull/17721))
Previously, changing the `exclude-newer` setting would cause package
versions to be upgraded, ignoring the lockfile entirely. Now, uv will
only change package versions if they are no longer within the
`exclude-newer` range.
You can restore the previous behavior by using `--upgrade` or
`--upgrade-package` to opt-in to package version changes.
- **Upgrade `uv format` to Ruff 0.15.0**
([#​17838](https://redirect.github.com/astral-sh/uv/pull/17838))
`uv format` now uses [Ruff
0.15.0](https://redirect.github.com/astral-sh/ruff/releases/tag/0.15.0),
which uses the [2026 style
guide](https://astral.sh/blog/ruff-v0.15.0#the-ruff-2026-style-guide).
See the blog post for details.
The formatting of code is likely to change. You can opt out of this
behavior by requesting an older Ruff version, e.g., `uv format --version
0.14.14`.
- **Update uv crate test features to use `test-` as a prefix**
([#​17860](https://redirect.github.com/astral-sh/uv/pull/17860))
This change only affects redistributors of uv. The Cargo features used
to gate test dependencies, e.g., `pypi`, have been renamed with a
`test-` prefix for clarity, e.g., `test-pypi`.
##### Stabilizations
- **`uv python upgrade` and `uv python install --upgrade`**
([#​17766](https://redirect.github.com/astral-sh/uv/pull/17766))
When installing Python versions, an [intermediary
directory](https://docs.astral.sh/uv/concepts/python-versions/#minor-version-directories)
without the patch version attached will be created, and virtual
environments will be transparently upgraded to new patch versions.
See the [Python version
documentation](https://docs.astral.sh/uv/concepts/python-versions/#upgrading-python-versions)
for more details.
- **`uv add --bounds` and the `add-bounds` configuration option**
([#​17660](https://redirect.github.com/astral-sh/uv/pull/17660))
This does not come with any behavior changes. You will no longer see an
experimental warning when using `uv add --bounds` or `add-bounds` in
configuration.
- **`uv workspace list` and `uv workspace dir`**
([#​17768](https://redirect.github.com/astral-sh/uv/pull/17768))
This does not come with any behavior changes. You will no longer see an
experimental warning when using these commands.
- **`extra-build-dependencies`**
([#​17767](https://redirect.github.com/astral-sh/uv/pull/17767))
This does not come with any behavior changes. You will no longer see an
experimental warning when using `extra-build-dependencies` in
configuration.
##### Enhancements
- Improve ABI tag error message phrasing
([#​17878](https://redirect.github.com/astral-sh/uv/pull/17878))
- Introduce a 10s connect timeout
([#​17733](https://redirect.github.com/astral-sh/uv/pull/17733))
- Allow using `pyx.dev` as a target in `uv auth` commands despite
`PYX_API_URL` differing
([#​17856](https://redirect.github.com/astral-sh/uv/pull/17856))
##### Bug fixes
- Support all CPython ABI tag suffixes properly
([#​17817](https://redirect.github.com/astral-sh/uv/pull/17817))
- Add support for detecting PowerShell on Linux and macOS
([#​17870](https://redirect.github.com/astral-sh/uv/pull/17870))
- Retry timeout errors for streams
([#​17875](https://redirect.github.com/astral-sh/uv/pull/17875))
###
[`v0.9.30`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0930)
[Compare
Source](https://redirect.github.com/astral-sh/uv/compare/0.9.29...0.9.30)
Released on 2026-02-04.
##### Python
- Add CPython 3.14.3 and 3.13.12
([#​17849](https://redirect.github.com/astral-sh/uv/pull/17849))
##### Enhancements
- Allow comma-separated values for `--extra` option
([#​17525](https://redirect.github.com/astral-sh/uv/pull/17525))
- Check all files during a dry-run publish instead of stopping at the
first failure
([#​17785](https://redirect.github.com/astral-sh/uv/pull/17785))
- Clarify `UV_HTTP_TIMEOUT` error message
([#​17493](https://redirect.github.com/astral-sh/uv/pull/17493))
##### Preview features
- Use relocatable virtual environments by default
([#​17770](https://redirect.github.com/astral-sh/uv/pull/17770))
##### Bug fixes
- Fix deadlock on token refresh in `uv publish` when using pyx
([#​17832](https://redirect.github.com/astral-sh/uv/pull/17832))
- Ignore global Python pins when incompatible with project
([#​15473](https://redirect.github.com/astral-sh/uv/pull/15473))
###
[`v0.9.29`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0929)
[Compare
Source](https://redirect.github.com/astral-sh/uv/compare/0.9.28...0.9.29)
Released on 2026-02-03.
##### Python
- Update to Pyodide 0.29.3
([#​17730](https://redirect.github.com/astral-sh/uv/pull/17730))
##### Enhancements
- Add wheel-tag-style aliases for manylinux platform names
([#​17750](https://redirect.github.com/astral-sh/uv/pull/17750))
- Hint on `uv version --bump dev` similar to pre-release bumps
([#​17796](https://redirect.github.com/astral-sh/uv/pull/17796))
- Improve display of RFC 9457 Problem Detail responses in `uv publish`
server errors
([#​17787](https://redirect.github.com/astral-sh/uv/pull/17787))
- Improve the wording of publish errors during dry-run
([#​17782](https://redirect.github.com/astral-sh/uv/pull/17782))
- Set backoff to 10 retries
([#​17816](https://redirect.github.com/astral-sh/uv/pull/17816))
- Add properties to synthentic and project roots in Cyclone DX exports
([#​17820](https://redirect.github.com/astral-sh/uv/pull/17820))
- Identify the invidividual clients in `uv publish` trace logs
([#​17784](https://redirect.github.com/astral-sh/uv/pull/17784))
##### Preview features
- Remove special casing for `base` and `default` conda environment names
([#​17758](https://redirect.github.com/astral-sh/uv/pull/17758))
##### Bug fixes
- Fix `PYTHONHOME` inheritance when spawning different Python versions
([#​17821](https://redirect.github.com/astral-sh/uv/pull/17821))
- Fix wheel rejections on freethreading+debug builds
([#​17812](https://redirect.github.com/astral-sh/uv/pull/17812))
- Pad with zeros during comparisons in `EqualStar` and `NotEqualStar`
operators
([#​17751](https://redirect.github.com/astral-sh/uv/pull/17751))
- Reject unknown field names in conflict declarations
([#​17727](https://redirect.github.com/astral-sh/uv/pull/17727))
- Fix panics in `system-configuration` in sandboxes
([#​17829](https://redirect.github.com/astral-sh/uv/pull/17829))
##### Documentation
- Update pip pre-release compatibility information
([#​17788](https://redirect.github.com/astral-sh/uv/pull/17788))
##### Security
- Hide a subset of environment variable values in `--help`
([#​17745](https://redirect.github.com/astral-sh/uv/pull/17745))
</details>
---
### Configuration
📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on
Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule
defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45NS4yIiwidXBkYXRlZEluVmVyIjoiNDIuOTcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1yZWxlYXNlIiwiaW50ZXJuYWwiXX0=-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://redirect.github.com/actions/checkout) |
action | patch | `v6.0.1` → `v6.0.2` |
---
### Release Notes
<details>
<summary>actions/checkout (actions/checkout)</summary>
###
[`v6.0.2`](https://redirect.github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v602)
[Compare
Source](https://redirect.github.com/actions/checkout/compare/v6.0.1...v6.0.2)
- Fix tag handling: preserve annotations and explicit fetch-tags by
[@​ericsciple](https://redirect.github.com/ericsciple) in
[#​2356](https://redirect.github.com/actions/checkout/pull/2356)
</details>
---
### Configuration
📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on
Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule
defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45Mi4xIiwidXBkYXRlZEluVmVyIjoiNDIuOTIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1yZWxlYXNlIiwiaW50ZXJuYWwiXX0=-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
Currently we require `macos:test` explicitly even when `test:extended`
is set, but from discussions it seems `test:extended` should also
trigger `test:macos` so this change adds that.
This change also introduces a new `test-macos` plan output variable which is used as the new condition.
## Test Plan
CI.
The goal here is to reduce cache consumption and contention by avoiding
cache saves on pull requests unless the pull request makes a change that
requires a new cache entry.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This is included in the Rust cache key hash because it is prefixed with
`RUST_` but has no affect on compilation. This invalidates caches that
could be shared across jobs.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Yet another attempt at #5714 to see if it improves CI times now that
Windows test times have increased
I think this is worth it now
```
main (1 shard): 13m 46s
branch (2 shards): 10m 31s
branch (3 shards): 7m 34s
```
total time (a.k.a., cost increase)
```
main (1 shard): 13m 46s
branch (2 shards): 20m 18s
branch (3 shards): 21m 32s
```
As in #875, we could explore moving the build step before the sharded
test runs. The build is 3m of the runtime, but I think artifact transfer
and runner startup time was too expensive last time and I don't expect
it to be faster. It might save a bit on CI cost, but I'm not super
worried about that.
I chose three shards due to a reasonable reduction in per-shard runtime
without a big increase in total runtime (compared to two shards). I
think since half of the shard runtime is fixed build time (vs reducable
test time), going up to more shards would be wasteful.
We use a hash-based strategy for test splitting, which means adding
tests will never move tests across shards.
I moved _off_ of the Depot runner because the "checkout" setup is taking
_way_ too long, about 120s more than the GitHub one which, once we split
over multiple shards, overcomes the speed benefits of the Depot runners.
The downsides here are:
1. Increased total CI time and therefore increased cost
2. GitHub runners are more expensive than Depot runners
3. Failing tests can be split across multiple shards, requiring more
GitHub UI navigation
(1) The runtime is unacceptably slow and I think the cost increase is
fairly marginal
(2) We can move back to Depot runners once they resolve the specific
performance issue
(3) Failing tests on Windows without failing tests on Linux are fairly
rare and should often be isolated to a single shard
---------
Co-authored-by: Claude <noreply@anthropic.com>
This file is too big for an LLM context window and several contributors
have complained about it being too scary to touch.
This also gets us collapsible sections in the UI.
I renamed some jobs for clarity in the meantime. And added a meta-job
for required checks passing so we can avoid churn in our "Settings" when
we change job names.
Note this was entirely refactored by Claude.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>