diff --git a/project_templates/fastapi_safir_app/example/CHANGELOG.md b/project_templates/fastapi_safir_app/example/CHANGELOG.md new file mode 100644 index 00000000..0c65db25 --- /dev/null +++ b/project_templates/fastapi_safir_app/example/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change log + +All notable changes to example will be documented in this file. + +Versioning follows [semver](https://semver.org/). + +Dependencies are updated to the latest available version during each release. Those changes are not noted here explicitly. + +This project uses [scriv](https://scriv.readthedocs.io/en/stable/) to maintain the change log. +Changes for the upcoming release can be found in [changelog.d](https://github.com/lsst-sqre/example/tree/main/changelog.d/). + + diff --git a/project_templates/fastapi_safir_app/example/changelog.d/_template.md.jinja b/project_templates/fastapi_safir_app/example/changelog.d/_template.md.jinja new file mode 100644 index 00000000..6e644b85 --- /dev/null +++ b/project_templates/fastapi_safir_app/example/changelog.d/_template.md.jinja @@ -0,0 +1,7 @@ + +{%- for cat in config.categories %} + +### {{ cat }} + +- +{%- endfor %} diff --git a/project_templates/fastapi_safir_app/example/pyproject.toml b/project_templates/fastapi_safir_app/example/pyproject.toml index c885cbc0..dcb327b8 100644 --- a/project_templates/fastapi_safir_app/example/pyproject.toml +++ b/project_templates/fastapi_safir_app/example/pyproject.toml @@ -207,3 +207,16 @@ classmethod-decorators = [ [tool.ruff.pydocstyle] convention = "numpy" + +[tool.scriv] +categories = [ + "Backwards-incompatible changes", + "New features", + "Bug fixes", + "Other changes", +] +entry_title_template = "{{ version }} ({{ date.strftime('%Y-%m-%d') }})" +format = "md" +md_header_level = "2" +new_fragment_template = "file:changelog.d/_template.md.jinja" +skip_fragments = "_template.md.jinja" diff --git a/project_templates/fastapi_safir_app/{{cookiecutter.name}}/CHANGELOG.md b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/CHANGELOG.md new file mode 100644 index 00000000..f2e08aca --- /dev/null +++ b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change log + +All notable changes to {{cookiecutter.name}} will be documented in this file. + +Versioning follows [semver](https://semver.org/). + +Dependencies are updated to the latest available version during each release. Those changes are not noted here explicitly. + +This project uses [scriv](https://scriv.readthedocs.io/en/stable/) to maintain the change log. +Changes for the upcoming release can be found in [changelog.d](https://github.com/{{cookiecutter.github_org}}/{{cookiecutter.name}}/tree/main/changelog.d/). + + diff --git a/project_templates/fastapi_safir_app/{{cookiecutter.name}}/changelog.d/_template.md.jinja b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/changelog.d/_template.md.jinja new file mode 100644 index 00000000..aabf509f --- /dev/null +++ b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/changelog.d/_template.md.jinja @@ -0,0 +1,7 @@ + +{{ "{%- for cat in config.categories %}" }} + +### {{ "{{ cat }}" }} + +- +{{ "{%- endfor %}" }} diff --git a/project_templates/fastapi_safir_app/{{cookiecutter.name}}/pyproject.toml b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/pyproject.toml index 7942f1ce..3f46d2f9 100644 --- a/project_templates/fastapi_safir_app/{{cookiecutter.name}}/pyproject.toml +++ b/project_templates/fastapi_safir_app/{{cookiecutter.name}}/pyproject.toml @@ -207,3 +207,16 @@ classmethod-decorators = [ [tool.ruff.pydocstyle] convention = "numpy" + +[tool.scriv] +categories = [ + "Backwards-incompatible changes", + "New features", + "Bug fixes", + "Other changes", +] +entry_title_template = "{{ "{{ version }} ({{ date.strftime('%Y-%m-%d') }})" }}" +format = "md" +md_header_level = "2" +new_fragment_template = "file:changelog.d/_template.md.jinja" +skip_fragments = "_template.md.jinja" diff --git a/project_templates/square_pypi_package/example/CHANGELOG.md b/project_templates/square_pypi_package/example/CHANGELOG.md index 28b0f3cd..0c65db25 100644 --- a/project_templates/square_pypi_package/example/CHANGELOG.md +++ b/project_templates/square_pypi_package/example/CHANGELOG.md @@ -1,7 +1,12 @@ # Change log - +All notable changes to example will be documented in this file. -## Unreleased +Versioning follows [semver](https://semver.org/). -- First release of example +Dependencies are updated to the latest available version during each release. Those changes are not noted here explicitly. + +This project uses [scriv](https://scriv.readthedocs.io/en/stable/) to maintain the change log. +Changes for the upcoming release can be found in [changelog.d](https://github.com/lsst-sqre/example/tree/main/changelog.d/). + + diff --git a/project_templates/square_pypi_package/example/changelog.d/_template.md.jinja b/project_templates/square_pypi_package/example/changelog.d/_template.md.jinja new file mode 100644 index 00000000..6e644b85 --- /dev/null +++ b/project_templates/square_pypi_package/example/changelog.d/_template.md.jinja @@ -0,0 +1,7 @@ + +{%- for cat in config.categories %} + +### {{ cat }} + +- +{%- endfor %} diff --git a/project_templates/square_pypi_package/example/docs/_rst_epilog.rst b/project_templates/square_pypi_package/example/docs/_rst_epilog.rst index eceba2f3..afd04ce1 100644 --- a/project_templates/square_pypi_package/example/docs/_rst_epilog.rst +++ b/project_templates/square_pypi_package/example/docs/_rst_epilog.rst @@ -1,6 +1,7 @@ - +.. _Click: https://click.palletsprojects.com/ .. _mypy: http://www.mypy-lang.org .. _pre-commit: https://pre-commit.com .. _pytest: https://docs.pytest.org/en/latest/ +.. _scriv: https://scriv.readthedocs.io/en/stable/ +.. _semver: https://semver.org/ .. _tox: https://tox.wiki/en/latest/ -.. _Click: https://click.palletsprojects.com/ diff --git a/project_templates/square_pypi_package/example/docs/dev/development.rst b/project_templates/square_pypi_package/example/docs/dev/development.rst index 6b1e102e..d0583012 100644 --- a/project_templates/square_pypi_package/example/docs/dev/development.rst +++ b/project_templates/square_pypi_package/example/docs/dev/development.rst @@ -101,30 +101,29 @@ The built documentation is located in the :file:`docs/_build/html` directory. Updating the change log ======================= -Each pull request should update the change log (:file:`CHANGELOG.md`). -Add a description of new features and fixes as list items under a section at the top of the change log called "Unreleased:" +example uses scriv_ to maintain its change log. -.. code-block:: md +When preparing a pull request, run :command:`scriv create`. +This will create a change log fragment in :file:`changelog.d`. +Edit that fragment, removing the sections that do not apply and adding entries fo this pull request. +You can pass the ``--edit`` flag to :command:`scriv create` to open the created fragment automatically in an editor. - ## Unreleased +Change log entries use the following sections: - - Description of the feature or fix. +.. rst-class:: compact -If the next version is known (because example's main branch is being prepared for a new major or minor version), the section may contain that version information: +- **Backward-incompatible changes** +- **New features** +- **Bug fixes** +- **Other changes** (for minor, patch-level changes that are not bug fixes, such as logging formatting changes or updates to the documentation) -.. code-block:: md +These entries will eventually be cut and pasted into the release description for the next release, so the Markdown for the change descriptions should be compatible with GitHub's Markdown conventions for the release description. +Specifically: - ## X.Y.0 (unreleased) - - - Description of the feature or fix. - -If the exact version and release date is known (:doc:`because a release is being prepared `), the section header is formatted as: - -.. code-block:: md - - ## X.Y.0 (YYYY-MM-DD) - - - Description of the feature or fix. +- Each bullet point should be entirely on one line, even if it contains multiple sentences. + This is an exception to the normal documentation convention of a newline after each sentence. + Unfortunately, GitHub interprets those newlines as hard line breaks, so they would result in an ugly release description. +- Avoid using too much complex markup, such as nested bullet lists, since the formatting in the GitHub release description may not be what you expect and manually editing it is tedious. .. _style-guide: diff --git a/project_templates/square_pypi_package/example/docs/dev/release.rst b/project_templates/square_pypi_package/example/docs/dev/release.rst index 3f393660..41d13513 100644 --- a/project_templates/square_pypi_package/example/docs/dev/release.rst +++ b/project_templates/square_pypi_package/example/docs/dev/release.rst @@ -26,11 +26,28 @@ Release tags are semantic version identifiers following the :pep:`440` specifica 1. Change log and documentation ------------------------------- -Each PR should include updates to the change log. -If the change log or documentation needs additional updates, now is the time to make those changes through the regular branch-and-PR development method against the ``main`` branch. +Change log messages for each release are accumulated using scriv_. +See :ref:`dev-change-log` in the *Developer guide* for more details. -In particular, replace the "Unreleased" section headline with the semantic version and date. -See :ref:`dev-change-log` in the *Developer guide* for details. +When it comes time to make the release, there should be a collection of change log fragments in :file:`changelog.d`. +Those fragments will make up the change log for the new release. + +Review those fragments to determine the version number of the next release. +Safir follows semver_, so follow its rules to pick the next version: + +.. rst-class:: compact + +- If there are any backward-incompatible changes, incremeent the major version number and set the other numbers to 0. +- If there are any new features, increment the minor version number and set the patch version to 0. +- Otherwise, increment the patch version number. + +Then, run ``scriv collect --version `` specifying the version number you decided on. +This will delete the fragment files and collect them into :file:`CHANGELOG.md` under an entry for the new release. +Review that entry and edit it as needed (proofread, change the order to put more important things first, etc.). +scriv will put blank lines between entries from different files. +You may wish to remove those blank lines to ensure consistent formatting by various Markdown parsers. + +Finally, create a PR from those changes and merge it before continuing with the release process. 2. GitHub release and tag ------------------------- @@ -75,7 +92,7 @@ If the release branch doesn't already exist, check out the latest patch for that Developing on a release branch ------------------------------ -Once a release branch exists, it becomes the "master" branch for patches of that major-minor version. +Once a release branch exists, it becomes the "main" branch for patches of that major-minor version. Pull requests should be based on, and merged into, the release branch. If the development on the release branch is a backport of commits on the ``main`` branch, use ``git cherry-pick`` to copy those commits into a new pull request against the release branch. diff --git a/project_templates/square_pypi_package/example/pyproject.toml b/project_templates/square_pypi_package/example/pyproject.toml index 2d01d37b..ef5b6ddd 100644 --- a/project_templates/square_pypi_package/example/pyproject.toml +++ b/project_templates/square_pypi_package/example/pyproject.toml @@ -234,3 +234,16 @@ classmethod-decorators = [ [tool.ruff.pydocstyle] convention = "numpy" + +[tool.scriv] +categories = [ + "Backwards-incompatible changes", + "New features", + "Bug fixes", + "Other changes", +] +entry_title_template = "{{ version }} ({{ date.strftime('%Y-%m-%d') }})" +format = "md" +md_header_level = "2" +new_fragment_template = "file:changelog.d/_template.md.jinja" +skip_fragments = "_template.md.jinja" diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/CHANGELOG.md b/project_templates/square_pypi_package/{{cookiecutter.name}}/CHANGELOG.md index 4551dfe6..f2e08aca 100644 --- a/project_templates/square_pypi_package/{{cookiecutter.name}}/CHANGELOG.md +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/CHANGELOG.md @@ -1,7 +1,12 @@ # Change log - +All notable changes to {{cookiecutter.name}} will be documented in this file. -## Unreleased +Versioning follows [semver](https://semver.org/). -- First release of {{cookiecutter.name}} +Dependencies are updated to the latest available version during each release. Those changes are not noted here explicitly. + +This project uses [scriv](https://scriv.readthedocs.io/en/stable/) to maintain the change log. +Changes for the upcoming release can be found in [changelog.d](https://github.com/{{cookiecutter.github_org}}/{{cookiecutter.name}}/tree/main/changelog.d/). + + diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/changelog.d/_template.md.jinja b/project_templates/square_pypi_package/{{cookiecutter.name}}/changelog.d/_template.md.jinja new file mode 100644 index 00000000..aabf509f --- /dev/null +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/changelog.d/_template.md.jinja @@ -0,0 +1,7 @@ + +{{ "{%- for cat in config.categories %}" }} + +### {{ "{{ cat }}" }} + +- +{{ "{%- endfor %}" }} diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/_rst_epilog.rst b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/_rst_epilog.rst index eceba2f3..afd04ce1 100644 --- a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/_rst_epilog.rst +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/_rst_epilog.rst @@ -1,6 +1,7 @@ - +.. _Click: https://click.palletsprojects.com/ .. _mypy: http://www.mypy-lang.org .. _pre-commit: https://pre-commit.com .. _pytest: https://docs.pytest.org/en/latest/ +.. _scriv: https://scriv.readthedocs.io/en/stable/ +.. _semver: https://semver.org/ .. _tox: https://tox.wiki/en/latest/ -.. _Click: https://click.palletsprojects.com/ diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/development.rst b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/development.rst index 6af5c7fe..c396c887 100644 --- a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/development.rst +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/development.rst @@ -101,30 +101,29 @@ The built documentation is located in the :file:`docs/_build/html` directory. Updating the change log ======================= -Each pull request should update the change log (:file:`CHANGELOG.md`). -Add a description of new features and fixes as list items under a section at the top of the change log called "Unreleased:" +{{cookiecutter.name}} uses scriv_ to maintain its change log. -.. code-block:: md +When preparing a pull request, run :command:`scriv create`. +This will create a change log fragment in :file:`changelog.d`. +Edit that fragment, removing the sections that do not apply and adding entries fo this pull request. +You can pass the ``--edit`` flag to :command:`scriv create` to open the created fragment automatically in an editor. - ## Unreleased +Change log entries use the following sections: - - Description of the feature or fix. +.. rst-class:: compact -If the next version is known (because {{cookiecutter.name}}'s main branch is being prepared for a new major or minor version), the section may contain that version information: +- **Backward-incompatible changes** +- **New features** +- **Bug fixes** +- **Other changes** (for minor, patch-level changes that are not bug fixes, such as logging formatting changes or updates to the documentation) -.. code-block:: md +These entries will eventually be cut and pasted into the release description for the next release, so the Markdown for the change descriptions should be compatible with GitHub's Markdown conventions for the release description. +Specifically: - ## X.Y.0 (unreleased) - - - Description of the feature or fix. - -If the exact version and release date is known (:doc:`because a release is being prepared `), the section header is formatted as: - -.. code-block:: md - - ## X.Y.0 (YYYY-MM-DD) - - - Description of the feature or fix. +- Each bullet point should be entirely on one line, even if it contains multiple sentences. + This is an exception to the normal documentation convention of a newline after each sentence. + Unfortunately, GitHub interprets those newlines as hard line breaks, so they would result in an ugly release description. +- Avoid using too much complex markup, such as nested bullet lists, since the formatting in the GitHub release description may not be what you expect and manually editing it is tedious. .. _style-guide: diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/release.rst b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/release.rst index 9caa7454..e50820c5 100644 --- a/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/release.rst +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/docs/dev/release.rst @@ -26,11 +26,28 @@ Release tags are semantic version identifiers following the :pep:`440` specifica 1. Change log and documentation ------------------------------- -Each PR should include updates to the change log. -If the change log or documentation needs additional updates, now is the time to make those changes through the regular branch-and-PR development method against the ``main`` branch. +Change log messages for each release are accumulated using scriv_. +See :ref:`dev-change-log` in the *Developer guide* for more details. -In particular, replace the "Unreleased" section headline with the semantic version and date. -See :ref:`dev-change-log` in the *Developer guide* for details. +When it comes time to make the release, there should be a collection of change log fragments in :file:`changelog.d`. +Those fragments will make up the change log for the new release. + +Review those fragments to determine the version number of the next release. +Safir follows semver_, so follow its rules to pick the next version: + +.. rst-class:: compact + +- If there are any backward-incompatible changes, incremeent the major version number and set the other numbers to 0. +- If there are any new features, increment the minor version number and set the patch version to 0. +- Otherwise, increment the patch version number. + +Then, run ``scriv collect --version `` specifying the version number you decided on. +This will delete the fragment files and collect them into :file:`CHANGELOG.md` under an entry for the new release. +Review that entry and edit it as needed (proofread, change the order to put more important things first, etc.). +scriv will put blank lines between entries from different files. +You may wish to remove those blank lines to ensure consistent formatting by various Markdown parsers. + +Finally, create a PR from those changes and merge it before continuing with the release process. 2. GitHub release and tag ------------------------- @@ -75,7 +92,7 @@ If the release branch doesn't already exist, check out the latest patch for that Developing on a release branch ------------------------------ -Once a release branch exists, it becomes the "master" branch for patches of that major-minor version. +Once a release branch exists, it becomes the "main" branch for patches of that major-minor version. Pull requests should be based on, and merged into, the release branch. If the development on the release branch is a backport of commits on the ``main`` branch, use ``git cherry-pick`` to copy those commits into a new pull request against the release branch. diff --git a/project_templates/square_pypi_package/{{cookiecutter.name}}/pyproject.toml b/project_templates/square_pypi_package/{{cookiecutter.name}}/pyproject.toml index 50da4f19..79c871e2 100644 --- a/project_templates/square_pypi_package/{{cookiecutter.name}}/pyproject.toml +++ b/project_templates/square_pypi_package/{{cookiecutter.name}}/pyproject.toml @@ -234,3 +234,16 @@ classmethod-decorators = [ [tool.ruff.pydocstyle] convention = "numpy" + +[tool.scriv] +categories = [ + "Backwards-incompatible changes", + "New features", + "Bug fixes", + "Other changes", +] +entry_title_template = "{{ "{{ version }} ({{ date.strftime('%Y-%m-%d') }})" }}" +format = "md" +md_header_level = "2" +new_fragment_template = "file:changelog.d/_template.md.jinja" +skip_fragments = "_template.md.jinja"