diff --git a/.github/requirements/.pip-tools.toml b/.github/requirements/.pip-tools.toml new file mode 100644 index 0000000..d64dd4b --- /dev/null +++ b/.github/requirements/.pip-tools.toml @@ -0,0 +1,7 @@ +# Dependabot reads the legacy section; pip-tools reads the tool section. +# setuptools is the required build backend, installed at a reviewed hash. +[pip-tools] +allow-unsafe = true + +[tool.pip-tools] +allow-unsafe = true diff --git a/.github/requirements/integration.in b/.github/requirements/integration.in index 4a66d5c..37d3bc3 100644 --- a/.github/requirements/integration.in +++ b/.github/requirements/integration.in @@ -1,18 +1,19 @@ # Python 3.12 integration dependencies, locked for all runner platforms. # Regenerate: uv pip compile --universal --python-version 3.12 --generate-hashes -# --only-binary :all: --exclude-newer 2026-10-02T00:00:00Z +# --only-binary :all: --exclude-newer 2026-10-05T00:00:00Z # .github/requirements/integration.in -o .github/requirements/integration.txt setuptools>=77 wheel requests>=2.31.0 tqdm>=4.66.0 watchdog>=4.0.0 -cryptography>=50.0.0 +cryptography>=50.0.2 prometheus_client>=0.26.0 defusedxml>=0.7.1 je_action_core>=0.0.2 PyYAML>=6.0.3 -tzdata>=2024.1; platform_system == 'Windows' +# Keep Windows timezone data even when Dependabot recompiles this shared lock on Linux. +tzdata>=2026.5 opentelemetry-api>=1.44.0 opentelemetry-sdk>=1.44.0 tomli>=2.0.1; python_version<"3.11" diff --git a/.github/requirements/integration.txt b/.github/requirements/integration.txt index 709249b..b510126 100644 --- a/.github/requirements/integration.txt +++ b/.github/requirements/integration.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile .github/requirements/integration.in --python-version 3.12 --universal --generate-hashes --only-binary=:all: --exclude-newer 2026-10-02 -o .github/requirements/integration.txt +# uv pip compile .github/requirements/integration.in --python-version 3.12 --universal --generate-hashes --only-binary :all: --exclude-newer 2026-10-05T00:00:00Z -o .github/requirements/integration.txt azure-core==1.41.0 \ --hash=sha256:522b4011e8180b1a3dcd2024396a4e7fe9ac37fb8597db47163d230b5efe892d \ --hash=sha256:f46ff5dfcd230f25cf1c19e8a34b8dc08a337b2503e268bb600a16c00db8ad5a @@ -1099,9 +1099,9 @@ typing-extensions==4.16.0 \ # opentelemetry-api # opentelemetry-sdk # opentelemetry-semantic-conventions -tzdata==2026.4 ; sys_platform == 'win32' \ - --hash=sha256:c2169a8b0a7a5e9674da5a135ccdfb2b3e671b333ed9fed17b41f73c34476e81 \ - --hash=sha256:f1b8bd365d8d210c55353f4d7f8d6d8561c0ba50d704b700d195a9424bba0d79 +tzdata==2026.5 \ + --hash=sha256:8cc73c0a0bfca7dbfa59235d60b2eff82231dee33f53d206db1acd9173cfc0a7 \ + --hash=sha256:b683bd1b6659ddcd810ff02ad09ba821d4bf1065072805063eb35c49617905ac # via -r .github/requirements/integration.in uritemplate==4.2.0 \ --hash=sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e \ diff --git a/.github/requirements/publish.txt b/.github/requirements/publish.txt index ba43a8a..6678b5d 100644 --- a/.github/requirements/publish.txt +++ b/.github/requirements/publish.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile .github/requirements/publish.in --generate-hashes --python-version 3.12 --python-platform x86_64-manylinux_2_28 --only-binary :all: --exclude-newer 2026-09-24T00:00:00Z -o .github/requirements/publish.txt +# uv pip compile .github/requirements/publish.in --generate-hashes --python-version 3.12 --python-platform x86_64-manylinux_2_28 --only-binary :all: --exclude-newer 2026-10-05T00:00:00Z -o .github/requirements/publish.txt build==1.6.1 \ --hash=sha256:51cc11666391ab6f092070437ac747002ff46f3e4113a3622177ee6b488bfc53 \ --hash=sha256:ecd351a4be9d35a9eaaba244a7687143c9c7d4aea6ac964e7e7ddab20cbcf4e7 @@ -284,53 +284,66 @@ charset-normalizer==3.5.1 \ --hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \ --hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f # via requests -cryptography==50.0.1 \ - --hash=sha256:01f41478cf33fc605a6a089cd56d28b45c6c0b45a1928b61797f2621a04bac71 \ - --hash=sha256:05ba322c4da95b262a212c345af888ef2c37c88c0509756ea00a0e6d68850f23 \ - --hash=sha256:16c5ecd954b3330ebfb6605eca4fd952da8bef376551d5cc264534e3770a9ee6 \ - --hash=sha256:2a93d05e34d5f67fba6f891fe85d929999baa7195e853923ea6d7576c9e68c5e \ - --hash=sha256:2b34d76a652ea2b6faf777c35df230c5637842cd904e04f16230c3f9f03e4361 \ - --hash=sha256:2ebbfb0f1fed745e91796e3e1080a1440423fdae8ece1b995a1d80883a409054 \ - --hash=sha256:30a125032e5642a21ff816e021152bd4e7e94f03eff3f4b7fca41cd22bc3110f \ - --hash=sha256:330fbb252391c596f1ae42c5754449dc924e6ad012dca8efe0d703f9f2d12ec6 \ - --hash=sha256:359e62deae718bce96170e223fdcb6357e4fbd3bb7a3a75f4430763532560e49 \ - --hash=sha256:407fe2b6db00939c05c0e945e9914238f2f0a430974839429dafc82b1ee6bee5 \ - --hash=sha256:42be3bb70596b3abe4ac097b75be223e8b3ab614a0e5de068e3dcc54d71d6149 \ - --hash=sha256:4c4188f7c0cf655be5c06342b817ed0f9595b69ffa2b12026e5353eed29dea88 \ - --hash=sha256:51593d180cf6d179bde5c5d065bed81386b1f381656ae7d042b7ffc87a9895ad \ - --hash=sha256:51afcfceb15597cf2635068e4ac9a56b2abde622edde17f37d85fd7b5306497a \ - --hash=sha256:53e279950892dc102c6b4e52af03ae5ea92fac572a1ddab78ca73a997f62b69f \ - --hash=sha256:55d16b1ef3ee0958d893a977b19777887e546c9954ea81b200c3301a864013f2 \ - --hash=sha256:5dd9bda1c12b4162f6ff568eeb5e0ff956c28d14406e875cfe8a63a2d414ff20 \ - --hash=sha256:5fe002589592ed749ce77fe0695fcbd3500dd61d7d6db5858a7544c612fa8e45 \ - --hash=sha256:5fe939deeb161024a6be98229c953b6591fef1f41214497a78fe793a244c017f \ - --hash=sha256:693c99b49bd37d0d096e4334c10232c77248c415b98d35236094cdf96d57258b \ - --hash=sha256:76de83fbd91ac49c0feaaa983d0748fd7a53176afac5fb3bf7478d244f0eb527 \ - --hash=sha256:79bf008d1f9af6071c797ad133e39915dfee7614f18f18f4db9072eb715064a3 \ - --hash=sha256:804728ce710890870f3aaa344b2e161172d258d768ac139d02cfd9092d0d94e6 \ - --hash=sha256:8921d58f426793c5f1b47f0b59575780de9a095214958d0eb37d909593db8367 \ - --hash=sha256:8df2de9102026855887e4587084f6eabd80ed0f345b8ad8a7ac27ab9bf4723e0 \ - --hash=sha256:9cb3cb952cf5a8abd50c782a98a89d71699715e802fe349704b47f2425b42a94 \ - --hash=sha256:9dde0a357190eb3b1da1bb9ab750e9c85cba82ca5977aa0836cbb94e92611239 \ - --hash=sha256:9ebcdd5519be9b652a46f507817a74591774fc3d6923ac364e4dfa64e36b291b \ - --hash=sha256:a0b1a59e3a089064a0ec309e9428c8e3ae4e161419d20ac33600767e83fc658a \ - --hash=sha256:a255449073358275b64b67d3f595f268bbef70e72b6edb65e0c70c735bf739c9 \ - --hash=sha256:a8f40ea47330e71b594a7e246898f93177c259490c63183dbaf9e571d71ed9a5 \ - --hash=sha256:ac02b07824d4d1001bd4367599f839c19cb171924c796e52c23508ac14c2c0cc \ - --hash=sha256:aed8db4f6d71c51efb89530e12d9464e7bf2923d46c3205dc794a2a93f8c0648 \ - --hash=sha256:b8f852c65863251b9e3a1b8c150ce21e59b522dbb6a7d4bc80e680d38388e986 \ - --hash=sha256:be224a65493ec5b74a158ff22a5522ce4a5ca1e543c647a3a4730d4a09e5f959 \ - --hash=sha256:ca83d00d9e69cd5eb63f2e69c3a5a59e0cecae5ae14c6ae0b35830fe3b37bad0 \ - --hash=sha256:cbf74a81765ee67413503ca6e26dcc4f6f5a519822436cc0a1b97aab6c1b8a17 \ - --hash=sha256:d63ae8f6481fec907ac0f588eee8a90aefde112c633131fe540e5711ddbb5a4e \ - --hash=sha256:e22dfed744bd4002e909464cb23d2f0b05c6f3113a79ef2e9864a53db737c733 \ - --hash=sha256:e2ca8fd1b6b4b82a1c4cb02841d0837e3c12336c2e24b520ab8ab3b969733d8f \ - --hash=sha256:e74591e283fe6eb956416c929eb58262a719fe0311fd9054c62c3350ed8760d8 \ - --hash=sha256:f74455bb086a85d5e81246412602aaa97ed095e504cd40dd261ef50be42205bf \ - --hash=sha256:fb4b9672d389c738b175c4166e78310f8a70358886aacd9173ee03a85ffdc671 \ - --hash=sha256:fc3ed7ebd2a8c96f5b166de0ab9b624996bef3b07bbeb19364dfb78222c22c80 \ - --hash=sha256:fd3718b960d0b5dd213cdf03f3bcb7000e69dda0de8b956061947ff6bcff5558 \ - --hash=sha256:ff838d62ec1bfce4f9ba7fa16f4a7b554cd8d0c299e6be37502161a660c84eef +cryptography==50.0.2 \ + --hash=sha256:0ddc924c04591c2811ca024d62ecad4f7f6f08af8939c211438f48a16bd23602 \ + --hash=sha256:0ec5f09541743261e66e291b4a0cbf0fb2997aeaab6d9e9c740b9dba1b58d1c2 \ + --hash=sha256:0ecbc5652bdb6fc9eaf89a7d196e20941adfe812f43bc4ca05d9150496821047 \ + --hash=sha256:1981f1db4630889b9ef7803fadef12b056f428cb6b85c27ba57b774793b6093c \ + --hash=sha256:1ba34f04897fcdaa73f74145c25f3ec146fbd56593853e88adc2e811303c5f42 \ + --hash=sha256:241449bf940a5d27309bd317e6f9a2af6932113818bb2b8f5c59ddc7ef16da18 \ + --hash=sha256:25784ce8b9621c90c643efb9e1e2162ab3b0224cae446ad5e70e7fcb1ce18b51 \ + --hash=sha256:3dc4fd8058cea1644971207d530e1a03a184a805ffc8ebdddf0599d78a331b81 \ + --hash=sha256:4061c0079120205fb760c58acab6443e217307dcf05e3702cf970e0689972856 \ + --hash=sha256:4a20ce1e5cb4284a86692fdcba7cb8754185c6b2e5c56fcef3751cf451d3cdc2 \ + --hash=sha256:4e81d95e5bafc2d6e34e4bed780e53e4d5b9a2f928573428aa4d35fbec1eb0de \ + --hash=sha256:58a0c478eeca76fe5e07993c5a0703def34a6dc6a0cda4f5564639b33112ffe7 \ + --hash=sha256:58ddb5a8e3179d12f19e4ea34d2d32e9d63a4baa142c875c1eb59f41b7243acd \ + --hash=sha256:630ebfea3bf689d075f82316324ff7433dc447fe6bc1bfc76524b74b4a9567d2 \ + --hash=sha256:6f8700550aa1474a91e5dc07049c46f98b423b5b1ddd0483e0b51362eeeaf5be \ + --hash=sha256:78198641e5be9521beea5aa782bb551a58068d10e6eb04c9c680c1b69f2e7d45 \ + --hash=sha256:79def8d059362e7831389ed3be0ecdf58a89386e1271e35dd9f5af84e81bffd0 \ + --hash=sha256:7a8701d6b584d76e909e3d305b7d126b41439876a5aaf76cddc67fc230eafa2e \ + --hash=sha256:7afa5a6602a9f29af1f3a2965f831bae7c9d5d597b7cbb716d41ab3b7d89879c \ + --hash=sha256:7b46165bb56eb4704e2eaaf86f3c940d19154535d9b0ca7d6d590b04060e00d5 \ + --hash=sha256:7b75de3c8b3be1cdb1052747c929440c3eea46c1bc2cb8a6e3a48388e9b7b452 \ + --hash=sha256:7c6d0330c472d96f6a6afe24d80dfdf15176c33096f0a4397ae4c60f3dd3be48 \ + --hash=sha256:828d49b0ff5a0e3975865571c5d91dbbdd0d38d8289b249a163e9425413a5e05 \ + --hash=sha256:84f964e537f916e2cc85199e5a88742e964939b575ac8598b3f9d6cc416cdaf1 \ + --hash=sha256:85d0d9a31b9098e98534226d5686b47264b95e62ce459dc2e62fdfc809f9fe93 \ + --hash=sha256:87e9ce85beb6b328ba370cc6e6aea483c92617b4c95b1d33a49297eb662bfb04 \ + --hash=sha256:8c71ba2cd31fc93748c38e1b613200ff1c2665cbfd5341fe3a61cfde35a1430e \ + --hash=sha256:92e665960f25fcdc73725b9cec7a3824f279ba97a98653afe9ffac2e43668f67 \ + --hash=sha256:94e5e9f108ee10471288214d3d233fbfbb492840a8457eb85178d643ddeb32c7 \ + --hash=sha256:9c8402a82ea0dc4ceeab793db05f0fafa8ca139ca34fcde5df0f596103c74107 \ + --hash=sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079 \ + --hash=sha256:a582ab2ae1d34f67112cadc86702774c9ea4374df6bca6afe672817203c99134 \ + --hash=sha256:a6557e5f38e065ca9fbdaf7cfc7435ecb1d113aa81a022d1b51921ee7432e227 \ + --hash=sha256:a9f7355e6fab51f6c369b86fb7571cffa05edee2c2121e0380a37fb9ac1cd5c1 \ + --hash=sha256:ab50ee449bf968271e820086f10a33d101dd060370abc10bcd22279be2656539 \ + --hash=sha256:ac9ed99d81760c62fe89d5f0815cdfa1ba9a35141cf30f1c2d044f04b4803d2e \ + --hash=sha256:b13478603dcd0a2479ff8e87e2c19a7d525734686fe3c49542472293a204212d \ + --hash=sha256:c423ab384a46c4dff7217b2ea5ba2e11cffdeab6441acd04cf65a369caf0366c \ + --hash=sha256:c5e67125c7dca78d199ec4e116aa93dbb83494808ecbb8211a2cb09b1bf41dbd \ + --hash=sha256:c71be1cbfa5cd9a41ee452acf1eccd82b2c05950358b106ec8ceb83411d1a020 \ + --hash=sha256:cbc8738fd8526d80f35cb3a40d41f41a2e7030bb3b18b09a6778ef63d291c2fd \ + --hash=sha256:ce47f66801c20ec6c6632453bb5960fe38939e9306970b48b3a5a26de7745d94 \ + --hash=sha256:d370b8d1dfcdf7130178137f6fbee6140774a1acc6cacefc4b42643ec11d0a3a \ + --hash=sha256:d38cdff612d06fa6a32840d5e1b1f7a27cee4a349aa9085d94a67789d6bfd408 \ + --hash=sha256:d8947001be83df1394050758ce0e745dd74fb134eef0a4b5124208dfc3a68c37 \ + --hash=sha256:deb9fde5c60e437ee4821bc9bc39ff31b42135c27e1dc61ef0a629389c1de62e \ + --hash=sha256:dfe9763530994147d9af1def057a5b9658b00e8f8fe8743d144d1e0911c2e454 \ + --hash=sha256:e105ab60406787da31fccc883fc0f733af1efd78f0136a4599692c4083a73d0c \ + --hash=sha256:e275096ea1e60cc595cda2836fd4a6c725d1125108b868be17f53684d164e2cc \ + --hash=sha256:edc3342adf8f697fc5f59c887a304356f147b397809440ed64e2fa6af2f50f37 \ + --hash=sha256:ee247f5c245c9a2fe7c8e2214e295918838e44e00a45a6718451e4004219e767 \ + --hash=sha256:eef4c2f3423810b3070ab391f85436d2f8bbfcb286ac15cbc73190b3563b1f1a \ + --hash=sha256:f21e8a22c8605750c7af886bab299a363721264061b4ac0a30efb73cfd58efc5 \ + --hash=sha256:f265528741e048bce55c3463ed721fb0aa45a5888d8add8cfeccb3035451bbdc \ + --hash=sha256:f2f9bd7f90c64fe89253f0a2c05e3c4856072660429ce8831b4235bf29403a67 \ + --hash=sha256:f785f6161f202ab04d8ca194158968798e480ca058943907972da5f12e2881e8 \ + --hash=sha256:f9f6143a8c75945eb960d9eb98905a441394abfa24afaae239d514ffb2586480 \ + --hash=sha256:fa8f5efb344d6908a1ce62f4a24e2e5780f825d6f53f5f50ec5ffacac72936cb \ + --hash=sha256:fdd28f912fccfec1846a94e2e1e8f9b0012f557f0c46fe4f3eb0d7a87afcf90b # via secretstorage docutils==0.23 \ --hash=sha256:25d013af9bf23bc1c7b2b093dff4208166c53a94786c9e447808335ef1185fea \ diff --git a/architecture.md b/architecture.md index d500aaa..5bffabc 100644 --- a/architecture.md +++ b/architecture.md @@ -41,7 +41,7 @@ piece of the 1.0 roadmap (`docs/FILEAUTOMATION-1.0-ROADMAP.md`, PR #107); what i | `MANIFEST.in` | Keeps `tests/` out of both source distributions (`tests/test_sdist_manifest.py`); package discovery in the TOMLs already keeps it out of the wheels | | `scripts/dev_release.py` | Release helper for the dev channel (standard library only): picks the next `automation_file_dev` version from PyPI and tells whether the built wheel differs from the newest published one | | `.github/requirements/publish.in`, `publish.txt` | The tools of the two publish jobs (`build`, `twine`, and the build backend `setuptools`) and their hash-locked resolution for Python 3.12 on Linux. `publish.in` holds the `uv pip compile` command that regenerates `publish.txt`; Dependabot reads the directory | -| `.github/requirements/lint.in`, `lint.txt`, `integration.in`, `integration.txt` | Hash-locked wheel dependencies for lint and Python 3.12 integration jobs. The editable package uses the locked build backend without dependency resolution or build isolation. | +| `.github/requirements/lint.in`, `lint.txt`, `integration.in`, `integration.txt`, `.pip-tools.toml` | Hash-locked wheel dependencies for lint and Python 3.12 integration jobs. Shared integration inputs retain Windows timezone data on every compiler host; pip-tools configuration keeps the hashed setuptools build backend during Dependabot updates. The editable package uses that backend without dependency resolution or build isolation. | | `main_ui.py` | Development shortcut for `launch_ui()` | | `tests/`, `docs/`, `examples/mcp/` | pytest suite (fixtures, including the shared Qt application lifecycle, in `tests/conftest.py`); Sphinx docs; MCP host configuration example | diff --git a/docs/updates/2026-10.md b/docs/updates/2026-10.md index a59a9cb..7acb3e0 100644 --- a/docs/updates/2026-10.md +++ b/docs/updates/2026-10.md @@ -756,3 +756,8 @@ Index and query commands: [README.md](README.md). New entries go at the end. ## U-20261011-02 · 2026-10-11 · Keep circuit breaker clock fixtures lint clean · #done #ci Name the clock fixture explicitly and request its side effect through usefixtures where no clock value is used. All eight circuit breaker regression tests pass. + + +## U-20261012-01 · 2026-10-12 · Preserve cross-platform integration dependencies during automated updates · #done #ci + +Keep tzdata unconditional in shared integration inputs so Linux-based dependency updates retain Windows timezone data. Add pip-tools configuration for Dependabot and local compilation to retain the hash-locked setuptools build backend. Regenerate the universal Python 3.12 lock with the seven-day release cutoff and add Linux, macOS and Windows compiler regressions. Validation: 37 workflow tests passed; the full local suite passed 5390 tests with 230 optional skips; Ruff lint and format checks passed; mypy reported no issues in 275 source files. Remote service jobs must install the editable package without fetching an unlocked backend. diff --git a/docs/updates/README.md b/docs/updates/README.md index 302e9af..4c3193c 100644 --- a/docs/updates/README.md +++ b/docs/updates/README.md @@ -58,6 +58,7 @@ In the same commit: delete the item from `progress.md`, add a `#done` entry here | ID | Date | Title | Tags | Batch | |---|---|---|---|---| +| U-20261012-01 | 2026-10-12 | Preserve cross-platform integration dependencies during automated updates | #done #ci | [2026-10](2026-10.md) | | U-20261011-02 | 2026-10-11 | Keep circuit breaker clock fixtures lint clean | #done #ci | [2026-10](2026-10.md) | | U-20261011-01 | 2026-10-11 | Integrate open pull requests and stabilize circuit breaker tests | #ci #tests #dependencies | [2026-10](2026-10.md) | | U-20261008-39 | 2026-10-08 | The legacy CLI flags exit 1 when an action failed | #feature #cli #testpioneer | [2026-10](2026-10.md) | @@ -136,5 +137,5 @@ In the same commit: delete the item from `progress.md`, add a `#done` entry here | File | Period | Entries | |---|---|---:| -| [2026-10.md](2026-10.md) | 2026-10 | 52 | +| [2026-10.md](2026-10.md) | 2026-10 | 53 | | [2026-09.md](2026-09.md) | 2026-09 | 21 | diff --git a/tests/test_workflow_actions.py b/tests/test_workflow_actions.py index 4213f30..da04b89 100644 --- a/tests/test_workflow_actions.py +++ b/tests/test_workflow_actions.py @@ -219,6 +219,25 @@ def test_lint_and_integration_jobs_cannot_resolve_unlocked_dependencies(workflow assert "--only-binary :all:" in command +@pytest.mark.parametrize( + "environment", + [ + {"platform_system": "Linux", "sys_platform": "linux"}, + {"platform_system": "Darwin", "sys_platform": "darwin"}, + {"platform_system": "Windows", "sys_platform": "win32"}, + ], + ids=["linux-compiler", "macos-compiler", "windows-compiler"], +) +def test_shared_integration_inputs_keep_timezone_data_on_every_compiler(environment): + """A Linux dependency update must retain Windows timezone data in the shared lock.""" + lines = (_REQUIREMENTS / "integration.in").read_text(encoding="utf-8").splitlines() + requirements = [ + Requirement(line) for line in lines if line.strip() and not line.startswith("#") + ] + timezone = next(item for item in requirements if canonicalize_name(item.name) == "tzdata") + assert timezone.marker is None or timezone.marker.evaluate(environment) + + def test_integration_lock_covers_the_package_and_its_build_backend(): text = (_REQUIREMENTS / "integration.txt").read_text(encoding="utf-8") pins = {canonicalize_name(name): version for name, version in _PIN.findall(text)}