Skip to content

Setup Towncrier for changelog management, remove release-drafter #2203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jul 30, 2025

Conversation

sirosen
Copy link
Member

@sirosen sirosen commented Jul 16, 2025

These changes are broken down into several commits for simpler review.

What

  • Convert to Towncrier and prepare notes for the upcoming release.

How

  • Remove release-drafter.
  • Setup Towncrier configuration.
  • Write Towncrier newsfiles to document all changes since v7.4.1 .
  • Setup integrations in git, sphinx, pre-commit, and tox.
Contributor checklist
  • Included tests for the changes.
  • A newsfile is created in changelog.d/ (see changelog.d/README.md) for instructions) or the PR text says "no changelog needed".
Maintainer checklist
  • If no changelog is needed, apply the skip-changelog label.
  • Assign the PR to an existing or new milestone for the target version (following Semantic Versioning).

@webknjaz
Copy link
Member

@sirosen I was thinking about having the change log fragments dir nested under the docs dir to reduce the number of the high-level things. Any objections?

Copy link
Member

@webknjaz webknjaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not very in-depth. I'll do another round after your next update. Could you make sure the contributors are credited in the notes, too?


##### Maintainer checklist

- [ ] Verified one of these labels is present: `backwards incompatible`, `feature`, `enhancement`, `deprecation`, `bug`, `dependency`, `docs` or `skip-changelog` as they determine changelog listing.
- [ ] If no changelog is needed, apply the `skip-changelog` label.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to record some guidelines for this (maybe, in a follow-up).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can refine this more in the contributing docs? For now, I wanted to make some kind of update here and keep it pretty simple.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was imagining it'd be just linked here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is okay for now? But if you have some idea on where/how to link, I'm happy to include a small change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In aiohttp, we have a bit of explanation right in the PR template: aio-libs/aiohttp#11320. However, it's also possible to add a Markdown link to RTD (or GH README preview), just like in the following checkbox one line below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was overthinking this one. The PR template now has a link to the changelog.d/README.md. Maybe there's a better way to do it, but I linked directly to https://github.com/jazzband/pip-tools/blob/main/changelog.d/README.md

My thought is that we may tweak the doc over time, so linking to the published RTD site could be out of date.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, no rush to make it perfect in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you decide not to follow my boilerplate? Any thoughts? Concrete fragment examples to show? These could be a few of the fragments you're adding in this PR copied into this doc.
Also, let's mention the possibility of bylines.

Copy link
Member Author

@sirosen sirosen Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, regarding bylines: yes, I'll add that for sure. More thoughts on that topic to follow (I want to rewrite the past entries too).

I was trying to balance concerns between trying to keep things similar to what you have in other projects, but also produce a document which gets new contributors to the instructions quickly. I'm a little concerned about the example from cheroot -- I think that for a new contributor that doc is a bit intimidating and gives too much detail about the rationale for Towncrier and changelogs up front.

My preference is for this doc to read primarily as a "how to", and for the motivation behind it to be separated out. (Similar to diataxis, but simply as sections within a doc.)

I think we can reintroduce all of the elments I removed in a sub-section, keeping the start of the doc short and recipe-like.
Would you be okay with the content flowing as follows?

## Adding Change Notes with PRs

<mostly the currently proposed "how to" content + mention of adding a byline>

### Categories

The change categories are defined as follows:

- `bugfix:` A bug fix for something we deemed an improper undesired behavior that got corrected in the release to match pre-agreed expectations.
- ... <list follows>

Sometimes it's not clear which category to use for a change. Do your best and a maintainer can discuss this with you during review.

### Example Change Notes

<copy from cheroot example>

### Rationale

When somebody makes a change, they must record the bits that would affect end-users only including information that would be useful to them. ... <content from cheroot example follows>

We write change notes in the past tense because this suits the users who will be reading these notes.
Combined with others, the notes will be a part of the "news digest" telling the readers what **changed** in a specific version of the library since the previous version.

<anything else from the cheroot doc which I've missed probably goes here>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea. I was mostly writing those explanations in isolation with no feedback loop, having been tired of re-explaining how people should author their notes. And so I've been dragging this document around across projects.
I think it's imperfect, and I'd like to improve it. I've been thinking of how to integrate some ideas from https://redhat-documentation.github.io/supplementary-style-guide/#release-notes and lurking into the release notes channel in the Write The Docs Slack, but haven't gotten to it yet.

So if you manage to make it more friendly, I'd love to copy it back into other projects. Making sphinxcontrib-towncrier was one of the sides of me attempting to improve authoring change logs.

### Example Change Notes

