Skip to content

👷 ci(release): move releases to shared workflows - #637

Merged
gaborbernat merged 1 commit into
mainfrom
fix/release-contract
Oct 27, 2026
Merged

gaborbernat merged 1 commit into
mainfrom
fix/release-contract

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

platformdirs releases now run on the shared tox-dev/github-workflows 6.0.1 pipeline and release-creator 4.1.0, so this repo stops carrying its own scripts for version bumping, changelog assembly, release notes and tag pushing. 🚀 Changelog readers get user-facing categories (Added, Fixed, Packaging and so on), a stable anchor for each release and category, and a credit line on every entry. The whole history back to v2.0.0a1 is rewritten into that shape, with maintenance-only entries dropped.

Contributors write a fragment that holds only the change. The new CONTRIBUTING section explains that the news check rejects a hand-written PR number or credit, and that release preparation links each fragment to its squash-merged PR, credits the authors and co-authors of the merge commit, and runs release-creator contributors to add a New Contributors subsection. The news check moves into its own workflow, so adding or removing the skip news label reruns that check alone instead of the whole test matrix.

Architecture

A release starts with one dispatch of the shared Towncrier prepare workflow, which assembles the changelog and pushes the release commit and tag with the release App's token. On the tag, the shared validate-python-release workflow builds the distributions while a read-only job renders the GitHub Release body from the changelog. PyPI publishing uses OIDC; a verify job then checks the files on PyPI against the built ones, and only after that does the last job create the GitHub Release in a single call. Jobs hand distributions and notes to each other by artifact ID.

flowchart LR
    Prepare[Prepare release<br/>commit + tag] --> Build[Build distributions]
    Prepare --> Notes[Render release notes]
    Build --> PyPI[Publish to PyPI]
    Notes --> PyPI
    PyPI --> Verify[Verify PyPI files]
    Verify --> GH[GitHub Release]
    Notes --> GH
    classDef shared fill:#cfe4ff,stroke:#1f6feb,color:#0b1f3a;
    classDef publish fill:#ffe3a3,stroke:#d29200,color:#3a2c00;
    class Prepare,Build,Notes,Verify shared;
    class PyPI,GH publish;
Loading

The workflows trust people with write access and validate their work when a PR merges. This repo drops the tag-time guard that refused to publish a version missing from the changelog, and the PyPI upload no longer skips files that already exist. PR-time checks stay, and the shared action runs the fragment check and the lock check only when the PR touches the files they validate.

Dependencies and packaging

🔒 nab now writes pylock.toml from the [tool.nab] table: universal mode, a seven-day upload cutoff, CPython 3.15 on Linux x86_64. A temporary per-package cutoff lets release-creator 4.1.0 in before its seven days pass. A build group locks the hatchling backend with Cython and setuptools, since PyYAML 6.0.3 ships no CPython 3.15 wheel. Release jobs install their tools from that lock through per-job groups, and a weekly workflow opens a PR that relocks pylock.toml. Test, type and docs CI still resolve current dependencies.

Hook updates come from Dependabot's pre-commit ecosystem weekly with a seven-day cooldown, and pre-commit.ci autoupdate drops to quarterly. Hook revisions are frozen to commit SHAs, and mdformat runs from its upstream repo with pinned plugins. On PyPI, hatch-fancy-pypi-readme renders the project description, the metadata declares import-names, and the license classifier goes in favor of the existing license = "MIT" expression, as PEP 639 asks. CI moves to the windows-2025-vs2026, macos-26 and ubuntu-26.04 runners, and every workflow, job and step name starts with an emoji.

🛡️ CodeQL

CodeQL moves from default setup to a committed workflow on ubuntu-26.04 with the same languages (actions, python), now on the security-extended suite with tests ignored, which removes the ubuntu-latest migration notice default setup produces.

@gaborbernat gaborbernat added documentation Improvements or additions to documentation enhancement New feature or request skip news No news fragment needed labels Oct 20, 2026
@gaborbernat gaborbernat changed the title 👷 ci(release): unify preparation and history 👷 ci: unify release preparation Oct 20, 2026
@gaborbernat
gaborbernat force-pushed the fix/release-contract branch 8 times, most recently from 0aba430 to dd2b4d3 Compare October 26, 2026 20:58
@gaborbernat gaborbernat changed the title 👷 ci: unify release preparation 👷 ci(release): move releases to shared workflows Oct 26, 2026
@gaborbernat
gaborbernat force-pushed the fix/release-contract branch 4 times, most recently from d11f37f to 457838e Compare October 27, 2026 01:58
Move releases to the shared github-workflows 6.0.1 pipeline and
release-creator 4.1.0. Preparation, App-authored commits and tags,
distribution builds and release notes come from the shared Actions. The
Sphinx changelog gets user-facing categories, stable release anchors and
credits from commit authors and co-authors, and the PyPI description is
rendered by hatch-fancy-pypi-readme. CONTRIBUTING explains that fragments
carry no hand-written credit and that prepare runs release-creator
contributors.

The tag workflow builds the distributions in parallel with a read-only notes
job, uploads to PyPI through OIDC, verifies the published digests and creates
the GitHub Release with one call. Only writers can push or move tags, so the
step that re-checked the tag before the GitHub Release is gone, as is the
always-true pull_request condition on the news job. Distributions and notes
pass between jobs by artifact ID. Tag runs never cancel; pull request and
branch runs do.

Nab writes pylock.toml from a [tool.nab] table, with a temporary upload
cutoff exception for release-creator 4.1.0. A build group locks the
hatchling backend with Cython and setuptools, because PyYAML has no
CPython 3.15 wheel. The release-check group and the release-validate group,
used only by the shared prepare validate job that 6.0.0 removed, go.

Dependabot's pre-commit ecosystem and pre-commit.ci's quarterly autoupdate
own hook updates, so the hook cooldown check and the managed hook pins go.

Every workflow, job and step name starts with an emoji, which renames the
required checks "Required checks pass" and "📦 build".

CodeQL moves from default setup to a committed advanced workflow on
ubuntu-26.04 with the same languages, now running the security-extended
suite and skipping tests.
@gaborbernat
gaborbernat marked this pull request as ready for review October 27, 2026 05:39
@gaborbernat
gaborbernat requested a review from ofek as a code owner October 27, 2026 05:39
@gaborbernat
gaborbernat merged commit 8d8cc48 into main Oct 27, 2026
41 checks passed
@gaborbernat
gaborbernat deleted the fix/release-contract branch October 27, 2026 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request skip news No news fragment needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants