Skip to content

Commit

Permalink
Setup towncrier for release notes generation
Browse files Browse the repository at this point in the history
Resolves: #99

Signed-off-by: Ryan Lerch <[email protected]>
  • Loading branch information
ryanlerch committed Feb 21, 2024
1 parent e468612 commit e1f9959
Show file tree
Hide file tree
Showing 8 changed files with 913 additions and 544 deletions.
29 changes: 24 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import os
import re
import sys

topdir = os.path.abspath("../")
Expand Down Expand Up @@ -48,6 +49,7 @@
"sphinx.ext.extlinks",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"myst_parser",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -92,14 +94,31 @@
# -- Extension configuration -------------------------------------------------

autodoc_mock_imports = ["gssapi", "requests_gssapi"]
source_suffix = {
".rst": "restructuredtext",
".md": "markdown",
}

myst_enable_extensions = [
"colon_fence",
]
myst_heading_anchors = 3

# -- Options for intersphinx extension ---------------------------------------

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}

extlinks = {
"commit": ("https://github.com/fedora-infra/fasjson-client/commit/%s", "%s"),
"issue": ("https://github.com/fedora-infra/fasjson-client/issues/%s", "#%s"),
"pr": ("https://github.com/fedora-infra/fasjson-client/pull/%s", "PR#%s"),
}
github_url = "https://github.com/fedora-infra/fasjson-client"


def changelog_github_links(app, docname, source):
if docname != "release_notes":
return
github_issue_re = re.compile(r"#(\d+)")
for docnr, doc in enumerate(source):
source[docnr] = github_issue_re.sub(f"[#\\1]({github_url}/issues/\\1)", doc)


def setup(app):
app.connect("source-read", changelog_github_links)
49 changes: 49 additions & 0 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,52 @@ License
Licensed under `lgpl-3.0`_

.. _lgpl-3.0: https://opensource.org/licenses/lgpl-3.0.html


Release Notes
-------------

To add entries to the release notes, create a file in the ``news`` directory in the
``source.type`` name format, where the ``source`` part of the filename is:

* ``42`` when the change is described in issue ``42``
* ``PR42`` when the change has been implemented in pull request ``42``, and
there is no associated issue
* ``Cabcdef`` when the change has been implemented in changeset ``abcdef``, and
there is no associated issue or pull request.

And where the extension ``type`` is one of:

* ``bic``: for backwards incompatible changes
* ``dependency``: for dependency changes
* ``feature``: for new features
* ``bug``: for bug fixes
* ``dev``: for development improvements
* ``docs``: for documentation improvements
* ``other``: for other changes

The content of the file will end up in the release notes. It should not end with a ``.``
(full stop).

If it is not present already, add a file in the ``news`` directory named ``username.author``
where ``username`` is the first part of your commit's email address, and containing the name
you want to be credited as. There is a script to generate a list of authors that we run
before releasing, but creating the file manually allows you to set a custom name.

A preview of the release notes can be generated with
``towncrier --draft``.

Release Process
^^^^^^^^^^^^^^^

#. Update the version in ``pyproject.toml`` by running ``poetry version major|minor|patch``
depending on the contents of the release.
#. Run ``poetry install`` to update the package's metadata.
#. Add missing authors to the release notes fragments by changing to the ``news`` directory and
running the ``get-authors.py`` script, but check for duplicates and errors
#. Generate the release notes by running ``poetry run towncrier build`` (in the base directory)
#. Adjust the release notes in ``docs/release_notes.md``.
#. Generate the docs with ``tox -r -e docs`` and check them in ``docs/_build/html``.
#. Commit the changes
#. Create the release and tag in the Github webui

9 changes: 9 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,12 @@ on open-api specs (version 2.0).
:caption: Contributor Guide

contributing


.. Release Notes
.. toctree::
:maxdepth: 2
:caption: Release Notes

release_notes
41 changes: 41 additions & 0 deletions docs/release_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Release notes

<!-- towncrier release notes start -->

## v1.0.8

Released on 2023-03-29.

### Changes

