ci: cover the full supported Python and Django matrix on every PR - #58
Merged
Merged
Conversation
pyproject.toml has allowed django<7.0 since dfcfd9f, but the CI matrix stopped at Django 5.2, so Django 6.0 and 6.1 were an untested claim of support. Verified locally that all four tests pass on 6.0.8 and 6.1.1 across Python 3.12, 3.13 and 3.14, then added the six missing legs. The matrix is now the full intersection of what the package declares: each Python in project.classifiers crossed with each Django series the dependency specifier allows, minus the pairs upstream Django rejects. That is 17 legs, Django 4.2 to 6.1 on Python 3.11 to 3.14. Also stop running the whole matrix twice per pull request. An unfiltered push trigger alongside pull_request meant every same-repo PR started two identical runs; push is now limited to main, and superseded PR runs are cancelled. Release runs are never cancelled, since cancel-in-progress is gated on the event being a pull_request. Each leg now prints the Django and Python it actually resolved into the job summary. make test-django layers uv run --with over the locked environment, so a constraint that silently failed to apply would pass as a false green against whatever uv.lock pins. Add a Required Checks job that aggregates the workflow into one stable check name for branch protection, because matrix job names change whenever a series is added or dropped. Declare the tested range as Framework :: Django classifiers, correct the stale django<6.0 line in the README, and document the rule that widening the declared support without widening the matrix is what caused this. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GitHub Actions expressions accept single quotes only as string delimiters, so join(needs.*.result, " ") made the whole workflow file invalid. The run failed at startup with zero jobs and the pull_request run never materialized. Verified with actionlint across every workflow in .github/workflows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merged
imakecodes
added a commit
that referenced
this pull request
Sep 11, 2026
Minor rather than patch: #60 changes the generated output for every user. A relation column is now typed by the column it points at, so a foreign key to a BigAutoField primary key renders as `big_auto` where it used to render as `foreign_key`. No API or CLI break, but anyone versioning a .dbml file will see a diff. Shipping since 1.1.2: - #57 CLAUDE.md and shared .claude configuration - #58 CI covers the full declared support matrix, Django 4.2 to 6.1 on Python 3.11 to 3.14, plus Framework :: Django classifiers so the tested range is visible on PyPI - #59 command surface and relation invariants under test, 89% to 99% - #60 relation columns typed by their target (closes #38) Regenerate uv.lock alongside the version. The package is a member of its own workspace, so uv.lock records project.version and `uv sync --locked` fails without it. That would have broken the release workflow at the sync step, before it built anything. Drop the hardcoded version from the release example in CONTRIBUTING.md; it went stale on every release. Co-authored-by: Michel Wilhelm <michel@revealhealth.com> Co-authored-by: Claude Opus 5 <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.
Why
Unit tests already ran on every pull request, but the matrix had drifted away from what the package actually promises.
pyproject.tomlhas alloweddjango>=4.2,<7.0since dfcfd9f. The CI matrix stopped at Django 5.2. Django 6.0 and 6.1 have been released, so the package has been claiming support for a major series that CI never executed once.I verified locally before touching the workflow. All four tests pass on Django 6.0.8 and 6.1.1, on every Python those series support:
So this is coverage that was missing, not a bug that was hiding.
What changed
The matrix is now the full intersection of what the package declares rather than a hand-maintained subset: each Python in
project.classifierscrossed with each Django series the dependency specifier allows, minus the pairs upstream Django does not support. 11 legs become 17.The gaps are upstream constraints, not omissions: Django 4.2 and 5.0 do not support Python 3.13, and Django 6.x requires Python 3.12 or newer.
The matrix no longer runs twice per PR.
on: pushhad no branch filter, so every pull request from a same-repo branch started two identical runs. PR #57 showed 27 checks where 14 would have done.pushis now limited tomain, and superseded PR runs are cancelled. Release runs are never cancelled:cancel-in-progressis gated on the event being apull_request, so theworkflow_callfrom the publish workflows is unaffected.Each leg now reports the versions it actually resolved into the job summary.
make test-djangolayersuv run --with <constraint>over the locked environment, so a constraint that silently failed to apply would pass as a false green against whateveruv.lockpins. The step iscontinue-on-error, purely diagnostic, and can never mask a test result.New
Required Checksjob aggregates the workflow into one stable check name. Branch protection should require that rather than 17 job names that change whenever a series is added or dropped, because a required check that no longer exists stops being enforced silently.Added
workflow_dispatchfor manual runs, andtimeout-minuteson every job.Supporting changes
Framework :: Django :: 4.2through6.1classifiers, so the tested range is visible on PyPI. All six verified against the current trove list.README.mdsaidDjango >=4.2,<6.0, which was stale in both directions. Now<7.0, with a pointer to the matrix.docs/development.mdandCLAUDE.mdrecord the rule that caused this: wideningrequires-python, thedjangospecifier, or the classifiers without adding the matching legs ships an untested claim of support..claude/commands/in docs: add CLAUDE.md and shared .claude configuration #57, and pointed/extend-generatorat both ends of the range instead of only the oldest.Verification
make cipasses locally: Ruff clean, 4 tests, wheel and sdist build. Wheel metadata confirmsRequires-Dist: django<7.0,>=4.2alongside the new classifiers.Follow-ups not in this PR
github-actions. Adding theuvecosystem would surface new Django series as PRs, which is the mechanism that would have caught this drift earlier.get_db_type()branches on five backends andbuilder.pyimportsdjango.contrib.postgres.indexes.HashIndex. A PostgreSQL leg is a separate axis worth its own PR.🤖 Generated with Claude Code