ci: run the suite weekly against re-resolved dependencies - #116
Merged
Merged
Conversation
Every trigger on this workflow was caused by someone pushing, so the suite only ever ran against the versions `uv.lock` pins. That is the right thing for a pull request and the wrong thing as the only signal: a `langgraph` minor that breaks the runtime is invisible here until a user on a fresh install hits it. Issue #103 is the standing form of the complaint -- the extras are unbounded and the lockfile hides what the next major would do. Adds a Monday cron and one job that re-resolves every range from scratch (`uv lock --upgrade`) and runs the suite against the newest versions pyproject.toml's constraints allow. The job is gated to `schedule` and `workflow_dispatch`: on pull requests it would turn someone's branch red for an upstream release that branch did not cause. The re-resolved lockfile diff is printed whether or not the suite passes, because a green run against moved dependencies is the evidence needed to widen a range or drop a pin. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… tab The job as first written had the flaw it was built to fix, one level up: it would detect upstream breakage and then tell nobody. A scheduled run has no pull request to turn red and no author to notify, and this repository has already paid for exactly that -- `pages.yml` failed on two consecutive pushes and sat unnoticed for the better part of two months, while the published site served a version six releases behind. A weekly job in a repository that goes quiet for weeks is the same shape. So a failure now opens an issue, or comments on the open one if there is already one. Reused rather than re-opened: an unattended weekly job that files a fresh issue every Monday is a second way of being ignored. Matched on title rather than a label, so it needs no label to exist first. The body says what a reader needs and not more: that this is not any branch's fault, that every other job resolves against `uv.lock` while this one does not, that the remedy is an upstream fix or a narrower range in pyproject.toml (#103), and that the run log's lockfile diff names what moved. `issues: write` is added at the job level, which replaces rather than extends the workflow's permissions, so `contents: read` is repeated there. Verified by extracting the step's script from the parsed YAML and running it against a stubbed `gh`: the heredoc dedents correctly out of the block scalar, the escaped backticks survive as literals, `$RUN_URL` expands, and the two paths do what they claim -- create when no issue is open, comment when one is, with no duplicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Shashankss1205
added a commit
that referenced
this pull request
Sep 26, 2026
…#129) Closes #103. #116 already covered most of what that issue asked for -- a weekly resolve that ignores `uv.lock`, reporting to the issue tracker, not gating pull requests. What it did not cover is the criterion's other half: importing every subpackage from the *built wheel*. The distinction is the one #101 was: `mcp>=1.2` resolved to 2.0.0 for anyone installing fresh, `mcp.server.fastmcp` had gone, and `grapharc[mcp]` was broken on arrival while every locked job stayed green. A suite run from the source tree does not see a packaging break that only shows in an installed wheel -- a subpackage dropped from the build, or an extra whose new major moves a module the package imports at import time. The walk moves out of `ci.yml`'s heredoc into `scripts/wheel_import_walk.py`, because two jobs now need exactly this check and two copies would drift apart. Same logic, two parameters: which checkout to compare against, and the prefix the import must come from. `scripts/` holds no `grapharc` package, so running it by path does not put the checkout on `sys.path` -- the property the old `cd /tmp` was there for, kept and now asserted with a message rather than a bare `assert`. Verified by running it for real rather than reasoning about it, and it earned its keep immediately: against the wheel then sitting in `dist/` it reported `grapharc.examples.plan_research` missing -- correctly, because that wheel was built before #115 merged. Rebuilt, it walks 132 modules clean. Deliberately **not** done: putting a ceiling on the eight unbounded extras. The issue asks for a decision on that and argues a bound should be "a ceiling with a reason attached, not a reflex" -- so adding eight of them at once is the reflex it warns against, and it would refuse users upgrades that are fine. Detection is what this closes; the policy is left open. Verified: 2214 selected, 13 deselected, ruff clean; the sdist's required-files and secret-leak checks still pass with `scripts/` added. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Every trigger on
ci.ymlwas caused by someone pushing, so the suite only ever ran against the versionsuv.lockpins. That is correct for a pull request and wrong as the only signal: alanggraphminor that breaks the runtime stays invisible here until a user on a freshpip install grapharchits it.That is the standing complaint in #103 — every extra but
mcpis unbounded, and the lockfile hides what the next major would do. With six weeks between commits there is currently no signal at all.What this adds
scheduletrigger.upstream-driftjob that runsuv lock --upgradeto re-resolve every range from scratch, then syncs and runs the suite against the newest versionspyproject.toml's constraints allow.Two deliberate choices
Gated to
scheduleandworkflow_dispatch. On pull requests this would turn a contributor's branch red for an upstream release that branch did not cause. A PR has to be judged against the lockfile it ships.The re-resolved lockfile diff is printed whether or not the suite then passes. A green run against moved dependencies is the useful half — it is the evidence needed to widen a range or drop a pin, which is what #103 actually asks for.
Noted in a comment on the trigger: GitHub disables a scheduled workflow after 60 days without repository activity, so a long quiet spell stops these runs rather than failing them.
Verification
ci.ymlparses; the five jobs arelint,live-marker-guard,test,upstream-drift,build, and the cron expression round-trips. Full suite green locally on 3.14.7 — 2151 passed, 13 live deselected.🤖 Generated with Claude Code
Follow-up commit: the job now reports where someone will see it
As first written this job had the flaw it exists to fix, one level up: it would detect upstream breakage and tell nobody. A scheduled run has no pull request to turn red and no author to notify.
This repository has already paid for exactly that.
pages.ymlfailed on two consecutive pushes in August and the failures sat unnoticed for the better part of two months, while the published site served a version six releases behind. A weekly job in a repository that goes quiet for weeks is the same shape.So a failure now opens an issue, or comments on the open one if there already is one — reused rather than re-opened, because an unattended weekly job that files a fresh issue every Monday is a second way of being ignored. Matched on title rather than a label, so it needs no label to exist first.
The body tells a reader what they need: that this is not any branch's fault, that every other job resolves against
uv.lockwhile this one does not, that the remedy is an upstream fix or a narrower range inpyproject.toml(#103), and that the run log's lockfile diff names what moved.issues: writeis added at the job level, which replaces rather than extends the workflow'spermissions, socontents: readis repeated there.Verification
A reporting step that only runs on a failing Monday months from now is not something to take on trust, so I extracted the step's script out of the parsed YAML and ran it against a stubbed
gh:$RUN_URLexpands;issue create; with one open it callsissue commentand neverissue create.