<copy from cheroot example>

I think you should copy some of the actual change notes you're adding in this PR. I've been doing that, and it feels more immersive when yarl fragment examples talk about yarl and aiohttp examples talk about aiohttp.

I'd be nice to improve my bot eventually to be able to help with change note authoring, similar to CPython's blurb-it. But that's a separate endeavor.

Copy link
Member Author

@sirosen sirosen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make sure the contributors are credited in the notes, too?

On review, I don't like my decision not to include the Thanks <user> lines, as with the past changelog entries.

I think I was struggling with the fact that there's no trivial way to do this in the format that I converted the past changelog entries to use. (Where the "Thanks" comes after the issue reference).

I'll include it here and I think I'll also do a separate change to make the changelog match the "new" format, of

- <text>. Thanks <user>!
  (#NNN, #NNN)

I want things to read uniformly if possible, from old to new. :)

I was thinking about having the change log fragments dir nested under the docs dir to reduce the number of the high-level things. Any objections?

I somewhat prefer to have it in the root of the repo, but that's weakly held. If your preference here is a strong one, I can move it.

My rationale is that this is a touch-point for any contributor, so it's simpler (especially for a new contributor) to only traverse one dir. And I think changelogs are important enough to get "two slots" (the file and the dir) in the repo root.


I can't put the time in right now to make the suggested changes, but I'll get it done soon. 👍


##### Maintainer checklist

- [ ] Verified one of these labels is present: `backwards incompatible`, `feature`, `enhancement`, `deprecation`, `bug`, `dependency`, `docs` or `skip-changelog` as they determine changelog listing.
- [ ] If no changelog is needed, apply the `skip-changelog` label.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can refine this more in the contributing docs? For now, I wanted to make some kind of update here and keep it pretty simple.

Copy link
Member Author

@sirosen sirosen Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, regarding bylines: yes, I'll add that for sure. More thoughts on that topic to follow (I want to rewrite the past entries too).

I was trying to balance concerns between trying to keep things similar to what you have in other projects, but also produce a document which gets new contributors to the instructions quickly. I'm a little concerned about the example from cheroot -- I think that for a new contributor that doc is a bit intimidating and gives too much detail about the rationale for Towncrier and changelogs up front.

My preference is for this doc to read primarily as a "how to", and for the motivation behind it to be separated out. (Similar to diataxis, but simply as sections within a doc.)

I think we can reintroduce all of the elments I removed in a sub-section, keeping the start of the doc short and recipe-like.
Would you be okay with the content flowing as follows?

## Adding Change Notes with PRs

<mostly the currently proposed "how to" content + mention of adding a byline>

### Categories

The change categories are defined as follows:

- `bugfix:` A bug fix for something we deemed an improper undesired behavior that got corrected in the release to match pre-agreed expectations.
- ... <list follows>

Sometimes it's not clear which category to use for a change. Do your best and a maintainer can discuss this with you during review.

### Example Change Notes

<copy from cheroot example>

### Rationale

When somebody makes a change, they must record the bits that would affect end-users only including information that would be useful to them. ... <content from cheroot example follows>

We write change notes in the past tense because this suits the users who will be reading these notes.
Combined with others, the notes will be a part of the "news digest" telling the readers what **changed** in a specific version of the library since the previous version.

<anything else from the cheroot doc which I've missed probably goes here>

@webknjaz webknjaz added docs Documentation related maintenance Related to maintenance processes ci Related to continuous integration tasks labels Jul 22, 2025
@webknjaz
Copy link
Member

@sirosen my bot for change note fragments is now plugged into this repo and reports via Checks API as follows: https://github.com/jazzband/pip-tools/pull/2203/checks?check_run_id=46466229160. As you get to adding the config (possibly in a separate PR), the reported check name may change (pip has that).

@webknjaz
Copy link
Member

webknjaz commented Jul 22, 2025

Could you make sure the contributors are credited in the notes, too?

On review, I don't like my decision not to include the Thanks <user> lines, as with the past changelog entries.

I think I was struggling with the fact that there's no trivial way to do this in the format that I converted the past changelog entries to use. (Where the "Thanks" comes after the issue reference).

I'll include it here and I think I'll also do a separate change to make the changelog match the "new" format, of

- <text>. Thanks <user>!
  (#NNN, #NNN)

I want things to read uniformly if possible, from old to new. :)

Haha! I'm getting flashbacks of one time I've gone deep down the rabbit hole to do something similar post Towncrier reconfig in setuptools: pypa/setuptools#2436.

I'm not sure how I feel about “Thanks” vs. “by”. This is something a contributor would be adding, so some may feel weird thanking themselves, while regular bylines might not trigger the same reaction.

