Repository navigation
Conversation
relock_dependencies.sh upgrades every package in uv.lock to the newest version pyproject.toml allows, passing --upgrade-package for each locked package except policyengine and the packages its extras pin (Core, the country models and the SPM calculator), which change only through the bundle update workflow. It resolves with Python 3.12 by default, runs uv lock --check, fails if a held package moved anyway, and reports changed=true or changed=false with a Markdown summary of the version changes. locked_packages.py reads the lock for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
open_relock_pull_request.sh commits the relocked uv.lock with a changelog fragment on the fixed relock branch, rebuilt from the base branch on every run. It pushes with a lease on the commit it last saw, and skips the push when the branch already holds the same files. It reuses the oldest open "Relock dependencies" issue or opens one, then opens the pull request with "Fixes #N" as the first line of its description and the version changes below it, or updates the description of the open relock pull request instead of opening another. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
relock-dependencies.yml runs at 07:00 UTC every day and on manual dispatch. It checks out the branch with the policyengine App's token, relocks with Python 3.12 and the uv version push.yml locks releases with, and runs open_relock_pull_request.sh only when uv.lock changed, so pull_request CI runs on the result. A run on master proposes the relock from auto/relock-dependencies; a manual run on another branch proposes it to that branch from a branch of its own. The workflow token is read-only. The relock branch is now fetched with --depth=1, so a shallow checkout does not download the history behind an older relock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gh pr list --head matches the head branch name in forks too, so a fork pull request from a branch named auto/relock-dependencies would have been treated as the relock pull request: its description edited, and no pull request opened for the pushed branch. The lookup now selects only pull requests whose head is in this repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
auto-relock-dependencies-workflow
branch
from
October 21, 2026 20:29
d4b173b to
a203765
Compare
This was referenced Oct 21, 2026
anth-volk
added this pull request to stack #3998
October 21, 2026 20:43
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## api-tests-from-lock #3994 +/- ##
====================================================
Coverage 49.24% 49.24%
====================================================
Files 243 243
Lines 14398 14398
Branches 2343 2343
====================================================
Hits 7090 7090
Misses 6682 6682
Partials 626 626 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3992
Summary
Adds
.github/workflows/relock-dependencies.yml, which relocksuv.lockevery day at 07:00 UTC (and on manual dispatch) and opens or updates a pull request with the result. Once CI installs fromuv.lockinstead of the newest PyPI versions, this pull request is how upgrades get tested and adopted..github/scripts/relock_dependencies.sh, helperlocked_packages.py): upgrades every locked package to the newest versionpyproject.tomlallows by passinguv lock --upgrade-packagefor each one, exceptpolicyengine(the .py bundle) and the packages its locked extras pin (todaypolicyengine-core,policyengine-us,policyengine-uk,spm-calculator). uv 0.12 has no option to exclude packages from--upgrade, so the script lists the packages to upgrade instead. Then it runsuv lock --check, and fails if a held package moved anyway. It resolves with Python 3.12 (--python 3.12;.python-versionnames 3.14). The resolution still covers every versionrequires-python = ">=3.11"allows.uv.lockis byte-identical after the relock, the step reportschanged=falseand the pull-request step is skipped..github/scripts/open_relock_pull_request.sh): commitsuv.lockandchangelog.d/relock-dependencies.changed.md(the changelog check needs a fragment) onauto/relock-dependencies, rebuilt frommasteron each run. It pushes with--force-with-leaseon the commit it last saw, and skips the push when the branch already holds the same files. It reuses the oldest open issue titled "Relock dependencies" or opens one. If no relock PR is open, it opens one withFixes #Nas the first line, then the version changes (old → new) and the held packages. If one is open, it updates that PR's description instead of opening another.contents: read. The policyengine App's token checks out, pushes, and writes the issue and pull request, sopull_requestCI runs on the result.masterrelocks that branch and proposes it to that branch fromauto/relock-dependencies-<branch>, so it doesn't touch themasterrelock PR.How the bundle is pinned:
pyproject.tomlpinspolicyengine[models]==6.7.5, and policyengine 6.7.5'smodelsextra pinspolicyengine-core==3.33.0,policyengine-us==2.2.1,policyengine-uk==2.130.1andspm-calculator==1.0.0. With today's exact pins a plainuv lock --upgradelocks the same versions (checked locally; only the order of 12 resolution-marker entries differed). The exclusion keeps those packages held if a pin is ever loosened, because the "Ensure PolicyEngine bundle is supported by simulation API" check runs only when thepolicyengine[models]pin changes.policyengine-canada,policyengine-ngandpolicyengine-ilaren't in the bundle. Their exact pins inpyproject.tomlhold them.The workflow edits no file the CI-from-lock work touches (
pr.yml,push.yml,Makefile). The rules registry needs no entry:[discovery].workflowscovers onlypr.yml, and theci-scriptsguard (single-linerun:steps, tested scripts, shellcheck) passes for the new workflow and scripts.Testing
Red-green per commit (
uv run --quiet --frozen --extra dev --python 3.12 pytest ...):relock_dependencies.shnot found (exit 127),locked_packages.pynot found (exit 2)open_relock_pull_request.shnot found (exit 127). The failure-path test was tightened to assert that the issue lookup ran, so it doesn't pass vacuously. Then a missing-summary test: 1 failed, because the script exited 0 without the summaryrelock-dependencies.ymlnot foundnumber, so a fork PR with the same head branch name would matchThe tests fake
uvandgh. The pull-request tests push to a local bare repository, with no network access. One change has no test: the third commit fetches the old relock branch with--depth=1, so a shallow checkout doesn't download its history. The tests use a full local repository.master's lock upgraded 142 packages, held the five bundle packages at their versions, keptrequires-python = ">=3.11", and passeduv lock --check. The lock wasn't committed here.tests/unit: 2964 passed (run on the third commit). On the final commit the 23 relock tests pass; the fourth commit changes only the relock pull-request script and its test.ruff format --check .andruff check .(locked ruff),python scripts/run_quality_guards.py,python -m scripts.rules guard --base-ref origin/master,python -m scripts.rules render(no changes),uv lock --check, andshellcheckon both new scripts: all pass. No inline suppressions (noqa) added.gh pr list --headalso matches fork branches with the same name, so the lookup now selects only same-repository pull requests. Two coverage gaps remain: the--depth=1fetch and the summary format for a package locked at more than one version have no tests.workflow_dispatchreturns 404 until the workflow file is onmaster, so the workflow hasn't run on GitHub yet.🤖 Generated with Claude Code