diff --git a/README.md b/README.md index bd57493..33ccbc0 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ first time is by hand; `copier update` takes over from then on. | Docstrings | NumPy style, [docstr-coverage](https://github.com/HunterMcGushion/docstr_coverage) ≥ 95% | | Docs | Sphinx + PyData theme, pandas-style API pages (a page per class, with tables of its attributes and methods, and a page per member), copy buttons, examples that run when the docs build (matplotlib's `.. plot::` in docstrings, IPython's `.. ipython::` in `.rst` pages, and with `docs_notebooks`, notebooks and code cells in Markdown pages), live preview (`just docs-serve`), built with warnings as errors; versioned on GitHub Pages (`dev/`, one folder per release, `stable/`) with a version dropdown | | pre-commit | pre-commit-hooks, rST checks, validate-pyproject, [zizmor](https://docs.zizmor.sh); `uv lock`, ruff and pyrefly run from `.venv`, so `uv.lock` pins their versions | -| Changelog | Keep a Changelog, hand-edited; `just changelog` drafts entries from Conventional Commits ([git-cliff](https://git-cliff.org)) | +| Changelog | Keep a Changelog, written at release (pull requests leave it alone): `just changelog` drafts the entries from Conventional Commits ([git-cliff](https://git-cliff.org)) | | CI | Tests (the chosen operating systems × all supported Pythons), Code Quality, Documentation, Publish (tag push → PyPI trusted publishing with attestations → GitHub Release from CHANGELOG → Zenodo) | | Upkeep | Dependabot for actions, pre-commit hooks and `uv.lock` (monthly, grouped, 7-day cooldown; never raises minimum versions); a monthly workflow runs `uv lock --upgrade` and opens a pull request when the lock changes, so the newest release for each supported Python gets tested | | Project files | AGENTS.md, CONTRIBUTING.md, CHANGELOG.md, CITATION.cff, `.zenodo.json`, issue forms, PR template | diff --git a/template/.github/pull_request_template.md b/template/.github/pull_request_template.md index 7552fe0..da78bad 100644 --- a/template/.github/pull_request_template.md +++ b/template/.github/pull_request_template.md @@ -7,4 +7,3 @@ - [ ] Tests added or updated - [ ] `just quality-check` passes (lint, type check, docstrings, tests) - [ ] Docs updated for any public API change (`just build-docs` has no warnings) -- [ ] `CHANGELOG.md` entry under `## [Unreleased]` diff --git a/template/AGENTS.md.jinja b/template/AGENTS.md.jinja index 5dbcaff..dd4e016 100644 --- a/template/AGENTS.md.jinja +++ b/template/AGENTS.md.jinja @@ -41,7 +41,7 @@ runs the same recipes. | Live docs preview | `just docs-serve` (port 8000) | | All pre-commit hooks | `just pre-commit` | | Build and check dists | `just dist` | -| Draft changelog entries | `just changelog` | +| Draft the changelog entries (at release) | `just changelog` | After editing dependencies in `pyproject.toml`, run `uv lock` and commit `uv.lock` in the same commit. @@ -185,9 +185,10 @@ when one breaks. - Commit messages follow Conventional Commits (`fix(io): ...`, `docs: ...`), with `!` for breaking changes (`feat!: ...`). -- User-visible changes go under `## [Unreleased]` in `CHANGELOG.md`, which follows - [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `just changelog` - drafts entries from commit messages (`cliff.toml`); the entries are edited by hand. +- A pull request leaves `CHANGELOG.md` alone. At release, `just changelog` drafts + the entries from the commit messages (`cliff.toml`) and the maintainer edits them + into `CHANGELOG.md`, which follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + So write each commit message as the line a user would read. - Docs are versioned on GitHub Pages, which serves the gh-pages branch (`dev/`, one folder per release, `stable/`); `.github/scripts/docs_versions.py` maintains the branch. Never edit gh-pages by hand. diff --git a/template/CHANGELOG.md b/template/CHANGELOG.md index 9fa38ac..e699aa7 100644 --- a/template/CHANGELOG.md +++ b/template/CHANGELOG.md @@ -2,6 +2,7 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), and versions -follow [PEP 440](https://peps.python.org/pep-0440/). +follow [PEP 440](https://peps.python.org/pep-0440/). Pull requests leave this +file alone: the entries are written at release (`just changelog` drafts them). ## [Unreleased] diff --git a/template/CONTRIBUTING.md.jinja b/template/CONTRIBUTING.md.jinja index 1a9d89e..eb59211 100644 --- a/template/CONTRIBUTING.md.jinja +++ b/template/CONTRIBUTING.md.jinja @@ -34,7 +34,7 @@ shows them all). | `just format` | fix lint and format the code with ruff | | `just build-docs` | build the HTML docs into `docs/_build/`, running every example; warnings are errors | | `just docs-serve` | preview the docs at , rebuilt on every save (on a remote machine, forward the port, e.g. VS Code's Ports panel) | -| `just changelog` | draft CHANGELOG entries from the commits since the last release | +| `just changelog` | draft CHANGELOG entries from the commits since the last release (run at release) | | `just pre-commit` | run every hook on every file | After changing dependencies in `pyproject.toml`, run `just lock` (the @@ -44,22 +44,22 @@ After changing dependencies in `pyproject.toml`, run `just lock` (the 1. Branch from `main`. 2. Make the change, with tests and NumPy-style docstrings. -3. Add a line under `## [Unreleased]` in [CHANGELOG.md](CHANGELOG.md) for - anything a user would notice. -4. Commit with a [Conventional Commits](https://www.conventionalcommits.org/) +3. Commit with a [Conventional Commits](https://www.conventionalcommits.org/) message, e.g. `fix(io): read files with a BOM` or `feat!: ...` for a - breaking change. -5. Open a pull request. Link the issue it addresses ("Fixes #12"). + breaking change. Leave [CHANGELOG.md](CHANGELOG.md) alone: the release notes + are drafted from these messages when the maintainer releases. +4. Open a pull request. Link the issue it addresses ("Fixes #12"). ## Releasing The version comes from git tags, through setuptools-scm, so there is no version string to bump. -1. Run `just changelog` to draft the entries from your commit messages, edit - them into `CHANGELOG.md` under `## [Unreleased]`, then rename that heading - to `## [X.Y.Z] - YYYY-MM-DD` and start a new empty `## [Unreleased]` above - it. Commit (`chore(release): X.Y.Z`) and push to `main`. +1. Write the changelog: `just changelog` drafts the entries from the commit + messages since the last release. Edit them into `CHANGELOG.md` under + `## [Unreleased]`, then rename that heading to `## [X.Y.Z] - YYYY-MM-DD` and + start a new empty `## [Unreleased]` above it. Commit (`chore(release): X.Y.Z`) + and push to `main`. 2. Run `just release X.Y.Z`. It checks that the tree is clean, that `main` is in sync with GitHub, and that the version is newer than every existing tag, then pushes the tag `vX.Y.Z`. diff --git a/template/justfile.jinja b/template/justfile.jinja index ce5f7f1..5df2b04 100644 --- a/template/justfile.jinja +++ b/template/justfile.jinja @@ -62,7 +62,7 @@ dist: uv build uv run twine check --strict dist/* -# Draft CHANGELOG entries from the commits since the last release +# At release, draft the CHANGELOG entries from the commits since the last release changelog: @uv run git-cliff --unreleased --strip all