From a6aef60ab22954a8d55d28c389c9c0cb20299145 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 11 Sep 2026 19:48:54 -0400 Subject: [PATCH] Pin the uv release toolchain and commit the lock in its marker normalization The first automatic version bump after #9428 failed closed in the release lock guard: "Versioning changed the reviewed dependency graph". The runner installs the latest uv (0.12.13, unpinned) while the committed lock was written by 0.11.7. A fresh lock is left alone by either version, but the bump forces a re-resolution, and 0.12.13 then rewrites 37 resolution-marker lines in its own normalization; the guard compares the whole graph and refuses. Reproduced locally with uv 0.12.13 at version 2.0.0; under 0.11.7 the same refresh changes only the root version. Commit the lock as 0.12.13 writes it after a re-resolution (bump, lock, restore, lock: 37 marker lines change, no package or version changes), and pin uv 0.12.13 in every setup-uv step of the push, pull request and weekly lock workflows so the toolchain that checks the lock is the one that wrote it. With this lock the 2.0.0 refresh differs from the committed graph in the root version alone, by the guard's own comparison. uv 0.11.7 still passes `uv lock --check` on it, so developers need no upgrade. The release-lock document records how to move the pin. Co-Authored-By: Claude Fable 5.1 --- .github/release-lock.md | 8 ++ .github/workflows/pr.yaml | 22 ++++++ .github/workflows/push.yaml | 20 +++++ .github/workflows/weekly-uv-lock.yaml | 2 + .../release-lock-uv-toolchain.fixed.md | 1 + uv.lock | 74 +++++++++---------- 6 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 changelog.d/release-lock-uv-toolchain.fixed.md diff --git a/.github/release-lock.md b/.github/release-lock.md index 7797d104b58..6a862f89c0e 100644 --- a/.github/release-lock.md +++ b/.github/release-lock.md @@ -20,6 +20,14 @@ contents, validates their semantics, and runs an actual `uv lock --check`. The default check supports inspecting an uncommitted candidate, but release CI uses `--committed`. Neither check repairs a stale lock. +The lock is generated by the uv version pinned in every `astral-sh/setup-uv` step of +the workflows (currently 0.12.13). Different uv releases normalize resolution markers +differently when they re-resolve, so an unpinned runner rewrites the reviewed graph the +first time the root version changes and `--refresh` fails closed (2026-09-11, the 2.0.0 +release). To upgrade uv: change the pin in all three workflows and regenerate the lock +with the new version in the same reviewed PR, forcing a re-resolution by bumping the +root version, locking, restoring the version, and locking again. + `--refresh` is only for the automatic root version bump. It runs uv to refresh and check the lock, preserving the complete reviewed dependency graph and all lock metadata except the root package version. Any dependency, artifact, diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 6e149140457..08446d9bcba 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,6 +18,8 @@ jobs: python-version: "3.14" - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Check committed registry lock run: python .github/release_lock.py --committed ReleaseLockTests: @@ -31,6 +33,8 @@ jobs: python-version: "3.14" - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Test guard without importing the country model env: RELEASE_LOCK_REAL_UV: "1" @@ -42,6 +46,8 @@ jobs: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Check formatting @@ -123,6 +129,8 @@ jobs: python-version: "3.14" - name: Install uv uses: astral-sh/setup-uv@v5 + with: + version: "0.12.13" - name: Install package run: uv sync --locked --extra dev - name: Install bundle validation tooling @@ -147,6 +155,8 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install package run: uv sync --locked --python "${{ matrix.python-version }}" --extra dev - name: Smoke-import @@ -181,6 +191,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -280,6 +292,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -304,6 +318,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -350,6 +366,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -377,6 +395,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -404,6 +424,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index ab6ab6af2b9..3353b150b53 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -18,6 +18,8 @@ jobs: python-version: "3.14" - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Check committed registry lock run: python .github/release_lock.py --committed ReleaseLockTests: @@ -31,6 +33,8 @@ jobs: python-version: "3.14" - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Test guard without importing the country model env: RELEASE_LOCK_REAL_UV: "1" @@ -45,6 +49,8 @@ jobs: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Check formatting @@ -69,6 +75,8 @@ jobs: token: ${{ steps.app-token.outputs.token }} - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Set up Python uses: actions/setup-python@v6 with: @@ -163,6 +171,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -190,6 +200,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -239,6 +251,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -269,6 +283,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -299,6 +315,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Install dependencies run: uv sync --locked --extra dev - name: Turn off default branching @@ -324,6 +342,8 @@ jobs: python-version: 3.14 - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Check committed registry lock before publication run: python .github/release_lock.py --committed - name: Install package diff --git a/.github/workflows/weekly-uv-lock.yaml b/.github/workflows/weekly-uv-lock.yaml index 5052a03466b..1e5acbf16bf 100644 --- a/.github/workflows/weekly-uv-lock.yaml +++ b/.github/workflows/weekly-uv-lock.yaml @@ -28,6 +28,8 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.12.13" - name: Set up Python uses: actions/setup-python@v6 diff --git a/changelog.d/release-lock-uv-toolchain.fixed.md b/changelog.d/release-lock-uv-toolchain.fixed.md new file mode 100644 index 00000000000..b5ff79bfab4 --- /dev/null +++ b/changelog.d/release-lock-uv-toolchain.fixed.md @@ -0,0 +1 @@ +Pin the uv release toolchain (0.12.13) in the workflows and commit the registry lock in that version's marker normalization, so the automatic version bump's lock refresh changes only the root version instead of failing closed. diff --git a/uv.lock b/uv.lock index 1f19f25b1a0..2e829e27f74 100644 --- a/uv.lock +++ b/uv.lock @@ -6,10 +6,10 @@ resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'win32'", "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] @@ -1663,7 +1663,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -2315,23 +2315,23 @@ resolution-markers = [ "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.12'" }, - { name = "babel", marker = "python_full_version < '3.12'" }, - { name = "colorama", marker = "python_full_version < '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version < '3.12'" }, - { name = "imagesize", marker = "python_full_version < '3.12'" }, - { name = "jinja2", marker = "python_full_version < '3.12'" }, - { name = "packaging", marker = "python_full_version < '3.12'" }, - { name = "pygments", marker = "python_full_version < '3.12'" }, - { name = "requests", marker = "python_full_version < '3.12'" }, - { name = "roman-numerals", marker = "python_full_version < '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.12'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ @@ -2351,23 +2351,23 @@ resolution-markers = [ "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [