Changelog Unleashed: Mergify's Leap into Automated Feature Announcements

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.

Charly Laurent

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.

Mergify's Changelog

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!

We do deliver on Friday! Why not?

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.

The Conventional Commit check-run
The Changelog Requirement check-run

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.

GitHub - Mergifyio/gha-changelog-syncer
Contribute to Mergifyio/gha-changelog-syncer development by creating an account on GitHub.

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!