- Drop support for Python 3.6 to update dependencies, and add support for Python 3.10 and 3.11
- Update dependencies
- Fix Sphinx config
- Fix CI
- Allow additional operation arguments in `list_all_entities`
- Register the `X-Fields` mask format
- Restore compatibility with `requests` < 2.26.0 to support RHEL9

### Contributors

Many thanks to the contributors of bug reports, pull requests, and pull request
reviews for this release:

- Akashdeep Dhar
- Aurélien Bompard
- Carl George

## v1.0.7

Released on 2022-05-11.

### Development Improvements

- add and configure packit (#268)

### Contributors

Many thanks to the contributors of bug reports, pull requests, and pull request
reviews for this release:

- Stephen Coady
58 changes: 58 additions & 0 deletions news/_template.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% macro reference(value) -%}
{%- if value.startswith("PR") -%}
PR #{{ value[2:] }}
{%- elif value.startswith("C") -%}
[{{ value[1:] }}](https://github.com/fedora-infra/fasjson-client/commits/{{ value[1:] }})
{%- else -%}
#{{ value }}
{%- endif -%}
{%- endmacro -%}

{{- top_line -}}

Released on {{ versiondata.date }}. This is a {major|feature|bugfix} release that adds [short summary].

{% for section, _ in sections.items() -%}
{%- if section -%}
## {{section}}
{%- endif -%}

{%- if sections[section] -%}
{%- for category, val in definitions.items() if category in sections[section] and category != "author" -%}
### {{ definitions[category]['name'] }}

{% if definitions[category]['showcontent'] -%}
{%- for text, values in sections[section][category].items() %}
- {{ text }} ({% for value in values -%}
{{ reference(value) }}
{%- if not loop.last %}, {% endif -%}
{%- endfor %}).
{% endfor -%}
{%- else -%}
- {{ sections[section][category]['']|sort|join(', ') }}

{% endif -%}
{%- if sections[section][category]|length == 0 %}
No significant changes.

{% else -%}
{%- endif %}

{% endfor -%}
{%- if sections[section]["author"] %}
## {{definitions['author']["name"]}}

Many thanks to the contributors of bug reports, pull requests, and pull request
reviews for this release:

{% for text, values in sections[section]["author"].items() -%}
- {{ text }}
{% endfor -%}
{%- endif -%}

{% else -%}
No significant changes.


{% endif -%}
{%- endfor -%}
74 changes: 74 additions & 0 deletions news/get-authors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3

"""
This script browses through git commit history (starting at latest tag), collects all authors of
commits and creates fragment for `towncrier`_ tool.
It's meant to be run during the release process, before generating the release notes.
Example::
$ python get_authors.py
.. _towncrier: https://github.com/hawkowl/towncrier/
Authors:
Aurelien Bompard
Michal Konecny
"""

import os
from argparse import ArgumentParser
from subprocess import check_output


EXCLUDE = [
"dependabot[bot]",
"dependabot-preview[bot]",
"Weblate (bot)",
"renovate[bot]",
]

last_tag = check_output(
"git tag | sort -n | tail -n 1", shell=True, universal_newlines=True
).strip()

args_parser = ArgumentParser()
args_parser.add_argument(
"until",
nargs="?",
default="HEAD",
help="Consider all commits until this one (default: %(default)s).",
)
args_parser.add_argument(
"since",
nargs="?",
default=last_tag,
help="Consider all commits since this one (default: %(default)s).",
)
args = args_parser.parse_args()

authors = {}
log_range = args.since + ".." + args.until
output = check_output(
["git", "log", log_range, "--format=%ae\t%an"], universal_newlines=True
)
print(last_tag)
for line in output.splitlines():
email, fullname = line.split("\t")
email = email.split("@")[0].replace(".", "")
if email in authors:
continue
authors[email] = fullname

for nick, fullname in authors.items():
if fullname in EXCLUDE or fullname.endswith("[bot]"):
continue
filename = f"{nick}.author"
if os.path.exists(filename):
print(f"Author Already Created {fullname} ({nick})")
continue
print(f"Adding author {fullname} ({nick})")
with open(filename, "w") as f:
f.write(fullname)
f.write("\n")
Loading

0 comments on commit e1f9959

Please sign in to comment.