I've been following the style over the past few years, where a byline would be either a part of a sentence (with no period before it but one after), or as a dedicated line (no periods). The standalone byline can be placed either at the end, or after the first paragraph. The in-sentence one could be integrated in one of the sentences wherever it feels right.

So my style would be like one of these:

A phrase -- by :user:`gh-username`.
A phrase -- by :user:`gh-username`.

Another paragraph.
A phrase -- by :user:`gh-username`. Extra detail.

Another paragraph.
A phrase. More detail.

-- by :user:`gh-username`

Another paragraph.

Or more.

.. code-block:: python

   <usage-example>

Recommendations.
A phrase. More detail.

Another paragraph.

-- by :user:`gh-username`

And with that, references would always come after since they're outside the fragment, in the template + have labels that wouldn't work before the note.

I was thinking about having the change log fragments dir nested under the docs dir to reduce the number of the high-level things. Any objections?

I somewhat prefer to have it in the root of the repo, but that's weakly held. If your preference here is a strong one, I can move it.

My rationale is that this is a touch-point for any contributor, so it's simpler (especially for a new contributor) to only traverse one dir. And I think changelogs are important enough to get "two slots" (the file and the dir) in the repo root.

I just know that many people dislike having many things in the root, so I've been moving the fragments deeper (and closer to the docs). But we can keep it at the top if you think it's best. I won't insist.

@sirosen sirosen force-pushed the use-towncrier branch 4 times, most recently from ac0c980 to 2b98b7b Compare July 25, 2025 05:49
@sirosen
Copy link
Member Author

sirosen commented Jul 25, 2025

I've just tinkered through what I think is "good enough to merge". I've tried to address all of the minor things like switching over from subprocess.PIPE to subprocess.DEVNULL, 100% better, or using symlinks for matching newsfiles.

The contributor notes are fleshed out more, but in the structure that I prefer where we put prescriptive "do this!" guidance up front, and explain/elaborate on it below. I feel like it's pretty good, but of course I'm open to feedback/improvements. It's cribbed somewhat from the cheroot example (... mid-post, I'm editing to make that a co-authored commit 😁 ), but I've applied some minor tweaks. Notably, the category descriptions are adjusted a bit to fit a CLI tool.

The bylines have been introduced, and integrated into the new fragments.
I did a minimal edit to the existing changelog to make every existing "Thanks" note into a byline for some level of uniformity, and then I started trying to make the style uniform... which I then abandoned and backed out. I think I need to do a bit more tweaking for that, and I'm not wanting to block the release on getting that done. So the ordering will be a little inconsistent in terms of where the PR reference goes, where the byline goes, and where punctuation goes. But all of the new items should be in "good style".

Overall, I think this is ready for a (final?) review. I'm going to scan over the comments and resolve the ones which I don't think we need to discuss, to make sure I didn't forget anything. I'm leaving the thread on the contributor doc, since that's the most likely thing to need more feedback.

@webknjaz
Copy link
Member

then I started trying to make the style uniform... which I then abandoned and backed out. I think I need to do a bit more tweaking for that, and I'm not wanting to block the release on getting that done. So the ordering will be a little inconsistent in terms of where the PR reference goes, where the byline goes, and where punctuation goes. But all of the new items should be in "good style".

That's something I wouldn't even put into this PR. It's nice to have in the future, but I personally wouldn't invest time into it. I wonder, however, if throwing it into something like Claude Chat or Claude Code would work and reduce your workload. This is something I'd like to explore in the interest of self-education. One other idea would be to try integrating prose linting tooling like https://vale.sh (I'm tracking some of it @ aio-libs/multidict#276) but that's definitely something out of the scope right now.

I'm going to scan over the comments and resolve the ones which I don't think we need to discuss, to make sure I didn't forget anything.

It's usually inconvenient for people who started such inline threads to go back in a following review and try to understand what's actually solved. I often have to spend some time tracking down all the collapsed discussions to make sure they are really solved (since in that hidden state it's unclear if there's something I wanted to follow up on or double-check). So I tend to recommend people to either let the topic starters resolve threads (since they would be the ones to judge if something is resolved) or at least add a comment “marking this thread as resolved” before clicking the button. Without that comment, the button click doesn't even generate any notifications, and it becomes difficult to track what's happening and when.

@webknjaz
Copy link
Member

* [x]  Included tests for the changes.

I marked this for you since I consider invoking Towncrier through Sphinx a very good smoke test already.

