Using towncrier for CHANGES.rst in Plone packages

I would like to start using towncrier for managing the CHANGES.rst file in several Plone packages. This tool gathers news fragments from a directory, instead of relying on developers keeping the CHANGES.rst file up to date. Editing a changelog file doesn't sound too hard, but usually in the end it is not a developer that does this, but github. And I have seen this go wrong too many times:

  • You create a pull request for a bug fix in version 1.0.
  • Someone creates a release 2.0 without your fix.
  • Your fix gets reviewed and merged.
  • Problem: after the merge, your fix is likely mentioned under the 1.0 version header. (See for example this commit to fix such an error.)
  • Or: some extra, completely unrelated lines get merged into the changelog.
  • If this doesn't get caught before release, it takes a software archeologist to figure out in which version a fix was really done.

To avoid problems like this, the pip project has been using towncrier for about a year now. The pip documentation explains how to use it. Basically, in a PR you would create a news/1234.bugfix file or a news/42.feature file. You do not touch CHANGES.rst. At release time, the person doing the release calls towncrier, which handles updating CHANGES.rst and removing the news fragments.

I (and the Plone Release Team) want to start using this for Plone packages as well. It may not be useful for all packages. The most to be gained would be for packages that get lots of changes, or that have multiple active branches. Likely we would start with just a couple of packages, like Products.CMFPlone and, to see how it goes.

Some work is on the way, like creating a zest.releaser plugin (see and a couple more things need to be done, like updates to mr.roboto (see

But I would like some feedback. Do others see the need of this as well? Maybe you have used towncrier already in other projects?


I never heard about it but it sounds really nice!

Sound like this is a great idea. The conflicts in CHANGES.rst are annoying.

For sure, it results in some communication at the beginning.

It is a good idea to start with a few packages first, but if all works and possible upcoming problems are solved (better sooner than later), I would use it for all core-packages. Mixing two styles is confusing never a good idea.

1 Like

This sounds nice. In order to make sure that developers know to do it the new way, we probably need a note at the top of CHANGES.rst to point them to the new approach (maybe there's a way to write this in an rst directive that won't render on PyPI?)

I have a sample PR (not meant to be merged) in plone.releaser that shows such a note. See

I have released zestreleaser.towncrier 1.0.0b1:

With that installed, a fullrelease will call towncrier at the right time. If the package doesn't use towncrier, this does no harm.

The plone.releaser wrapper around zest.releaser will require that package:
Once that is merged and released, it should be fine for core Plone packages to start using towncrier.
The PR has documentation on how to set that up initially.

Biggest hurdle that I see now is adapting the changelog entry check by mr.roboto on core Plone pull requests. See

There is a new towncrier release 18.5.0 (2018, May, release 0). That has a fix from me which means you do not need to set an importable package name in pyproject.toml. That avoids confusion.

I have meanwhile released two bugfix versions of zestreleaser.towncrier, so we are now at 1.0.0b3. It requires the latest towncrier.

1 Like

I have released plone.releaser 1.7.0 which uses towncrier.

Towncrier is of course still optional: if a package does not have a pyproject.toml, nothing special will happen, and releasing will work as before.

I will be initializing towncrier for several core pacakges during the sprint in Halle.
A script for automating most of the parts is here.


Awesome work Maurits! Thank you!

Products.Archetypes is the first package that uses it (well, apart from plone.releaser and some own packages). This was easy because all relevant branches had been released recently and had no changes.
Sample change:

1 Like

I am keeping a list of packages for which towncrier should be initialized:

That might be a nice task for the post conference sprint in Japan. Hint. :slight_smile: Should be fairly straightforward for most packages, so should be good for newcomers.

Big change of today: I have initialized towncrier on Products.CMFPlone! There was a release of that package today, so that is a good time to do this. The 5.0.x branch had lots of changes though, so that required more manual work.

Hi, Maurits! :slight_smile: How are you?

I have a question/feature proposal: is it already possible, or not desirable, that we reference in towncrier issues opened in other repositories? It's a very common case as even core developers may open an issue where it is more noticeable then after some investigation the problem proves to lie in another package so I fear this might exponentially burden us more than necessary.


Workaround: use the own issue's PR as number (Github treats them similarly).

Hi @davilima6,

The most important requirement for the number is that it is unique, or at least unique for the current release. If you create a PR and randomly pick 123.bugfix as news snippet, and someone else in a different PR also picks 123.bugfix, then this will give a git merge conflict.

You could create a really random number, probably slightly longer with 123456.bugfix. That would make it unique.
But the most practical way to make the number unique, and at the same time meaningful, is to use a ticket number.

For most Plone packages this can already mean two things:

  1. An issue number (or PR) of the package.
  2. An issue number (or PR) of Products.CMFPlone.

Long answer short: yes it is fine to use issue numbers of other repositories. Just keep them unique for the current release.

BTW, in corner cases it may be perfectly reasonable and valid to have 42.bugfix, 42.feature and 42.breaking all in one release. So strictly speaking the number plus category should be unique for the current release.

1 Like

It's very clear now, thanks!