Repository navigation
👷 ci(release): move releases to shared workflows - #282
Draft
gaborbernat wants to merge 1 commit into
Draft
gaborbernat wants to merge 1 commit into
gaborbernat wants to merge 1 commit into
Conversation
gaborbernat
force-pushed
the
fix/release-contract
branch
8 times, most recently
from
October 26, 2026 20:58
4eae918 to
ab94427
Compare
gaborbernat
force-pushed
the
fix/release-contract
branch
3 times, most recently
from
October 26, 2026 23:40
950f755 to
e96cf71
Compare
Move pytest-env to the github-workflows 6.0.1 release path with release-creator 4.1.0. A news check validates changelog fragments on PRs, running each check only when the PR touches its files. Preparation runs the shared Towncrier workflow, and a weekly job refreshes the release lock. The tag workflow builds through validate-python-release while a read-only notes job renders the release notes. PyPI uploads through OIDC without skip-existing, then one job verifies the published digests and creates the GitHub Release. The workflow runs under a per-tag concurrency group. Writers are trusted, so checks that only re-validate their actions go: the tag re-check before the GitHub Release, the redundant pull_request condition on the news job, and the release-validate group. Every job and step gets an emoji name; the gate becomes "🚦 Required checks pass" and the news job "📝 News fragment", so the ruleset needs the new check names before merge. Nab writes pylock.toml for every group from a [tool.nab] table, with a temporary upload cutoff exception for release-creator 4.1.0. A build group locks the hatchling backends with Cython and setuptools, because PyYAML has no CPython 3.15 wheel. The unused release, release-check and release-validate groups are gone. Dependabot's pre-commit ecosystem and pre-commit.ci's quarterly autoupdate handle hook updates, so there is no hook cooldown check. CONTRIBUTING explains that credits come from commit authors and co-authors and that preparation runs release-creator contributors. The changelog is backfilled for every PyPI version, and the package metadata and PyPI README links are fixed. CodeQL moves from default setup to a committed advanced workflow on ubuntu-26.04, scanning Actions and Python with security-extended and ignoring tests.
gaborbernat
force-pushed
the
fix/release-contract
branch
from
October 26, 2026 23:40
e96cf71 to
03509f3
Compare
This branch has not been deployed
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.
pytest-env's releases ran on two hand-written workflows of 89 lines each, mostly inline bash: one picked the next version, stitched fragments into
CHANGELOG.mdand pushed the tag, the other built, uploaded and wrote the GitHub Release. This PR hands that work to tox-dev/github-workflows 6.0.1 and release-creator 4.1.0. 🚀 Maintainers can now dispatch withautoand get the bump from the fragments, write named fragments in ten categories, and get pull request links, author credits and a New Contributors list in the release notes.Architecture
Pull requests run the shared
validate-newscheck as 📝 News fragment. A human PR needs a fragment or theskip newslabel, the check waives bot PRs, and it validates every fragment a PR adds. Following the 6.0.0 change, the fragment, Towncrier config and lock checks run only when the PR touches what they validate; the fragment requirement runs on every PR. The test workflow keeps only the test matrix behind 🚦 Required checks pass.A manual dispatch calls the shared prepare workflow. Its first job holds no write credentials: Towncrier builds the changelog and
release-creatorlinks each fragment to its pull request, credits the commit authors and co-authors, and adds new contributors. A second job in therelease-authenvironment mints a token for the repository's GitHub App and pushes the release commit and tag. A weekly job, Tuesdays at 08:00 UTC, refreshes the release-tool lock through the same App.The tag run splits into four jobs under a per-tag concurrency group. The shared build produces the distributions while a read-only job renders the GitHub Release notes from
CHANGELOG.md. PyPI publishing keeps trusted publishing with attestations in thereleaseenvironment. The last job compares the local files with what PyPI now serves and only then creates the GitHub Release. 🔐 That digest check stays because it guards an external store.flowchart LR PR[Pull request] --> News[📝 News fragment] Dispatch[Manual dispatch] --> Assemble[Assemble changelog<br/>read-only] Assemble --> Push[Push commit and tag<br/>release App] Push --> Build[🏗️ Build] Push --> Notes[📝 Render notes] Build --> PyPI[🚀 Publish to PyPI] Notes --> PyPI PyPI --> GHR[🚀 Publish GitHub Release<br/>after digest check] classDef pr fill:#d8ecd8,stroke:#2f8132,color:#0f2a10; classDef write fill:#ffe3a3,stroke:#d29200,color:#3a2c00; classDef read fill:#cfe4ff,stroke:#1f6feb,color:#0b1f3a; class PR,News pr; class Dispatch,Assemble,Build,Notes read; class Push,PyPI,GHR write;We trust people with write access, so the checks that only re-validated their own actions outside a pull request are gone: the tag-time lookup of a matching changelog heading, the check that the built files carry the tag's version, and prepare's refusals to bump to an existing tag or to release malformed or empty fragments. github-workflows 6.0.0 drops the matching shared checks (tag identity, the tag-time lock job, artifact shape, and prepare's re-validation of its own patch). PR-time checks still run.
Dependencies and packaging
The release tools install from a
pylock.tomlthat Nab generates for every dependency group on CPython 3.15linux_x86_64, the platform the release jobs run on, and thefix,pkg_metaandtypetox environments now install from dependency groups too. The release groups requirerelease-creator4.1, and a temporaryuploaded-prior-toexception admits 4.1.0, uploaded 2026-10-26, ahead of the seven-day cutoff; it is marked for deletion after 2026-11-02.PyYAML 6.0.3 has no CPython 3.15 wheel, so the lock carries its sdist and a
buildgroup locks Cython and setuptools alongside the hatchling plugins. Hook updates move to Dependabot'spre-commitecosystem on Tuesdays with a seven-day cooldown and theskip newslabel, hook revisions are pinned to frozen commit SHAs, and pre-commit.ci autoupdates quarterly.CHANGELOG.mdnow covers all 29 PyPI versions with user-facing categories, stable anchors and human credits. PyPI lists 0.5, 0.5.1, 0.6.0 and 0.6.1, which have no tag in the repository, so their entries link the version commits. 📝 The package metadata gains an SPDXMITlicense expression,import-names, theFramework :: PytestandTopic :: Software Development :: Testingclassifiers and a new summary, and the README's links toCHANGELOG.mdand the newCONTRIBUTING.mdnow point to GitHub on PyPI.Rollout
release-authenvironment, which deploys frommainonly. A pytest-dev administrator still needs to install the release App on this repository and add it as a bypass actor to themainruleset (1973547), which today lets only the repository admin role bypass, so the prepare job can push tomain.swap_required_checks.py pytest-dev/pytest-env 282 --applyto point ruleset 1973547 at the renamed checks:Required checks passbecomes🚦 Required checks passandchangelogbecomes📝 News fragment;pre-commit.ci - prstays.🛡️ CodeQL
CodeQL moves from default setup to a committed workflow on
ubuntu-26.04scanning Actions and Python with thesecurity-extendedsuite and ignoringtests, which removes theubuntu-latestmigration notice default setup produces. GitHub rejects advanced-setup results while default setup is on, so the🛡️ Analyzejobs fail until default setup is turned off for this repository; that happens right before merging (switch_codeql.sh pytest-dev/pytest-env 282 --apply).