For having a good overview of changes in the software lifecycle, it makes sense to use a software revision system like GIT to automatically generate a CHANGELOG. In order to do that, it is necessary to write appropriate commit messages.
Below you can find a sample configuration for GitLab CI/CD to automatically generate a CHANGELOG.md file on a push to the main branch. Also, an automatically versioning is implemented, based on Semantic Versioning.
For semantic versioning, a version number consists mainly of 3 digits: MAJOR.MINOR.PATCH. Each part of the version has a different meaning:
- MAJOR: An increased MAJOR means, that changes are incompatible with previous versions (breaking changes)
- MINOR: New features were implemented, but all are compatible with previous versions.
- PATCH: There are only bug fixes and no new features
Also, there are some suffixes for pre-releases, etc. For details, you can read the specification.
In order to automatically generate a CHANGELOG, it is necessary to have a Commit-Message-Convention. In our example, we will use the Conventional Commits. Obviously, there are other conventions too. The following setup is supporting some of them too – but you can also configure your own conventions.
The key facts of the Conventional Commits specifications are:
The commit message should be structured as follows:
<type>[optional scope]: <description>
The commit contains the following structural elements, to communicate intent to the consumers of your library:
- fix: a commit of the type
fixpatches a bug in your codebase (this correlates with
PATCHin Semantic Versioning).
- feat: a commit of the type
featintroduces a new feature to the codebase (this correlates with
MINORin Semantic Versioning).
- BREAKING CHANGE: a commit that has a footer
BREAKING CHANGE:, or appends a
!after the type/scope, introduces a breaking API change (correlating with
MAJORin Semantic Versioning). A BREAKING CHANGE can be part of commits of any type.
- types other than
feat:are allowed, for example @commitlint/config-conventional (based on the the Angular convention) recommends
test:, and others.
- footers other than
BREAKING CHANGE: <description>may be provided and follow a convention similar to git trailer format.
Additional types are not mandated by the Conventional Commits specification, and have no implicit effect in Semantic Versioning (unless they include a BREAKING CHANGE). A scope may be provided to a commit’s type, to provide additional contextual information and is contained within parenthesis, e.g.,
feat(parser): add ability to parse arrays.
Our goal is, to automatically generate a file called CHANGELOG.md on each commit to the main branch. In order to do that, we will use the tool semantic-release.
First, we will create a configuration file called .releaserc in the root folder:
With branches we define, which branches we’d like to generate a release. With the plugin section, we tell the tool, that commit messages should be analyzed with the conventionalcommits convention. Derived from the commit messages, it is determined, if the new release should be a Major, Minor, or just a Patch Release. The plugin release-notes-generator will generate the changelog-content. The Addon changelog is finally writing to the CHANGELOG.md file. git creates a commit with the new file. With the parameter message, you can define the commit-message. Noticeable is the text [skip ci]. With that, you can tell GitLab, to skip triggering the CI-Pipeline – because we do not want to create a new version just for the new CHANGELOG file.
Additionally, we create the following file, to actually start the automatic create for commits to the main branch:
With only: main we define, that the section should just be executed, if the commit was in the main branch. In the section before_script we install the necessary software components. In script we finally execute the generation.
In order to successfully execute the tasks, an Access Token needs to be assigned (In order to allow the CI-Task to do commits). A personal access token can be generated, as described here. In the project settings CI / CD in the sections Variables you have to add the access token with the key GITLAB_TOKEN. This Variable should be marked as Protected and Masked.
Initially, we will commit both files to the main branch with the following commit-Message:
feat: Initial commit
Demo repository for an automated generation of CHANGELOG.md and semantic versioning
The general workflow can be as following: During the normal development process, changes are pushed to development-Branches. After everything is ready, a Merge Request is created. After the Review it is merged to the main branch. In order to take over all changes, it is necessary to do not squash the commits.
On GitLab you can find a Demo-Repository with the described configurations: philipp.doblhofer/automatic-changelog-demo