From 2c4545957e6e6c827442df9f0c1693f5e8682898 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 00:35:41 +0000 Subject: [PATCH 1/4] build(deps-dev): bump uv from 0.11.15 to 0.12.1 Bumps [uv](https://github.com/astral-sh/uv) from 0.11.15 to 0.12.1. - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.11.15...0.12.1) --- updated-dependencies: - dependency-name: uv dependency-version: 0.12.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- uv.lock | 46 +++++++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 38754e3..e314895 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ validation = [ "pytest==9.1.1", "ruff==0.15.20", "setuptools==83.0.0", - "uv==0.11.15", + "uv==0.12.1", ] [tool.setuptools] diff --git a/uv.lock b/uv.lock index d42ba19..dc64495 100644 --- a/uv.lock +++ b/uv.lock @@ -293,7 +293,7 @@ validation = [ { name = "pytest", specifier = "==9.1.1" }, { name = "ruff", specifier = "==0.15.20" }, { name = "setuptools", specifier = "==83.0.0" }, - { name = "uv", specifier = "==0.11.15" }, + { name = "uv", specifier = "==0.12.1" }, ] [[package]] @@ -690,26 +690,26 @@ wheels = [ [[package]] name = "uv" -version = "0.11.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/34/609d5d01ba21dc8f0974610ca7802fbb2c946a0c38665cfe5c5aeddbefb5/uv-0.11.15.tar.gz", hash = "sha256:755f959ec6a2fd8ccb6ee76ad90ab759d2eb1f4797444078645dd1ee4bca92d6", size = 4159545, upload-time = "2026-05-18T19:57:48.133Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/7c/dcc230c5911884d8848145dabcac8fb95a5ed6f9fe1c57fae8242618f28a/uv-0.11.15-py3-none-linux_armv6l.whl", hash = "sha256:83b04ab49514a0a761ffedb36a748ee81f87746671e72088e5f32c9585e5f1a9", size = 23110183, upload-time = "2026-05-18T19:57:23.051Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f3/efd4e044b60eb9c3c12ee386be098d56c335538ccec7caa49349cfba9344/uv-0.11.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cae61f737be075b90be9e3f07d961072aed7019f4c9b8ed5c5d41c4d6cade3", size = 22637941, upload-time = "2026-05-18T19:57:26.752Z" }, - { url = "https://files.pythonhosted.org/packages/a6/b8/48627f895a1569e576822e0a8416aa4797eb4a4551de21a4ad97b9b5819d/uv-0.11.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9accae33619a9166e5c48531deb455d672cfb89f9357a00975e669c76b0bd49f", size = 21258803, upload-time = "2026-05-18T19:57:05.473Z" }, - { url = "https://files.pythonhosted.org/packages/af/50/4bc8a148274feabee2d9c9f1fa15009e10c0228dfe57981ee3ea2ef1d481/uv-0.11.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c0cf52cd6d50bb9e05e2d968f45f80761107e4cbc8d4a26d9758f9d8274aaec1", size = 23066178, upload-time = "2026-05-18T19:57:33.058Z" }, - { url = "https://files.pythonhosted.org/packages/a9/56/139fc3bec9a8b0a25bfe2196123adb9f16124da437bf4fbcf0d21cfcafb2/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:49dc6ed70bff00937384f96cdc4b1a4742d18e5504ec2c4a1214dba2dee5687a", size = 22705332, upload-time = "2026-05-18T19:57:36.714Z" }, - { url = "https://files.pythonhosted.org/packages/ca/b0/b18b3dd204f8c213236a1ebd148e009861637129a8cce34df0e9aa22ed40/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:adb9a89352539fdd8f7cd5f9966cf9f94fc5b98e0ccdf5003a04123dc6423bec", size = 22707534, upload-time = "2026-05-18T19:58:04.117Z" }, - { url = "https://files.pythonhosted.org/packages/76/36/3ca09f95572df99d361b49c96b1297149e96e120d8d1ecf074095a4b6da4/uv-0.11.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40ff67e3f8e8a7533781a2e892a534975a93acb83ea35460e64e7b2bf2111774", size = 24096607, upload-time = "2026-05-18T19:58:11.625Z" }, - { url = "https://files.pythonhosted.org/packages/64/be/3bdee21a296bbf5336a526e3613d0e7d4538dacc39c62d7fcba55d15f6b0/uv-0.11.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6463a299ed7e6b5a800ed6f108af8e1588352629424133ddef7572b0e1e1118", size = 25082562, upload-time = "2026-05-18T19:57:40.69Z" }, - { url = "https://files.pythonhosted.org/packages/cd/73/f371f3689ffe741066468d001d85f739fc4b5574de83b639ef19b5e8a7f4/uv-0.11.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68c1e62d4b78578b90b833553286b65d6a7e327537716441068583ba652ec4f5", size = 24253391, upload-time = "2026-05-18T19:57:18.47Z" }, - { url = "https://files.pythonhosted.org/packages/d3/16/fe392d618af6b00c064b3e718d585dcf791546a77c5123a5bec07ce53a0a/uv-0.11.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98edf1bdaf82447014852051d93e3ee95012509c567bf057fd117e6bdbd9a807", size = 24415871, upload-time = "2026-05-18T19:58:19.651Z" }, - { url = "https://files.pythonhosted.org/packages/6e/24/2e92a052fb6334fcd746d1c7cb57847c204b118c84f5da53c0f9e129f7b7/uv-0.11.15-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:be8f76d25bcf4c92bb384240ac1bf9aa7f51063d0bdeca4c9cf0ec3ed8b145e0", size = 23159007, upload-time = "2026-05-18T19:57:10.653Z" }, - { url = "https://files.pythonhosted.org/packages/3d/2e/6923d0658d164bb2c435ed1868aa2d49b3074594679917a001ff92dc95bb/uv-0.11.15-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:f9f4fbbf4fe485522054f3c7496c6e8e932d6436e4200ff3daf718db0b7c7bd5", size = 23769385, upload-time = "2026-05-18T19:58:15.856Z" }, - { url = "https://files.pythonhosted.org/packages/a4/99/7e34cd949e57360814e8064cc9fb7104df445d0f6a663504e5f7473480aa/uv-0.11.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0ed920e896b2fd13a35031707e307e42fbb2681458b967440a17272d86d49137", size = 23860973, upload-time = "2026-05-18T19:57:55.575Z" }, - { url = "https://files.pythonhosted.org/packages/28/98/8fe1f5f9d816e94569a0298dd8e0936801097625fa1952162951f0d628b6/uv-0.11.15-py3-none-musllinux_1_1_i686.whl", hash = "sha256:41d907611f3e6a13262807fd7f0a17849f76285ca80f536f6b3943732bdc6656", size = 23431392, upload-time = "2026-05-18T19:57:59.814Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6b/76a1ce2fa860026913a5941700cdc7d715fce9c3277a3fa3489cf2523ca0/uv-0.11.15-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e3b68f8bf1a4568710f77e5bda9182ce7682811d89a8e7468c22460e032b234d", size = 24519478, upload-time = "2026-05-18T19:57:51.165Z" }, - { url = "https://files.pythonhosted.org/packages/43/60/1d58e8a05718cb50494763115710b73846cacb651fd735d285233fd72c59/uv-0.11.15-py3-none-win32.whl", hash = "sha256:8e2da3076761086a5b76869c3f38ef0509c836046ef41ddd19485dfd7271dca9", size = 22020178, upload-time = "2026-05-18T19:58:07.64Z" }, - { url = "https://files.pythonhosted.org/packages/55/53/40fcefcb348af660488597ed3c01363df7344e60611f8883750dc596f5c6/uv-0.11.15-py3-none-win_amd64.whl", hash = "sha256:cc3915ab291a1ecaf31de05f5d8bd70d09c66fe9911a53f70d9efa62ff0dbd8a", size = 24668779, upload-time = "2026-05-18T19:57:44.894Z" }, - { url = "https://files.pythonhosted.org/packages/e5/7d/fa3a9960c95af9bbe2a629048760d0b9b4fead8ccd4f2235af747ec7cdf0/uv-0.11.15-py3-none-win_arm64.whl", hash = "sha256:4f39426a13dee24897aed60c4b98058c66f18bd983885ac5f4a54a04b24fbddf", size = 23198178, upload-time = "2026-05-18T19:57:14.68Z" }, +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/37/20d51f1130dfa924c88905c421efe384fec37753f5ddf1e1dbaae5c47a3c/uv-0.12.1.tar.gz", hash = "sha256:76d87de420213ca92fa403e87023c4c7c6956c6726c6b96d91c42cfe620173a3", size = 5850527, upload-time = "2026-07-31T19:42:35.054Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/59/4d3c0f3a23add0588d1ff3d0d9e12d9b4e17cb98bf85b76cc62e8827d437/uv-0.12.1-py3-none-linux_armv6l.whl", hash = "sha256:71f86410264c69a3e8acd18171897dd8ab1a13350cf40f718e4def5db2b724be", size = 21878444, upload-time = "2026-07-31T19:41:34.827Z" }, + { url = "https://files.pythonhosted.org/packages/fd/07/a417475380e901f4325d13b09938baab227b0c143547124b944c5bc71783/uv-0.12.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:41b8fc2335f682312a1ca39a7b4abfd6af800992065c663582ca3e4d51cf9258", size = 20155103, upload-time = "2026-07-31T19:41:38.272Z" }, + { url = "https://files.pythonhosted.org/packages/c9/68/391ff0cc3d8020e64adc43bb4e50607f744c69e792fb7623dc7c1526704b/uv-0.12.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e9b0b86e180abc5968b979c6e25203b32e85969abb5083ee1e8b88a5aa98a76", size = 18419745, upload-time = "2026-07-31T19:41:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/29/c2/d3ece0a61c4ccbe3569591788182fa8ebc6262012f34b078d413603feda2/uv-0.12.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:9331dda0dc4990512c232f86e1d3a7b83c13f459777fcc2bd46030911b40eaaa", size = 21257008, upload-time = "2026-07-31T19:41:44.464Z" }, + { url = "https://files.pythonhosted.org/packages/1f/37/3b56bd819f7b92440f81d395bda4483e6978d52b04406fb108a6d7ba9fc6/uv-0.12.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:1e8fd95fe98768e29436ad57f9ef7b68dc294b7b9862ef63396af8b15ab85e6c", size = 21353801, upload-time = "2026-07-31T19:41:47.988Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f0/fcfaacfaef576356854c2af7bc4030f2e68792f3ca58f9154ca892908020/uv-0.12.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04290ea4001dca31ac8a8324113a4930dccad69ce35dbf6eaae307d54880890d", size = 21415143, upload-time = "2026-07-31T19:41:51.107Z" }, + { url = "https://files.pythonhosted.org/packages/12/d9/780718210efa1cb163c154ae65757666f391cc6bf49a8cb8f991b781a1aa/uv-0.12.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29399e1e73b67ed24abe82bc971aa4eb8419c4de804784290f39cf681f0b51ce", size = 22096098, upload-time = "2026-07-31T19:41:54.347Z" }, + { url = "https://files.pythonhosted.org/packages/6f/a2/4322ae9ba2d6c8a328b642172fb331ef482a1d268571d2b0b175cc46f840/uv-0.12.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bd04849dd5346517cc4e57b4b3aa0b01c67c423878260c04f5893a038fe25b6", size = 23318282, upload-time = "2026-07-31T19:41:58.174Z" }, + { url = "https://files.pythonhosted.org/packages/90/c4/24261ba2f19558380dec3d11f212aec572811078498c72629866b95dfe37/uv-0.12.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e35e0030480a8c3bf8ecd87ae4a6f6a224009e15e96a6fbb3634ac11ab75d582", size = 23017040, upload-time = "2026-07-31T19:42:01.664Z" }, + { url = "https://files.pythonhosted.org/packages/72/d6/207945fe69903b9794e2ef3e42608c91a59972567343a6719078d99c71f7/uv-0.12.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27211df9b277f440dea438a4e525ba40250fb721ad39b8927eefc2d91f9aea15", size = 22386347, upload-time = "2026-07-31T19:42:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/9a/c7/29e426865c2eb8df61253dae93b953523f48c9fca1e471c7e49ff068f19a/uv-0.12.1-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:b255ac23958e45f39f9c7a4cd65890df5ef46f539a3b14de03bd296bbba9cb60", size = 21409254, upload-time = "2026-07-31T19:42:08.158Z" }, + { url = "https://files.pythonhosted.org/packages/be/cb/9c49f12872b2bdbf92e7544466ec1d9d29a951366503c9eeb5031fe01bdd/uv-0.12.1-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:1de49d9b04438f1ad2f41a1441dbbe19e230b94fca56d632818cfaed69e03bfc", size = 22062247, upload-time = "2026-07-31T19:42:11.363Z" }, + { url = "https://files.pythonhosted.org/packages/49/c3/1180739ab92d6c5e89133470864d8b26430d82bf43fa904c8e052be4a24d/uv-0.12.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6f7e72543264d2420ebb2ddc84696a751af2d6c5910046b7666589118f47292b", size = 22196149, upload-time = "2026-07-31T19:42:15.059Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2d/29d3f89b3b22e1b01d1703636cc6f04cb309fa9a9298fb57483e0ebd05f2/uv-0.12.1-py3-none-musllinux_1_1_i686.whl", hash = "sha256:3bd5db002adc763aa8d277f5b44f8d6e3fd82d20f2e51225b0bbdae1badc7259", size = 21351269, upload-time = "2026-07-31T19:42:18.269Z" }, + { url = "https://files.pythonhosted.org/packages/30/f8/02285615f3f6b13a5f18c884a8581fa8f9f904a20de5b77a2ecf122a97be/uv-0.12.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:153ec0959a15397514438aefc1d7cd04235f335dd6bb53ea0f9e6e82c5a49f03", size = 22571781, upload-time = "2026-07-31T19:42:22.071Z" }, + { url = "https://files.pythonhosted.org/packages/fd/02/f73e4867c0748eaa3dea90cdfeb73d15bab0f04802c5c20bb37fc14918fe/uv-0.12.1-py3-none-win32.whl", hash = "sha256:173ee216f17d89fc39f65339d311a53584fc7de4918d27c0f3c7edafabc6b54d", size = 19440400, upload-time = "2026-07-31T19:42:25.788Z" }, + { url = "https://files.pythonhosted.org/packages/0d/a4/467c99c76fefa8b1259a1d382a5e49f73068f38a2d58db401504a783ed2c/uv-0.12.1-py3-none-win_amd64.whl", hash = "sha256:bd02f2da212e6a983115dc64a6fc94e9256c2d60e056d6b669de0a6025aaec05", size = 20277937, upload-time = "2026-07-31T19:42:29.375Z" }, + { url = "https://files.pythonhosted.org/packages/68/80/ec1acbf8e22dc4866f9070c30b064728cc0da73bedc30f2fbfdc0c5901a7/uv-0.12.1-py3-none-win_arm64.whl", hash = "sha256:ead7ad064f291a5df358c3ffa8ffab347a32bd5a75a6a068ca22254c2539a829", size = 19258877, upload-time = "2026-07-31T19:42:32.544Z" }, ] From a1d96303663bd3e9975740971ae6425050e86b3a Mon Sep 17 00:00:00 2001 From: cjharriskc-ai Date: Tue, 4 Aug 2026 23:05:53 -0500 Subject: [PATCH 2/4] Finish the uv bump across the pin sites Dependabot cannot reach Dependabot updated `pyproject.toml` and `uv.lock`. Three sites still carried 0.11.15: requirements-validation.lock tests/test_validation_dependency_lock.py EXPECTED_VALIDATION_TOOLS scripts/validate_release_python.py EXPECTED_TOOL_VERSIONS The last one asserts the INSTALLED tool version rather than the locked one, which is why it is the one that gets missed. Both lock files were regenerated with uv **0.12.1 itself**, not the local 0.11.15, because `validation_lock_reproducible` and `runtime_lock_reproducible` byte-compare the committed file against what the installed uv emits -- so regenerating with the old binary would produce a lock that passes here and fails in CI. Checked rather than assumed: the export format did not change across the bump. `requirements-runtime.lock` hashes identically before and after regeneration under 0.12.1, so the only real diff is the uv pin inside the validation lock. Co-Authored-By: Claude Opus 5 --- requirements-validation.lock | 40 ++++++++++++------------ scripts/validate_release_python.py | 2 +- tests/test_validation_dependency_lock.py | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/requirements-validation.lock b/requirements-validation.lock index 9d185fd..a2c6ec8 100644 --- a/requirements-validation.lock +++ b/requirements-validation.lock @@ -247,23 +247,23 @@ tomli-w==1.2.0 \ urllib3==2.7.0 \ --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \ --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 -uv==0.11.15 \ - --hash=sha256:0ed920e896b2fd13a35031707e307e42fbb2681458b967440a17272d86d49137 \ - --hash=sha256:40ff67e3f8e8a7533781a2e892a534975a93acb83ea35460e64e7b2bf2111774 \ - --hash=sha256:41d907611f3e6a13262807fd7f0a17849f76285ca80f536f6b3943732bdc6656 \ - --hash=sha256:49dc6ed70bff00937384f96cdc4b1a4742d18e5504ec2c4a1214dba2dee5687a \ - --hash=sha256:4f39426a13dee24897aed60c4b98058c66f18bd983885ac5f4a54a04b24fbddf \ - --hash=sha256:68c1e62d4b78578b90b833553286b65d6a7e327537716441068583ba652ec4f5 \ - --hash=sha256:755f959ec6a2fd8ccb6ee76ad90ab759d2eb1f4797444078645dd1ee4bca92d6 \ - --hash=sha256:83b04ab49514a0a761ffedb36a748ee81f87746671e72088e5f32c9585e5f1a9 \ - --hash=sha256:8e2da3076761086a5b76869c3f38ef0509c836046ef41ddd19485dfd7271dca9 \ - --hash=sha256:98edf1bdaf82447014852051d93e3ee95012509c567bf057fd117e6bdbd9a807 \ - --hash=sha256:9accae33619a9166e5c48531deb455d672cfb89f9357a00975e669c76b0bd49f \ - --hash=sha256:adb9a89352539fdd8f7cd5f9966cf9f94fc5b98e0ccdf5003a04123dc6423bec \ - --hash=sha256:b6cae61f737be075b90be9e3f07d961072aed7019f4c9b8ed5c5d41c4d6cade3 \ - --hash=sha256:be8f76d25bcf4c92bb384240ac1bf9aa7f51063d0bdeca4c9cf0ec3ed8b145e0 \ - --hash=sha256:c0cf52cd6d50bb9e05e2d968f45f80761107e4cbc8d4a26d9758f9d8274aaec1 \ - --hash=sha256:c6463a299ed7e6b5a800ed6f108af8e1588352629424133ddef7572b0e1e1118 \ - --hash=sha256:cc3915ab291a1ecaf31de05f5d8bd70d09c66fe9911a53f70d9efa62ff0dbd8a \ - --hash=sha256:e3b68f8bf1a4568710f77e5bda9182ce7682811d89a8e7468c22460e032b234d \ - --hash=sha256:f9f4fbbf4fe485522054f3c7496c6e8e932d6436e4200ff3daf718db0b7c7bd5 +uv==0.12.1 \ + --hash=sha256:04290ea4001dca31ac8a8324113a4930dccad69ce35dbf6eaae307d54880890d \ + --hash=sha256:153ec0959a15397514438aefc1d7cd04235f335dd6bb53ea0f9e6e82c5a49f03 \ + --hash=sha256:173ee216f17d89fc39f65339d311a53584fc7de4918d27c0f3c7edafabc6b54d \ + --hash=sha256:1de49d9b04438f1ad2f41a1441dbbe19e230b94fca56d632818cfaed69e03bfc \ + --hash=sha256:1e8fd95fe98768e29436ad57f9ef7b68dc294b7b9862ef63396af8b15ab85e6c \ + --hash=sha256:27211df9b277f440dea438a4e525ba40250fb721ad39b8927eefc2d91f9aea15 \ + --hash=sha256:29399e1e73b67ed24abe82bc971aa4eb8419c4de804784290f39cf681f0b51ce \ + --hash=sha256:2e9b0b86e180abc5968b979c6e25203b32e85969abb5083ee1e8b88a5aa98a76 \ + --hash=sha256:3bd5db002adc763aa8d277f5b44f8d6e3fd82d20f2e51225b0bbdae1badc7259 \ + --hash=sha256:41b8fc2335f682312a1ca39a7b4abfd6af800992065c663582ca3e4d51cf9258 \ + --hash=sha256:5bd04849dd5346517cc4e57b4b3aa0b01c67c423878260c04f5893a038fe25b6 \ + --hash=sha256:6f7e72543264d2420ebb2ddc84696a751af2d6c5910046b7666589118f47292b \ + --hash=sha256:71f86410264c69a3e8acd18171897dd8ab1a13350cf40f718e4def5db2b724be \ + --hash=sha256:76d87de420213ca92fa403e87023c4c7c6956c6726c6b96d91c42cfe620173a3 \ + --hash=sha256:9331dda0dc4990512c232f86e1d3a7b83c13f459777fcc2bd46030911b40eaaa \ + --hash=sha256:b255ac23958e45f39f9c7a4cd65890df5ef46f539a3b14de03bd296bbba9cb60 \ + --hash=sha256:bd02f2da212e6a983115dc64a6fc94e9256c2d60e056d6b669de0a6025aaec05 \ + --hash=sha256:e35e0030480a8c3bf8ecd87ae4a6f6a224009e15e96a6fbb3634ac11ab75d582 \ + --hash=sha256:ead7ad064f291a5df358c3ffa8ffab347a32bd5a75a6a068ca22254c2539a829 diff --git a/scripts/validate_release_python.py b/scripts/validate_release_python.py index 2db920b..7e23bf2 100644 --- a/scripts/validate_release_python.py +++ b/scripts/validate_release_python.py @@ -43,7 +43,7 @@ "pytest": "9.1.1", "ruff": "0.15.20", "setuptools": "83.0.0", - "uv": "0.11.15", + "uv": "0.12.1", } VALIDATION_BOUNDARIES = { "rustsec_advisory_scan": ( diff --git a/tests/test_validation_dependency_lock.py b/tests/test_validation_dependency_lock.py index 5226ecf..18788cf 100644 --- a/tests/test_validation_dependency_lock.py +++ b/tests/test_validation_dependency_lock.py @@ -12,7 +12,7 @@ "pytest": "9.1.1", "ruff": "0.15.20", "setuptools": "83.0.0", - "uv": "0.11.15", + "uv": "0.12.1", } From 2872e30bb52e67e64efa415a75138ef30a492ce8 Mon Sep 17 00:00:00 2001 From: cjharriskc-ai Date: Tue, 4 Aug 2026 23:48:01 -0500 Subject: [PATCH 3/4] Pin uv 0.12.1 in the workflow too, and stop the failure receipt burying the error TWO defects, and the second is why the first was hard to read. 1. A SEVENTH uv pin site. `.github/workflows/ui.yml` hard-codes the expected version twice, in a regex and in the message it throws: $uvVersion -notmatch '^uv 0\.11\.15(?:\s|$)' throw "Expected the exact lock-pinned uv 0.11.15 build." Neither Dependabot nor a grep of the Python pin sites reaches it, so `Native Windows desktop validation` failed while every other check passed. 2. The failure receipt masked it. `Upload sanitized native smoke failure receipt` runs `if: failure()` and takes its path from `DUMBMONEY_NATIVE_SMOKE_FAILURE_GLOB`, which is not set until line 131 -- after the bootstrap step that failed at line 76. So the receipt step died with: ##[error]Input required and not supplied: path That error lands LAST, which is what `gh run view --log-failed` shows first. The visible failure was a missing input on the diagnostic step, not the version mismatch that actually stopped the job. Guarded on the variable, so an early failure now reports itself instead of being overwritten by the machinery meant to explain it. Co-Authored-By: Claude Opus 5 --- .github/workflows/ui.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml index cea9e12..ec03616 100644 --- a/.github/workflows/ui.yml +++ b/.github/workflows/ui.yml @@ -73,9 +73,9 @@ jobs: $uvVersion = (& uv --version).Trim() if ( $LASTEXITCODE -ne 0 -or - $uvVersion -notmatch '^uv 0\.11\.15(?:\s|$)' + $uvVersion -notmatch '^uv 0\.12\.1(?:\s|$)' ) { - throw "Expected the exact lock-pinned uv 0.11.15 build." + throw "Expected the exact lock-pinned uv 0.12.1 build." } - name: Configure pinned Rust MSVC toolchain shell: pwsh @@ -139,7 +139,11 @@ jobs: ) } - name: Upload sanitized native smoke failure receipt - if: failure() + # The glob is only set once the smoke step runs. A failure BEFORE that + # leaves it empty, and this step then dies with "Input required and not + # supplied: path" -- which lands last in the log and buries the real + # error. Guard on the variable so an early failure reports itself. + if: failure() && env.DUMBMONEY_NATIVE_SMOKE_FAILURE_GLOB != '' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: dumbmoney-native-smoke-failure-${{ github.run_id }}-${{ github.run_attempt }} @@ -186,9 +190,9 @@ jobs: $uvVersion = (& uv --version).Trim() if ( $LASTEXITCODE -ne 0 -or - $uvVersion -notmatch '^uv 0\.11\.15(?:\s|$)' + $uvVersion -notmatch '^uv 0\.12\.1(?:\s|$)' ) { - throw "Expected the exact lock-pinned uv 0.11.15 build." + throw "Expected the exact lock-pinned uv 0.12.1 build." } - name: Configure pinned Rust MSVC toolchain shell: pwsh From 74a3014dc839eca44f8eeea0dfffe529d22b0005 Mon Sep 17 00:00:00 2001 From: cjharriskc-ai Date: Wed, 5 Aug 2026 00:33:53 -0500 Subject: [PATCH 4/4] Derive the expected uv version from the lock instead of restating it An EIGHTH pin site, and it only surfaced after the other seven were done: tests/test_release_build_trust.py assertIn("$uvVersion -notmatch '^uv 0\.11\.15(?:\s|$)'", job) The test's purpose is 'the native workflow bootstraps THE lock-pinned uv'. It was checking against a literal typed here, which is a different and weaker claim -- it passes whenever this file and the workflow agree, even if both have drifted from the lock they are supposed to enforce. Now it reads the version out of `requirements-validation.lock`, so: - bumping uv no longer requires editing this file at all - the assertion catches the drift it exists to catch: workflow disagreeing with the lock, in either direction - the throw message is asserted too, not just the regex, since that string also carries the version and was equally able to rot Mutation-checked, because the test was written after the code and so proved nothing on its own. Changing the workflow's message to `uv 0.12.2` while the lock says `0.12.1` fails exactly this test at the new assertion; restoring it returns 14 passed. Co-Authored-By: Claude Opus 5 --- tests/test_release_build_trust.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/test_release_build_trust.py b/tests/test_release_build_trust.py index 8df237d..a2770d8 100644 --- a/tests/test_release_build_trust.py +++ b/tests/test_release_build_trust.py @@ -12,6 +12,27 @@ BUILD_SCRIPT = WORKSPACE / "scripts" / "Build-DumbMoneyDesktop.ps1" UI_WORKFLOW = WORKSPACE / ".github" / "workflows" / "ui.yml" DEPENDABOT = WORKSPACE / ".github" / "dependabot.yml" +VALIDATION_LOCK = WORKSPACE / "requirements-validation.lock" + + +def locked_uv_version() -> str: + """Read the pinned uv version from the lock rather than restating it here. + + Hard-coding it made this assertion one more site to remember: bumping uv + meant editing pyproject, uv.lock, requirements-validation.lock, + EXPECTED_VALIDATION_TOOLS, EXPECTED_TOOL_VERSIONS, the workflow regex, the + workflow throw message, and this test -- eight places, and this one failed + only after the other seven were already done. + + Deriving it also makes the test STRONGER. It now fails when the workflow + and the lock disagree, which is the drift it exists to catch, rather than + when both correctly move off a literal written here. + """ + + for line in VALIDATION_LOCK.read_text(encoding="utf-8").splitlines(): + if line.startswith("uv=="): + return line.split("==", 1)[1].split()[0].rstrip("\\").strip() + raise AssertionError("requirements-validation.lock does not pin uv") class NativeReleaseBuildTrustTests(unittest.TestCase): @@ -265,8 +286,14 @@ def test_native_workflow_bootstraps_exact_lock_pinned_uv_before_builds( "--requirement requirements-validation.lock", job, ) + expected = locked_uv_version() + escaped = expected.replace(".", "\\.") + self.assertIn( + f"$uvVersion -notmatch '^uv {escaped}(?:\\s|$)'", + job, + ) self.assertIn( - "$uvVersion -notmatch '^uv 0\\.11\\.15(?:\\s|$)'", + f"Expected the exact lock-pinned uv {expected} build.", job, ) self.assertLess(