Closed as not planned
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified, ready for an AFK agentFully specified, ready for an AFK agent
Description
Why
The standard, section 7: every library's ci.yml and scheduled.yml call one reusable checks.yml living here, referenced at main. Today 22 repos carry a copy of _checks.yml; 12 are byte-identical and the rest differ in service containers, the lint-job Python pin, and a docs job.
Design (settled)
- File:
.github/workflows/checks.ymlinmodern-python/.github,on: workflow_call. Callers:uses: modern-python/.github/.github/workflows/checks.yml@mainwithsecrets: inherit. Referenced atmaindeliberately: one merge here reaches every repo; a change is first exercised from a branch ref in one repo. - Jobs:
linton the repo's floor Python (just install lint-ci),pytestmatrix (just installthenjust test-ci,fail-fast: false),links(lychee--offlinewith theblob/mainremap),docsbehind a boolean input. - Matrix derived at run time: floor from
requires-python, ceiling from the newest released cycle onhttps://endoflife.date/api/python.json, plus that cycle's free-threaded build. No repo edits a matrix when a Python ships. - Service containers: GitHub's context table lists
inputsas available injobs.<job_id>.services, so the shared workflow can take the image and health command as inputs for the four repos that need one (db-retry: postgres; faststream-redis-timers, modern-di-arq: redis; faststream-concurrent-aiokafka: redpanda). Verify this on the first of those four before migrating the others. release.ymlstays per repo: PyPI Trusted Publishing does not accept a reusable workflow (Trusted publishing: Support for GitHub reusable workflows pypi/warehouse#11096, open).
Done when
Every library's ci.yml and scheduled.yml call the shared workflow and _checks.yml is deleted in each; the four service repos run through the inputs path.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified, ready for an AFK agentFully specified, ready for an AFK agent
Activity
lesnik512 commentedon Sep 12, 2026
Input from #91 (adding
3.14tto the per-repo_checks.yml): the derived matrix needs two per-entry knobs that the shared workflow has to expose, otherwise two repos go red the day it switches on.db-retrysetsDISABLE_SQLALCHEMY_CEXT_RUNTIME=1on3.14t(SQLAlchemy 2.0.x cyext re-enables the GIL; fixed upstream for 2.1),faststream-concurrent-aiokafkasetsAIOKAFKA_NO_EXTENSIONS=1(no cp314t wheel; the C codecs re-enable the GIL). Both use${{ matrix.python-version == '3.14t' && '1' || '' }}today, so anenvinput (or afree-threaded-envmap) that the workflow spreads onto the pytest job covers it.modern-di-arq(hiredis, free-threading support redis/hiredis-py#229) andmodern-di-grpc(grpcio, Support no-GIL (free-threaded) Python grpc/grpc#38762) cannot keep the GIL disabled because of a dependency and carry exemption rows on the standard. A boolean input likefree-threaded: falseis the minimum; the exemption row is the record that justifies setting it.Also worth carrying over: the
3.14tentry in every migrated repo runspython -c "import sys, <package>; assert not sys._is_gil_enabled()"before the suite. Pytest only emits a RuntimeWarning when an import re-enables the GIL, so without that step a GIL-enabled run still goes green.lesnik512 commentedon Sep 15, 2026
Closing without migrating. #101 built the workflow as designed and db-retry#46 proved it end to end from a branch ref, including the service-container path. The decision is against it, on the shape of the interface rather than on whether it works.
Why not
workflow_callinputs are scalars. Anything structured a repo varies, a service container or an env map, has to be flattened into a string: first a health command plus a baked-inPOSTGRES_PASSWORD, then rawdocker createoptions. Both are image knowledge leaking into the org repo, and neither reads well. That is a GitHub limit, not a design slip, so it does not go away with better input names.What sharing buys is real but bounded: the run-time matrix (the only part section 6 needs) and one-PR policy changes instead of a per-repo sweep. Sweeps are how the org already works, so that saving does not pay for the interface.
The idea, if this is ever reopened
A reusable workflow with zero inputs, everything read from the repo:
just services-upwhenjust --summarylists it; the recipe isdocker compose up -d --wait <service>, so image, env and healthcheck stay in the compose file the repo already keeps for local dev (modern-di-arq has this today asredis-up)Free Threadingclassifier section 11 requires; today exactly the two exempt repos lack itdocs-buildDISABLE_SQLALCHEMY_CEXT_RUNTIME,AIOKAFKA_NO_EXTENSIONS): exported bytest-ciwhen the interpreter reports the GIL disabledEvery caller is then the same two lines. The matrix script and its tests in #101 are the reusable part of that work.
Section 7 of the standard still says the shared
checks.yml"will live" here; that sentence needs its own change now.