From d0307267836cc8b0b9fdbbf89745daa118f03562 Mon Sep 17 00:00:00 2001 From: "Josef M. Gallmetzer" <64498081+galjos@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:18:06 +0200 Subject: [PATCH 1/2] Automate release notes and document the release process - .github/release.yml: group auto-generated release notes (from `gh release create --generate-notes`) by PR label; unlabelled PRs fall under "Other Changes"; exclude bots. - RELEASING.md: document the one-command release flow (tag a GitHub Release -> publish.yml builds + publishes to PyPI via Trusted Publishing), the setuptools_scm versioning, and the trusted-publisher config. Keeps the release trigger manual (deliberate cadence + version control) while removing the note-writing toil. --- .github/release.yml | 30 ++++++++++++++++++++++++++++++ RELEASING.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 .github/release.yml create mode 100644 RELEASING.md diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..4445b7a --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,30 @@ +# Configuration for GitHub's auto-generated release notes +# (used by `gh release create --generate-notes` and the "Generate release notes" +# button). Merged pull requests are grouped by label; unlabelled PRs fall into +# "Other Changes". +changelog: + exclude: + labels: + - no-changelog + authors: + - dependabot + - github-actions + categories: + - title: Features + labels: + - enhancement + - feature + - title: Fixes + labels: + - bug + - fix + - title: Documentation + labels: + - documentation + - docs + - title: Dependencies + labels: + - dependencies + - title: Other Changes + labels: + - "*" diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..7865dc5 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,44 @@ +# Releasing + +Releases are published to PyPI automatically when a GitHub Release is created — +there is no manual upload step and no stored API token. + +## Cut a release + +1. Make sure `main` is green and contains everything for the release. +2. Create a GitHub Release with a semantic-version tag (the leading `v` is + stripped by `setuptools_scm`, so `v0.2.0` becomes version `0.2.0`): + + ```bash + gh release create v0.2.0 --generate-notes + ``` + + `--generate-notes` fills the body from the merged pull requests, grouped by + label according to [`.github/release.yml`](.github/release.yml). Review and + edit the notes, then publish the release. +3. Publishing the release triggers + [`.github/workflows/publish.yml`](.github/workflows/publish.yml), which builds + the sdist + wheel and uploads them to PyPI via + [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC). + +## Versioning + +- The version is derived from the git tag by `setuptools_scm`; never hardcode a + version in `pyproject.toml`. +- Between releases the version is a development version (e.g. + `0.2.0.dev5+g`), a PEP 440 *local* version that PyPI rejects — so only a + tagged release can be published (a built-in safety net against accidental + uploads). + +## Notes + +- Label pull requests (`enhancement`, `bug`, `documentation`, `dependencies`, + ...) so the generated notes are grouped; unlabelled PRs still appear under + **Other Changes**. +- The PyPI trusted publisher is configured for the project `thermoscreening` + (owner `MolarVerse`, repository `ThermoScreening`, workflow `publish.yml`, no + environment). If a release's publish job fails with `invalid-publisher`, these + four values on PyPI must match the workflow. +- To publish **conda-forge** as well (the channel that also pulls the DFTB+ / + xtb / tblite backends), `PQAnalysis` first needs to be available on + conda-forge; then submit a recipe via `staged-recipes`. From 3710215cd6bd82d6b016617d8a9cb2883378d9c6 Mon Sep 17 00:00:00 2001 From: "Josef M. Gallmetzer" <64498081+galjos@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:21:28 +0200 Subject: [PATCH 2/2] Address review: use [bot] author logins and fix dev-version example - .github/release.yml: exclude dependabot[bot]/github-actions[bot] (the real bot logins carry the [bot] suffix; without it the exclusion is inert). - RELEASING.md: setuptools_scm guess-next-dev bumps the patch, so the between- releases example is 0.2.1.dev5+g (after v0.2.0), not 0.2.0.dev5. --- .github/release.yml | 4 ++-- RELEASING.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/release.yml b/.github/release.yml index 4445b7a..42979b7 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -7,8 +7,8 @@ changelog: labels: - no-changelog authors: - - dependabot - - github-actions + - dependabot[bot] + - github-actions[bot] categories: - title: Features labels: diff --git a/RELEASING.md b/RELEASING.md index 7865dc5..ce2f54a 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -25,8 +25,8 @@ there is no manual upload step and no stored API token. - The version is derived from the git tag by `setuptools_scm`; never hardcode a version in `pyproject.toml`. -- Between releases the version is a development version (e.g. - `0.2.0.dev5+g`), a PEP 440 *local* version that PyPI rejects — so only a +- Between releases the version is a development version (e.g. after `v0.2.0`, + `0.2.1.dev5+g`), a PEP 440 *local* version that PyPI rejects — so only a tagged release can be published (a built-in safety net against accidental uploads).