Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ Entries for 1.0.0 through 1.5.2 were backfilled from git history after the fact,

<!-- scriv-insert-here -->

## [1.10.0] - 2026-10-03

Releases are automated, through two reusable workflows that generated projects call from thin `@v1` callers. Run "Prepare release" from the Actions tab, approve the CI on the pull request it opens, and merge. The merge tags the release and creates the GitHub release, and a library on PyPI is then published. Libraries now build with `uv_build`, with the version set once in `pyproject.toml`. Every project needs one repository setting and `copier update --trust`, and libraries should check their version and wheel after updating; see Upgrading.

### Added
Comment thread
MattFisher marked this conversation as resolved.

- Automated releases. Run **Prepare release** from the Actions tab: it bumps `version` in `pyproject.toml` with `uv version --bump`, collects `changelog.d/` into `CHANGELOG.md`, and opens a "Release vX.Y.Z" pull request. Approve its CI and merge it, and **Release on merge** tags the merge commit, creates the GitHub release from the changelog section, and, for a library published to PyPI, starts `publish.yml`. The `auto` bump picks minor when a fragment adds, changes, deprecates or removes something, and patch when fragments only fix; it never picks major.
- The steps live in two reusable workflows in this repo, `prepare-release.yml` and `release-on-merge.yml`, and generated projects get thin callers pinned to `@v1`, as with `python-ci.yml`. Release fixes reach every project when `v1` moves, without a `copier update`.
- The safeguards: Prepare release refuses a run from another branch, with no fragments, with a fragment that has entries but no category heading or that quotes a scriv marker (scriv would silently drop the lines above it), with an existing tag, or with a release pull request already open, and is safe to re-run after a failure. Release on merge checks that `pyproject.toml` at the merge commit agrees with the release branch, refuses a tag already on another commit, and skips a tag or release that already exists, so it can be re-run. Its concurrency group is keyed on the branch, so an unrelated pull request closing can't cancel a pending release run.
- `publish.yml` takes a `workflow_dispatch` trigger, so Release on merge can start it. A tag created with the default Actions token triggers no workflows, and PyPI trusted publishing can't run from a reusable workflow, so the dispatched run is still `publish.yml`, the workflow the trusted publisher names. It refuses any ref but a `v*` tag, fails if the tag doesn't match the built wheel's version, and moves to checkout 7.0.1 and setup-uv 10.0.1.
- This template releases itself with the same reusable workflows, in a mode that takes the version from the latest `vX.Y.Z` tag, so every template release exercises them before `v1` moves. Its own changelog is now scriv fragments too, and `bump-v1.yml` can be started on a tag as well as by a published release. Started that way, it refuses anything but the newest final `v1.X.Y` tag, so `v1` only moves forward.

### Changed

- Libraries build with uv's own backend, `uv_build`, instead of hatchling, and keep a static `version` in `pyproject.toml`, so `uv version --bump` manages it. `__version__` reads it back from the installed package metadata (`"unknown"` in a source tree that was never installed). hatchling was there to read the version from `__init__.py`, which uv can't bump; with the version in `pyproject.toml` it isn't needed. `[tool.scriv]` reads the version from `pyproject.toml` for every project kind. MIT projects set `license-files = ["LICENSE"]`, since uv_build ships only the license files it is told about.

### Upgrading

- A manual `copier update` across 1.10.0 needs `--trust`, because the template now runs a migration. Without it copier stops with `Template uses potentially unsafe feature: migrations.` and changes nothing, for apps as well as libraries. The weekly template-update workflow already passes it.
- Turn on _Settings → Actions → General_ → **Allow GitHub Actions to create and approve pull requests**, or Prepare release fails when it opens the pull request. The weekly template-update workflow needs the same setting. CI on each release pull request then starts once you click **Approve workflows to run** on it.
- For a library, `copier update` changes `pyproject.toml` to uv_build and a static `version`, and a migration then sets that `version` to the `__version__` the project's `__init__.py` had before the update. Without it the template's `0.1.0` would merge in silently. Check `uv version --short` before merging the update. `__init__.py` itself conflicts: keep the template's metadata lookup, plus any other code the file had.
- For a library, check that the wheel's contents don't change: uv_build expects the package under `src/<package>/`, and any hatch build options (includes, excludes, force-include) need their `[tool.uv.build-backend]` equivalents.
- No PyPI change is needed. The trusted publisher still names `publish.yml`. A project that publishes from a differently named workflow should rename it to `publish.yml` and update the publisher.

## [1.9.1] - 2026-10-02

Repairs 1.9.0, which was tagged before `CHANGELOG.md` had a `[1.9.0]` section. `bump-v1.yml` refuses a release it can't find described, so it left `v1` on 1.8.1 and the 1.9.0 tag lightweight. Consumers land on 1.9.1 rather than 1.9.0; the contents are the same bar this changelog.
Expand Down Expand Up @@ -203,4 +227,5 @@ The largest release so far: an optional TypeScript side, automated template upda
[1.8.1]: https://github.com/MattFisher/python-project-template/compare/v1.8.0...v1.8.1
[1.9.0]: https://github.com/Generality-Labs/python-project-template/compare/v1.8.1...v1.9.0
[1.9.1]: https://github.com/Generality-Labs/python-project-template/compare/v1.9.0...v1.9.1
[unreleased]: https://github.com/Generality-Labs/python-project-template/compare/v1.9.1...HEAD
[1.10.0]: https://github.com/Generality-Labs/python-project-template/compare/v1.9.1...v1.10.0
[unreleased]: https://github.com/Generality-Labs/python-project-template/compare/v1.10.0...HEAD
19 changes: 0 additions & 19 deletions changelog.d/20261002_000000_release_workflows.md

This file was deleted.

Loading