From 39a908378b989e8639501a7ca38c5f39382da79f Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Singh Date: Fri, 25 Sep 2026 21:21:45 +0530 Subject: [PATCH 1/2] ci: run the suite weekly against re-resolved dependencies 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) --- .github/workflows/ci.yml | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33f4a44..09c1f9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,13 @@ on: push: branches: [main] pull_request: + # Mondays, 06:00 UTC. Every other trigger here is caused by someone pushing, + # so without this the suite is only ever run against the dependency versions + # `uv.lock` pins -- see the `upstream-drift` job for what that hides. Note + # GitHub disables a scheduled workflow after 60 days with no repository + # activity, so a long quiet spell stops these runs rather than failing them. + schedule: + - cron: "0 6 * * 1" workflow_dispatch: permissions: @@ -167,6 +174,40 @@ jobs: # `addopts` in pyproject.toml supplies `-m 'not live'`. run: uv run pytest + upstream-drift: + # `uv.lock` is what every other job resolves against, so nothing in this + # workflow would notice a new `langgraph` minor breaking the runtime until a + # user on a fresh `pip install grapharc` hit it. Issue #103 is the standing + # form of that complaint: the extras are unbounded and the lockfile hides + # what the next major would do. This job re-resolves every range from + # scratch and runs the suite against the newest versions the constraints in + # pyproject.toml actually allow. + # + # Scheduled and manual only, deliberately. A pull request has to be judged + # against the lockfile it ships; if this ran on PRs, an upstream release on + # the morning of a review would turn someone else's branch red for a reason + # that branch did not cause. + name: upstream drift (unlocked deps) + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v5 + with: + python-version: "3.12" + enable-cache: true + - name: Re-resolve every dependency to the newest allowed version + run: uv lock --upgrade + - name: Report what moved + # Printed whether or not the suite then passes: a green run against + # moved dependencies is the useful half of this job, because it is the + # evidence that a range can be widened or a pin dropped. + run: git --no-pager diff --stat -- uv.lock + - name: Sync and test against the re-resolved versions + run: | + uv sync --all-extras --group dev + uv run pytest + build: name: build and check the distribution runs-on: ubuntu-latest From e2cafbe74803fdc92e177bfa12c1c0cdf6f2454e Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Singh Date: Sat, 26 Sep 2026 00:29:42 +0530 Subject: [PATCH 2/2] ci: a failing drift run reports to the issue tracker, not the Actions 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) --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09c1f9a..02ce4f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,6 +190,12 @@ jobs: name: upstream drift (unlocked deps) if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + # `issues: write` is for the reporting step below; a job's permissions + # replace the workflow's rather than adding to them, so `contents: read` + # is repeated here. + permissions: + contents: read + issues: write steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 @@ -207,6 +213,45 @@ jobs: run: | uv sync --all-extras --group dev uv run pytest + - name: Say so where someone will see it + # A scheduled run reports to nobody. This repository has already paid + # for that: `pages.yml` failed on two consecutive pushes 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 at a time is the same shape, + # so the failure comes to the issue tracker instead of the Actions tab. + # + # One issue, reused: an unattended weekly job that opens a fresh issue + # every Monday is a second way of being ignored. Matched on title + # rather than a label, so this needs no label to exist first. + if: failure() + env: + GH_TOKEN: ${{ github.token }} + TITLE: "upstream drift: the suite fails against re-resolved dependencies" + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + body=$(cat <