From 7dc9c6d6e4fa6768f7a65d8dfa84357585d8ffc0 Mon Sep 17 00:00:00 2001 From: Robin Bowes Date: Wed, 21 Oct 2026 10:48:32 +0100 Subject: [PATCH] build: move uv to the 0.13 series mise.toml installs uv 0.13 and the build backend moves to uv_build>=0.13.2,<0.14.0, superseding Dependabot's #75, which moved uv_build alone. tool.uv.required-version becomes >=0.12.18,<0.14 rather than >=0.13.2: uv enforces that range and Dependabot runs uv 0.12.18 until dependabot-core#16639 ships, so a 0.13 floor would fail every Python Dependabot PR. CI and the sync-lockfile job install the newest uv in range. decisions/2026-10-21-uv-0.13-bridge-range.md records this and when to raise the floor. Verified: uv lock --check passes under 0.13.3 and 0.12.18 and is refused under 0.12.17; uv build succeeds with uv_build 0.13; task dev:check and the prek hooks pass. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Robin Bowes --- decisions/2026-10-21-uv-0.13-bridge-range.md | 46 +++++++++++++++++++ .../content/docs/how-to/use-hatchling.mdx | 2 +- mise.toml | 2 +- pyproject.toml | 24 +++++----- 4 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 decisions/2026-10-21-uv-0.13-bridge-range.md diff --git a/decisions/2026-10-21-uv-0.13-bridge-range.md b/decisions/2026-10-21-uv-0.13-bridge-range.md new file mode 100644 index 0000000..e46a35d --- /dev/null +++ b/decisions/2026-10-21-uv-0.13-bridge-range.md @@ -0,0 +1,46 @@ +# uv 0.13 bridge range + +## Decision: move to uv 0.13, with `required-version` still admitting Dependabot's 0.12.18 + +- `mise.toml`: `uv = "0.13"`. +- `[build-system] requires`: `uv_build>=0.13.2,<0.14.0`. +- `tool.uv.required-version`: `>=0.12.18,<0.14`. + +Raise the `required-version` floor to `>=0.13` once dependabot-core ships uv +0.13 (dependabot/dependabot-core#16639, 0.12.18 → 0.13.4, open on 2026-10-21). + +## Context: why it came up + +Dependabot opened #75, moving `uv_build` to `>=0.13.0,<0.14.0` while uv itself +stayed on the 0.12 series. The two move together, so on 2026-10-21 Robin chose +to move the template to the uv 0.13 series with a 0.13.2 floor. + +uv refuses to run outside `tool.uv.required-version`. Dependabot runs its own +uv, `uv==0.12.18` in `dependabot-core/uv/helpers/requirements.txt`. A +`required-version` floor of 0.13.2 would fail every Python Dependabot PR, the +reason `2026-10-14-uv-lock-revision-flapping.md` rejected even `>=0.12.22`. + +## Alternatives considered + +- **`required-version = ">=0.13.2,<0.14"` now.** Rejected: every Python + Dependabot PR fails until dependabot-core#16639 ships and is deployed. +- **Wait for Dependabot, then move.** Rejected: it leaves #75 open, and the + template that other repositories copy stays on 0.12 for an unknown time. + +## Reasoning + +`setup-uv` installs the newest uv in `required-version`, so CI and the +sync-lockfile job run 0.13.x. mise provides 0.13.x locally. Only Dependabot +runs 0.12.18, and the range admits it. `uv_build` is fetched into an isolated +build environment, so a 0.13 backend does not need a 0.13 front end. + +## Trade-offs accepted + +- Until the floor is raised, `required-version` admits a 0.12 uv that nobody + but Dependabot should be running. +- Lockfiles written by Dependabot's 0.12.18 and by CI's 0.13.x may carry + different `revision` values; see `2026-10-14-uv-lock-revision-flapping.md`. + +## Supersedes + +Nothing. Extends `2026-10-14-uv-lock-revision-flapping.md`. diff --git a/docs/site/content/docs/how-to/use-hatchling.mdx b/docs/site/content/docs/how-to/use-hatchling.mdx index 2c9868c..839d6bc 100644 --- a/docs/site/content/docs/how-to/use-hatchling.mdx +++ b/docs/site/content/docs/how-to/use-hatchling.mdx @@ -29,7 +29,7 @@ In `pyproject.toml`, replace: ```toml [build-system] -requires = ["uv_build>=0.12.5,<0.13.0"] +requires = ["uv_build>=0.13.2,<0.14.0"] build-backend = "uv_build" [tool.uv.build-backend] diff --git a/mise.toml b/mise.toml index 3fee1ce..f1fd539 100644 --- a/mise.toml +++ b/mise.toml @@ -1,5 +1,5 @@ [tools] -uv = "0.12" +uv = "0.13" # Exact, matching CI's TASK_VERSION, NODE_VERSION and PNPM_VERSION; Renovate moves each pair # together. uv is a range on purpose: see required-version in pyproject.toml. task = "3.54.0" diff --git a/pyproject.toml b/pyproject.toml index 4b7d2cf..dd4b8bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,24 +24,24 @@ dev = [ ] [build-system] -requires = ["uv_build>=0.12.23,<0.13.0"] +requires = ["uv_build>=0.13.2,<0.14.0"] build-backend = "uv_build" [tool.uv] -# Pins uv to the 0.12 series. `setup-uv` reads `tool.uv.required-version` +# Pins uv to the 0.13 series. `setup-uv` reads `tool.uv.required-version` # (src/version/file-parser.ts), so CI and the sync-lockfile job install the -# same series `mise.toml` provides locally. That job commits a lockfile; it -# should not be generated by a uv nobody else runs. +# newest uv in range, the series `mise.toml` provides locally. The floor is +# 0.12.18 only because Dependabot runs that uv and uv enforces this range: +# decisions/2026-10-21-uv-0.13-bridge-range.md. Raise it to 0.13 when +# dependabot-core ships uv 0.13. # -# The floor is the minor, not a patch. mise hides releases younger than its -# `minimum_release_age`, so pinning to the newest patch resolves to a version -# mise will not install for days -- CI green, every local uv command refusing -# to run. +# Never pin the newest patch. mise hides releases younger than its +# `minimum_release_age`, so it resolves to a version mise will not install +# for days -- CI green, every local uv command refusing to run. # -# Belt and braces, not the real guard: uv.lock's `revision` has been 3 across -# 0.10, 0.11 and 0.12, so a format change is not imminent. `uv sync --locked` -# failing in CI is what actually catches a lockfile that has drifted. -required-version = ">=0.12,<0.13" +# `uv sync --locked` failing in CI is what catches a lockfile that has +# drifted; see decisions/2026-10-14-uv-lock-revision-flapping.md. +required-version = ">=0.12.18,<0.14" [tool.uv.build-backend] # Required. uv_build derives the package directory from the distribution