Changelog Automation within Gitlab


Bicycle

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:

{:class="table table-bordered"}

Commit messageRelease type
feat(next-version): add configuration options for accountingFeature 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.

 1version:
 2  stage: version
 3  image: registry.gitlab.com/mbuchleitner/go-semrel-gitlab:v0.21.1
 4  script:
 5    - git fetch --tags
 6    - release next-version --bump-patch > .next-version
 7  artifacts:
 8    paths:
 9      - .next-version
10  except:
11    - 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.

 1compile:
 2  stage: build
 3  script:
 4    - echo "some artifact using version " > artifact
 5    - cat .next-version >> artifact
 6    - echo "RELEASE_URL=https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/$CI_JOB_ID/artifacts/release" > build_info
 7    - echo "RELEASE_DESC=\"$(uname -mo) binary\"" >> build_info
 8    - echo "RELEASE_SHA=$CI_COMMIT_SHA" >> build_info
 9    - echo "RELEASE_VERSION=$(<.next-version)" >> build_info
10  artifacts:
11    paths:
12      - build_info
13      - artifact
14  except:
15    - 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.

 1release:
 2  stage: release
 3  image: registry.gitlab.com/mbuchleitner/go-semrel-gitlab:v0.21.1
 4  script:
 5    - git fetch --tags
 6
 7    - rm -f release_info
 8    - mv build_info release_info
 9    - . release_info
10
11    - echo -n "update version information v$RELEASE_VERSION ..."
12
13    - release changelog
14    - release commit-and-tag CHANGELOG.md release_info
15    - release --ci-commit-tag v$RELEASE_VERSION add-download-link --name release --url $RELEASE_URL --description "$RELEASE_DESC"
16  only:
17    - 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:

1 <!--- 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.

Go Back explore our courses

We are here for you

You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.

Contact us