Changelog Automation within Gitlab

published in: DevOps Cloud Native HashiCorp Continuous Integration Date: February 11, 2020
Martin Buchleitner, Senior IT-Consultant

About the author

Martin Buchleitner is a Senior IT-Consultant for Infralovers and for Commandemy. Twitter github LinkedIn

See all articles by this author

Changelog Automation within Gitlab

As a developer it is not your favorite duty to write changelogs according to the tagging which was done in a code repository. So the best idea is to automate the process of updating changelogs based on the commit messages which ( should ) already describe what changes came into the repo since the last merge into master or tagging a version.

For this you can use semantic releases.

semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.

This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification.

This process can now be used for terraform modules, chef cookbooks or any other software releasing process.

How does it work? Commit message format

semantic-release uses the commit messages to determine the type of changes in the codebase. Following formalized conventions for commit messages, semantic-release automatically determines the next semantic version number, generates a changelog and publishes the release.

By default semantic-release uses Angular Commit Message Conventions. The commit message format can be changed with the preset or config options Tools such as commitizen or commitlint can be used to help contributors and enforce valid commit messages. Here is an example of the release type that will be done based on a commit messages:

Commit message Release type
feat(next-version): add configuration options for accounting Feature Release
fix(accounting): accounting configuration options bug

fixxes #1234
Patch Release
refactor(accounting): removing accounting configuration

BREAKING CHANGE: Configuration options removed for accounting
Breaking Change

In some implementation of semantic releases it is also possible to customize those flags. In our current example we chose go-semrel-gitlab which supports this adaptions, but it is not used in any of our setups right now.

Gitlab CI example

Within our upcoming pipeline we gonne use 3 stages: version, build and release. The release stage should only run when running in master.

Version estimation

In our initial step a version estimation is done and stored into an artifact .next-version. This file is restored on the next runs to reuse its content for stamping your binary with this build information. In our example we just generate another artifact build_info which holds some sample data to inspire you what can be done and used for your application workflow.

The git fetch --tags is only mandatory on gitlab because of this issue within gitlab runner which does not fetch this information on creation.

  stage: version
  image: registry.gitlab.com/mbuchleitner/go-semrel-gitlab:v0.21.1
    - git fetch --tags
    - release next-version --bump-patch > .next-version
      - .next-version
    - tags

Building code

At the building step you can now use the information to stamp your application with the correct version number, commit sha and build job information.

  stage: build
    - echo "some artifact using version " > artifact
    - cat .next-version >> artifact
    - echo "RELEASE_URL=https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/$CI_JOB_ID/artifacts/release" > build_info
    - echo "RELEASE_DESC=\"$(uname -mo) binary\"" >> build_info
    - echo "RELEASE_SHA=$CI_COMMIT_SHA" >> build_info
    - echo "RELEASE_VERSION=$(<.next-version)" >> build_info
      - build_info
      - artifact
    - tags

Releasing code

Now we are within the most relevant part of this blog post - generating version tags and update the changelog with some auto-magic. If we are using this workflow on code which does not produce a binary output which can/must be stamped we could also skip the previous build steps from this post and only add this last one.

In this sample we rename the build information artifact as release information, then generate an updated changelog about the latest changes and afterwards commit our changed and tag those with the automaically generated version. As a bonus step also a download link for the current release is generated within gitlab.

For some use cases you might also want to update some meta information files ( e.g. metadata.rb on chef cookbooks ) and commit those changes with the changelog.

  stage: release
  image: registry.gitlab.com/mbuchleitner/go-semrel-gitlab:v0.21.1
    - git fetch --tags

    - rm -f release_info
    - mv build_info release_info
    - . release_info

    - echo -n "update version information v$RELEASE_VERSION ..."

    - release changelog
    - release commit-and-tag CHANGELOG.md release_info
    - release --ci-commit-tag v$RELEASE_VERSION add-download-link --name release --url $RELEASE_URL --description "$RELEASE_DESC"
    - master

When you start a fresh project or at least start with fresh changelog you are perfect fine now. But if you already got a changelog within your code repository you need to adapt it and add a line into the markdown:

 <!--- next entry here -->

With this marker the automation is able to find the insertion of the changes. You must review the used implementation how this marker is named.