Comment on lines 1 to 7
{%- if versiondata["version"] == "main" -%}
## Unreleased Changes
{% else -%}
## {{ versiondata["version"] }}
{% endif %}

*{{ versiondata["date"] }}*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is a bit new for me as I typically use RST and the title is coming from the Sphinx's directive entirely (and the version is setuptools-scm-made in those cases), but perhaps, we could take this opportunity to prefix the date with clearer text:

Suggested change
{%- if versiondata["version"] == "main" -%}
## Unreleased Changes
{% else -%}
## {{ versiondata["version"] }}
{% endif %}
*{{ versiondata["date"] }}*
{%- set is_draft_preview = versiondata["version"] == "$$sphinx-draft-preview$$" -%}
{%- if is_draft_preview -%}
## Unreleased Changes
{% else -%}
## {{ versiondata["version"] }}
{% endif %}
*{%- if is_draft_preview -%}Generated for preview on {%- endif -%}{{ versiondata["date"] }}*

(we probably don't need an else-branch with an "actually released on " wording, right?)


By the way, have you tested a regular non---draft run locally? Does it produce satisfactory output?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the "Generated for preview on..." style; adding that to my current changeset!

I did a non-draft run pretty early in this work, so it easily could have drifted. I'll double-check it after this next batch of changes.

{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section] -%}

{{ definitions[category]['name'] }}:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this deserves to be a title:

Suggested change
{{ definitions[category]['name'] }}:
### {{ definitions[category]['name'] }}:

Alternatively, at least make it more distinct:

Suggested change
{{ definitions[category]['name'] }}:
**{{ definitions[category]['name'] }}**:
Suggested change
{{ definitions[category]['name'] }}:
*{{ definitions[category]['name'] }}*:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it as plain text doesn't help people notice that there are multiple categories rather than just a wall of text, in my view: https://pip-tools--2203.org.readthedocs.build/en/2203/changelog/#unreleased-changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted these to be titles, but I resisted in order to stay consistent with the past changelogs.
I'll update them all to match, but I'll do it in a dedicated commit so that it's easy to revert if we'd rather save this for later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too worried about temporary inconsistency. My preference is to just have the final template in right away. But I'll let you decide if you want to postpone this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a change where I made the old sections into headers. So the names of sections may be inconsistent but the styling will be consistent.

<!-- new stuff -->
### Features
...
### Contributor-facing changes
...
<!-- old stuff -->
### Major Changes
...
### Other Changes
...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine. The old categories are different and it's okay to skip normalizing them.


