diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b8277..612aa27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated pip from 25.3 to 26.0.1. ([#508](https://github.com/heroku/buildpacks-python/pull/508)) +- Explicitly configured uv to use hard links to maintain the behaviour of previous versions. ([#519](https://github.com/heroku/buildpacks-python/pull/519)) ## [5.1.0] - 2026-02-26 diff --git a/src/layers/uv.rs b/src/layers/uv.rs index 1501721..2212bf3 100644 --- a/src/layers/uv.rs +++ b/src/layers/uv.rs @@ -39,9 +39,9 @@ pub(crate) fn install_uv( }, )?; - // Prevent uv from downloading/using its own Python installation: - // https://docs.astral.sh/uv/concepts/python-versions/#disabling-automatic-python-downloads let mut layer_env = LayerEnv::new() + // Prevent uv from downloading/using its own Python installation: + // https://docs.astral.sh/uv/concepts/python-versions/#disabling-automatic-python-downloads .chainable_insert( Scope::Build, ModificationBehavior::Override, @@ -53,6 +53,14 @@ pub(crate) fn install_uv( ModificationBehavior::Override, "UV_PYTHON_DOWNLOADS", "never", + ) + // Force uv to use hardlinks rather than the new default of reflinks, since the latter are + // significantly slower in some environments: https://github.com/astral-sh/uv/issues/18259 + .chainable_insert( + Scope::Build, + ModificationBehavior::Override, + "UV_LINK_MODE", + "hardlink", ); match layer.state { diff --git a/tests/uv_test.rs b/tests/uv_test.rs index b874d63..34dbc50 100644 --- a/tests/uv_test.rs +++ b/tests/uv_test.rs @@ -50,6 +50,7 @@ fn uv_basic_install_and_cache_reuse() { PYTHONUNBUFFERED=1 SOURCE_DATE_EPOCH=315532801 UV_CACHE_DIR=/layers/heroku_python/uv-cache + UV_LINK_MODE=hardlink UV_NO_MANAGED_PYTHON=1 UV_PROJECT_ENVIRONMENT=/layers/heroku_python/venv UV_PYTHON_DOWNLOADS=never