ci: detect public-API breakage with griffe check - #118
Merged
Conversation
Add a pull-request job that diffs the working tree's public API against the latest release tag with griffe check, covering interlock/__init__.py's re-exports and interlock/integrations/* (public, not re-exported). A detected breakage is failable but overridable via the "breaking-change" label, since a future major release will make one on purpose.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
bagowix
added a commit
that referenced
this pull request
Aug 3, 2026
Every release bumps `interlock.VERSION`, and `griffe check` reports the new value as a changed attribute — the release mechanism working, not a public-API breakage. The job was added in #118 and this is the first release since, so it had never been exercised against a bump: it failed the 2.1.4 release PR and would have failed every one after it, or forced a misleading `breaking-change` label onto it. The `-f github` run still annotates the diff; the gate now reads a `oneline` run with that one finding filtered out. The filter matches only that attribute, in that file, for that check — if griffe rewords the message it stops matching and the job fails, which is the safe direction.
7 tasks
bagowix
added a commit
that referenced
this pull request
Aug 3, 2026
## Summary Prepare the `2.1.4` patch release. - bump the package version from `2.1.3` to `2.1.4` - move the current changelog entries from `[Unreleased]` into `2.1.4` - update changelog comparison links - update the release version in the comparison page - regenerate `docs/llms-full.txt` Everything in `[Unreleased]` is infrastructure, documentation and bug fixes — the correctness docs page, the OpenSSF badge, `griffe check`, mutation testing, pyrefly, the Codecov move, the supply-chain hardening, plus the coordinator lane `task_done()` fix and `EventListener` failure isolation. No public symbol was added or changed, so this is a patch, not a minor. ### Why now The `v2.1.4` tag was pushed while `interlock/version.py` still read `2.1.3`, so the release workflow built `2.1.3` artifacts and PyPI rejected the upload — that filename already exists and PyPI never allows reuse. The tag has been deleted locally and on the remote; it needs to be re-created on the merge commit of this PR so the build picks up the bumped version. ### Note on `docs/llms-full.txt` The regenerated file carries one change that is not from the version bump: #87 changed the migration-guide anchors in `docs/migration.md` but did not regenerate `llms-full.txt`, so the committed copy had drifted. Running `scripts/build_llms_full.py` brings it back in sync. `docs/comparison.md` keeps its "as of July 2026" label: that date records when the *other* libraries' versions were checked, and only interlock's own cell moves — the same way the 2.1.3 release handled it. ### The griffe gate had to be fixed first `griffe check` failed this PR on `Attribute value was changed: '2.1.3' -> '2.1.4'`. The job landed in #118 and this is the first release since, so it had never run against a version bump — it would have failed every release from now on, or forced a misleading `breaking-change` label onto each one. The `-f github` run still annotates the diff; the gate now reads a `oneline` run with that single finding filtered out. The filter matches only that attribute, in that file, for that one check, so it fails closed: if griffe rewords the message it stops matching and the job fails. Verified both ways locally — the bump alone passes, and a removed public export (`sync_timeout`) still fails it. ## Checklist - [x] Test suite passes with 100% coverage (583 passed, 2 skipped) - [x] `uv run ruff format --check` and `uv run ruff check` pass - [x] `uv run mypy`, `uv run pyright` and `uv run pyrefly check` pass - [x] Documentation updated (`docs/`) - [x] `CHANGELOG.md` `[Unreleased]` updated - [x] Release artifacts build successfully (`interlock_cb-2.1.4`, sdist + wheel) - [x] Commits follow Conventional Commits ## Related issues - Includes changes from #83, #97, #102, #103, #104, #105, #107, #113, #87
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.
Summary
.github/workflows/api-compatibility.yml: a pull-request job that runsgriffe check interlock --search ., diffing the working tree's public APIagainst the latest release tag (removed/renamed objects, changed parameter
kinds, order or defaults, narrowed return types).
interlock/__init__.py's re-exports andinterlock/integrations/*,which is public even though it is not re-exported.
breaking-change(created on the repo), in which case it's reported as awarning instead — a future major release should not be blocked by its own
tooling.
griffeadded as a dev-only dependency (uv add --dev griffe); the corestays at zero dependencies.
CONTRIBUTING.md,and the tool/command in
AGENTS.md.Checklist
code changed; full suite still passes at 100% coverage
uv run ruff format --checkanduv run ruff checkpassuv run mypy,uv run pyrightanduv run pyrefly checkpassCONTRIBUTING.md,AGENTS.md) — no user-facingdocs/change needed (non-goal: no griffe/mkdocstrings API docs generation)
CHANGELOG.md[Unreleased]updateduv run zizmor .github/workflows/passes (new workflow audited clean)Related issues
Closes #104