- {{ text }} {%
if pr_issue_numbers -%}
({issue}`{{ pr_issue_numbers|join('`, {issue}`') }}`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm uneasy about dropping the "PRs and issues" prefix. Having this start with a paren enables weird sequences when the change notes end with a period.

You can see multiple sequences like . (# @ https://pip-tools--2203.org.readthedocs.build/en/2203/changelog/#unreleased-changes which is what I was trying to avoid by (1) placing these refs on separate lines (so weird things in notes wouldn't make it look odd), and (2) would work with both single-liners and multi-paragraph blurbs.

Having no prefix only works when somebody forgets to end their phrase with a period.

Besides, commit and arbitrary refs have the same level of importance and I think they should follow the same style.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm easily convinced on this. I don't mind the . (# formatting, but it is a little weird looking.

I'll adjust (back) to "PRs and issues".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

docs/conf.py Outdated
)
if IS_RELEASE_ON_RTD:
tags: set[str]
# pylint: disable-next=used-before-assignment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've since learned that it's possible to have something like

def setup(app: Sphinx) -> dict[str, bool | str]:
    """Register project-local Sphinx extension-API customizations.

    :param app: Initialized Sphinx app instance.
    :returns: Extension metadata.
    """
    if IS_RELEASE_ON_RTD:
        app.tags.add("is_release")

    return {
        'parallel_read_safe': True,
        'parallel_write_safe': True,
        'version': release,
    }

at the very bottom.

I think this can work better with typing, plus would let us drop linting suppressions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty neat; I never knew you could put this hook into conf.py. I wonder if some of the custom plugin cases I've bumped into could be replaced with this... 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I've been doing this for years. Just keep in mind that conf.py is a special case and there be dragons (I was once very confused when I placed some directive classes into it and couldn't understand why that was exploding — this was when I was first writing that sphinxcontrib-towncrier extension in-tree). But most of the time, it works just fine. For more complex things, I still tend to move code into dedicated modules in-project.

Some examples include https://github.com/cherrypy/cheroot/blob/587d1fa5e19eb1337d2b9c22995783761628c4b1/docs/spelling_stub_ext.py vs. https://github.com/ansible/awx-plugins/blob/c4180cd22bc6b83750d3256892c38f342eb1e9c5/docs/conf.py#L236-L272.

sirosen and others added 21 commits July 29, 2025 18:57
This follows the example of cherrypy/cheroot, but with a few
alterations:

- no need to specially handle `int` in jinja, since the bug referenced
  in current cheroot config has been fixed

- match the current PR style which puts issue links in parens on the
  same line as the text

- only put one line between items; closer to current style
These are compiled from the non-automated pull requests which have
merged since v7.4.1 (the last release).
Use a subprocess invocation to control stderr with the fewest
additional dependencies and minimal complexity.
Add various Python CLI options for isolation and error handling.

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <578543+webknjaz@users.noreply.github.com>
- update all existing "Thanks <user>" lines to use this style
- add bylines to the newly proposed change notes
- update the changelog guidance to recommend including a byline

Also, add a link for the sphinx-issues item.
The contributor doc now covers three new sections: categories,
examples, rationale. These expand upon the procedural guidance for
contributors who want to understand more deeply or want more detail on
how to understand the changelog process.

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <578543+webknjaz@users.noreply.github.com>
Place the period at the end of the byline for lines which attach to a
single sentence. For notes which multiple sentences, terminate them as
complete sentences, and put the byline after an empty line for a clear
separation.
Co-authored-by: James Addison <55152140+jayaddison@users.noreply.github.com>
- call the draft version "DRAFT_VERSION" rather than the opaque "main"
- split issue/PR citations to a separate line in the changelog
- use the conf.py setup() hook for sphinx customization
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <578543+webknjaz@users.noreply.github.com>
- link to it from the PR template
- fix a stray backtick
- put category examples in more uniform style
- swap "library" (wrong!) for "pip-tools"

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <578543+webknjaz@users.noreply.github.com>
Co-authored-by: James Addison <55152140+jayaddison@users.noreply.github.com>
This is applied both to the towncrier template and to the historical
changelog. Except for some minor discrepancies (e.g., inconsistent
casing), the historical sections are left intact and are only restyled
here.
Fix '.' placement vis-a-vis bylines.
MyST does not properly evaluate `{only}` directives, and
experimentally always treats them as `true`. As a result, the draft
changelog is included even when a release build is set.

To fix, nest a layer of `eval-rst`, to drop into the sphinx rst parser
which handles these correctly, into the changelog. An explanatory
comment describes why we are doing this.

In order to support this usage, the changelog draft MyST directive is
broken out into a separate partial doc for inclusion. For now, it's
placed into `changelog.d/` to keep it clearly outside of the doc build
targets.

MyST flags the partial for starting at the wrong header level. This
appears to be a false positive for that check -- the header level is
intentionally starting at H2 for this partial doc. It does not appear
to be possible to turn off the warning with specificity or to use
MyST directives to clarify our intent. `:start-after:` for the include
directive, with a dummy header, is similarly ineffective, as MyST
seems to be warning when it loads the partial doc.
For now, we can simply suppress the warning altogether.

In order to facilitate testing -- and potentially unifying our RTD
build with our tox config in the future -- RTD environment variables
are now declared in passenv for the `build-docs` environment.
Using leading, rather than trailing, whitespace makes it easier to
keep presentation consistent. Explicit newline literals are used for
the initial spacing.

This new configuration has been tested against all combinations of
combined references for a changelog entry and confirmed to produce
consistent results.

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <578543+webknjaz@users.noreply.github.com>
@sirosen
Copy link
Member Author

sirosen commented Jul 30, 2025

Okay, I think I've reached the point of diminishing returns after a couple of interactive rebase passes. I could probably spend hours rebuilding a perfect history, with only the "useful" variations on this work included, but I don't think that's a good use of our time.

@sirosen sirosen added this pull request to the merge queue Jul 30, 2025
Merged via the queue into jazzband:main with commit b4ddd75 Jul 30, 2025
41 checks passed
@sirosen sirosen deleted the use-towncrier branch July 30, 2025 02:22
jayaddison added a commit to openculinary/pip-tools that referenced this pull request Aug 1, 2025
The migration to towncrier in jazzband#2203 included a couple of
synthetic change note examples.

Now that towncrier is in use and some changes that use it
have landed in pip-tools, we can update the examples so that
they hyperlink to genuine pull requests.

This is intended to aid contributors by providing them with
more accurate, representative examples to crib from.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot:chronographer:provided ci Related to continuous integration tasks docs Documentation related maintenance Related to maintenance processes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proper change log management with Towncrier
3 participants