Changelog Unleashed: Mergify's Leap into Automated Feature Announcements
In this blog post, we are diving into the process we created to generate our changelog, hence announcing our new features each time a pull request is merged.
Picture this: your favorite SaaS tool dropping updates left and right, but you're left in the dark about what's actually happening. Sounds a bit odd, right? Obviously, every SaaS product should have a changelog. Mergify has had a changelog since the first year of its existence.
Think of a changelog as a product’s diary, without the dramatic entries. Take GitHub’s changelog for instance. It’s a simple timeline where every feature has its own spotlight. A descriptive title, an easy-to-digest description, and some labels to keep things organized. Each feature can be shared easily with a link. Well, that should not be too difficult to do so, right?
In this blog post, we are diving into the process we created to generate our changelog. As we ship dozens of pull requests every day, we wanted a changelog as automated as possible, to keep our users up-to-date with their favorite product as soon as possible.
Need for Change
Before the end of 2022, we used to publish a quarterly changelog on our blog and send this by email to our users.
Our Product Owner had to forge it every three months, which was a bit time-consuming. The task consisted of crawling the list of the pull requests merged on our main repositories during the last months and writing a post about this batch of features.
There were some drawbacks to this process, in addition to the time it took to create the blog post. Especially, if a feature was released on the first day of the quarter, it was only announced three months later. Moreover, if a user wanted the list of the last semester's features, he had to read through several blog posts. Finally, we couldn’t share a single change easily. Each change was mixed with other non-related changes.
We had to rethink the whole process to address our problems.
- We should be able to announce new features and changes whenever we want;
- It should be easy to find the list of changes for any period;
- We should be able to share a single change with a link.
Changelog, the Remake
Our new changelog should be a web page that we can update as soon as we publish something new in one of our repositories. This page doesn’t have to be complicated. As we can see on GitHub’s changelog, a simple timeline of changes does the job.
As we are great fans of Notion, we came up with the idea that our changelog could be a simple Notion page published on the web. And that’s exactly what we did! What you can see on this page is a laid-out Notion database.
This is a simple list of changes ordered by date of release. Each change has a descriptive title, one or several labels, a release date, and an emoji (of course 😏). Adding a search button to find an entry fast is a piece of cake. You can even view the changelog as a calendar if you want!
The Notion database makes the changelog easy to maintain. The Product Owner just has to add an entry to the database for it to be instantly published. The changelog can be updated regularly by anyone from the marketing team.
Automate the Change
Now comes the fun part for us engineers!
We asked ourselves:
As we ship changes every day thanks to our CI/CD pipelines, is it possible to add an entry to the changelog database every time a pull request is merged?
What would be needed to create such a process?
First, we have to know which pull request will create an entry in the changelog. We want to have an entry for each new relevant feature. Well, almost done already, as every pull request’s title has to follow the Conventional Commit rule. So every feature pull request has a title like feat(scope): title
. Excellent!
But every feature doesn’t have to be published in the public changelog. Some features are private or trivial. So we have to rely on the developers to tag each feature. Thanks to Mergify, we can easily remind the developer to tag a pull request with a label using a post_check
action.
Here is the interesting part of our Mergify configuration file.
pull_request_rules:
- name: Conventional Commit
conditions:
- base=main
actions:
post_check:
success_conditions:
- "title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\\(.+\\))?:"
title: |
{% if check_succeed %}
Title follows Conventional Commit
{% else %}
Title does not follow Conventional Commit
{% endif %}
summary: |
{% if not check_succeed %}
The pull request title must follow
[Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/).
{% endif %}
- name: Changelog Requirements
conditions:
- or:
- "-title~=^feat"
- label=skip changelog
- label=need changelog
actions:
post_check:
title: |
{% if check_succeed %}
Changelog requirements are present.
{% else %}
Changelog requirements are missing.
{% endif %}
There are two pull request rules above. The first one will create a successful check-run on GitHub if the pull request’s title follows the Conventional Commit rule. The second one will create a successful check-run if the pull request is a feature with a mandatory changelog label. If the conditions don’t match, Mergify will create a failed check-run on GitHub and won’t merge the pull request, as these check-runs are set as mandatory in our merge queue configuration.
What we have to do now is to add an entry in the changelog every time a pull request tagged with need changelog
is merged. At Mergify, we use GitHub Actions to create new pipelines. So we wrote a simple Action able to create entries in a Notion Database.
It’s a simple Python script that uses the Notion public API. Everyone can use it with a GitHub workflow like the following.
name: Changelog sync
on:
pull_request_target:
branches:
- main
types:
- closed
- labeled
permissions: read-all
jobs:
changelog_sync:
if: >
github.event.pull_request.merged == true
&& contains(github.event.pull_request.labels.*.name, 'need changelog')
runs-on: ubuntu-latest
steps:
- name: Synchronize changelog
uses: Mergifyio/gha-changelog-syncer@main
with:
NOTION_API_KEY: ${{ secrets.CHANGELOG_NOTION_API_KEY }}
NOTION_DATABASE_ID: ${{ secrets.CHANGELOG_NOTION_DATABASE_ID }}
And that’s it! Once a feature is merged, the GitHub Action workflow adds the pull request’s title, description, and merge date to the Notion database. The new entry is not published by default. The Product Owner can still rework the title and the description, choose a cool emoji, and then check the Visible
checkbox to publish the change.
Once again, process automation proves its worth: on the one hand, the Mergify team no longer has to update the changelog and write numerous posts about new features, and on the other, users have much better visibility of the development of new features.
This type of automation eases the mental load on the technical team, helping them to be more productive while delivering real added value for Mergify users.
What an automated life!