Automatic Releases & Changelogs
For one of my clients, Transform Studios, I built what is essentially a Statamic Starter Kit, but as an addon. This allows us to update sites easily via composer update
.
One of our current challenges is that we want to be more transparent with our customer with regards to updates and enhancements; to do that we want a dashboard page that shows the latest changes to their site.
However, creating a changelog manually is error prone and takes a while, so I wanted to automate as much as possible.
My end goal was a changelog that conformed to the Keep a Changelog format, as well as a release with the same information, driven by Github Actions, all from the usual PRs and tags.
For this to happen:
- PRs need to be categorized as features or bugs, so they can be separated in the release note
- Release note needs to include every PR since the last release
- Changelog should mirror the release note
To label the PRs, I found Timon van Spronsen's PR Labeler Action. You can configure it, but used the defaults, and set it to run whenever a PR was opened:
name: PR Labeler
on:
pull_request:
types: [opened]
jobs:
pr-labeler:
runs-on: ubuntu-latest
steps:
- uses: TimonVS/pr-labeler-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Next up is creating a draft release, because I wanted to be able to see what the notes looked like before the release was published. For that I found the amazing Release Drafter. This action takes the categorized PRs and creates sections (Changed/Fixed, etc) with the PR titles, author(s) and PR link. This action has many config options, but again, I kept it simple:
name: Release Drafter
on:
pull_request:
types: [closed]
permissions:
contents: read
jobs:
update-draft-release:
if: github.event.pull_request.merged == true
permissions:
contents: write # for release-drafter/release-drafter to create a github release
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Note that there is no merged
Github event so you have to run it on closed
but check to see if the PR was merged vs closed.
Lastly, when I push a (versioned) tag, like v3.4.5
, the release should be published and the changelog updated. This one was the most complicated because it's gotta do a few things:
- Get the draft release
- Update the release title and attach it to the pushed tag
- Update the changelog from the release note
- Commit the updated changelog.
I started with Cardinalby's Get Release action, to get the release id. Then I use Github's script action to update the release (I couldn't find an existing action that let me attach the release to a tag).
After that I found a pair of Stefan Zweifel's actions, stefanzweifel/changelog-updater-action
and stefanzweifel/git-auto-commit-action
that update the changelog based on the release note and commit it:
name: Release
on:
push:
tags: ['v*']
jobs:
update-changelog:
runs-on: ubuntu-latest
steps:
- name: Get Draft Release
uses: cardinalby/git-get-release-action@v1
id: latest_draft_release
env:
GITHUB_TOKEN: ${{ github.token }}
with:
draft: true
latest: true
- name: Update Title and Publish Release
id: publish_release
uses: actions/github-script@v6
with:
script: |
github.rest.repos.updateRelease({
draft: false,
name: '${{ github.ref_name }}',
owner: context.repo.owner,
repo: context.repo.repo,
release_id: ${{ steps.latest_draft_release.outputs.id }},
tag_name: '${{ github.ref_name }}'
})
- name: Checkout code
uses: actions/checkout@v3
- name: Update Changelog
id: update_changelog
uses: stefanzweifel/changelog-updater-action@v1
with:
latest-version: ${{ github.ref_name }}
release-notes: ${{ steps.latest_draft_release.outputs.body }}
- name: Commit updated Changelog
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: main
commit_message: Update CHANGELOG
file_pattern: CHANGELOG.md
You can see the release note it produces and the changelog. It was my test repo so yours will look nicer I'm sure.