Automatic release generation based on commit message history with GitLab
The objective is to automatically generate a changelog based on the commits and to feed the GitLab release notes with this changelog.
Requirements
The automatic generation of the changelog will be based on the commit messages and requires the use of the standard Conventional Commits.
This standard defines a list of prefixes for your commit messages to help categorize them.
Available prefixes are fix:
, feat:
, docs:
, style:
, refactor:
, etc.
Once the right prefix has been chosen, just add a short description for this commit.
This description will then be used in the changelog.
Example: feat: automatic release note generation based on commits
.
Generate the changelog with git-cliff
Now that our commit history is clean and follows the Conventional Commits convention, we will be able to generate the changelog and for that we will use git-cliff.
Introduction to git-cliff
git-cliff is a tool whose objective is to generate the changelog by taking the commits and providing the result in Markdown format.
Commits are grouped according to version and type of commit (fix:
, feat:
, etc.).
A git-cliff
Docker image allows you to run it locally with the following command from the root of your Git project:
docker run --rm -t -v $(pwd)/.git:/app/ orhunp/git-cliff
An example of result file:
# Changelog
## [unreleased]
### Features
- Automatic release note generation based on commits
## [1.0.0] - 2022-06-23
### Features
- Initial commit
- Creating a Hadoop TDP cluster on AWS
### Styling
- Update font-color
- Update profil picture
It is possible to customize the result by modifying the configuration file to translate or modify the titles associated with each of the categories.
For more information on customizing the result, please refer to the project’s README git-cliff.
Integration in a GitLab pipeline
In order to automate the generation of this changelog, we will add a job in the GitLab pipeline:
build:changelog:
stage: build
image:
name: orhunp/git-cliff:latest
entrypoint: [""]
before_script:
- apt update
- apt install -y git
- export PREVIOUS_TAG=`git describe --abbrev=0 HEAD~`
- echo ${PREVIOUS_TAG}
script:
- |
if [ -z "${PREVIOUS_TAG}" ]; then
git-cliff -c config/cliff.toml > CHANGELOG.md
else
git-cliff -c config/cliff.toml -r . ${PREVIOUS_TAG}.. > CHANGELOG.md
fi
needs: []
cache:
key: ${CI_COMMIT_REF_SLUG}-CL
policy: push
paths:
- CHANGELOG.md
variables:
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
GIT_DEPTH: 0 # avoid shallow clone to give cliff all the info it needs
By default, the git-cliff tool generates the complete changelog.
As we only want to have the changelog of the current version, we retrieve in the variable PREVIOUS_TAG
the previous tag with the command git describe --abbrev=0 HEAD~
.
Then we just need to specify to git-cliff
that we want to generate the changelog from the previous tag to the current commit.
The result file in Markdown format is then added to the pipeline cache.
Generation of the release
The last step in our pipeline once the changelog file is generated is to create the release. To achieve it, GitLab provides a dedicated image that will be perfect for our use:
deploy:release:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
before_script: []
script:
- echo 'running release_job'
needs: [
"build:changelog",
]
cache:
key: ${CI_COMMIT_REF_SLUG}-CL
policy: pull
paths:
- CHANGELOG.md
release:
name: '${CI_COMMIT_TAG}'
description: 'CHANGELOG.md'
tag_name: '${CI_COMMIT_TAG}'
ref: '${CI_COMMIT_TAG}'
rules:
- if: $CI_COMMIT_TAG
The changelog file generated during the previous step is then extracted to feed the description of the release.
Note that if the build:changelog
job was executed at each commit pushed to the GitLab repository, we have here logically limited the execution of the deploy:release
job to the presence of a tag.
Conclusion
Thanks to these two jobs, which can be added to any GitLab pipeline, it is possible to automatically create a release with the changelog of your project.
All you have to do is to take care of the commit messages to allow you to have a perfect changelog associated with the releases!