Skip to content
Snippets Groups Projects

Semantic Versioning with Gitlab CI/CD

This document contains the guidelines for integration and usage of the semantic versioning with Gitlab CI/CD components for versioning the outcomes of the Emerald Project.

Table of contents

Semantic Versioning

Semantic versioning is a versioning system that allows to define the version of a software component based on the changes that have been made to it. The version number is composed of three numbers separated by dots: MAJOR.MINOR.PATCH. The version number is increased based on the following rules:

  • MAJOR version is increased when incompatible changes are made to the software component.
  • MINOR version is increased when new features are added to the software component in a backwards-compatible manner.
  • PATCH version is increased when backwards-compatible bug fixes are made to the software component.

semver.org provides a detailed explanation of the semantic versioning system.

Semantic Release CI/CD

Semantic Release is a tool that automates the versioning and release of software components. It uses the commit messages to determine the type of changes that have been made to the software component and automatically increases the version number based on the changes that have been made.

It offloads the responsibility of versioning and releasing software components from the developers, allowing them to focus on writing code and making changes to the software component. Managing the versioning and releasing of software components can be a time-consuming and error-prone process, as it may involve manually updating the version number in multiple places, creating release notes, and publishing the software component in different places.

Semantic Release automates this process by analyzing the commit messages that have been made to the software component and determining the type of changes that have been made. It then increases the version number based on the changes that have been made and creates release notes that describe the changes that have been made. It also publishes the software component to different places, such as a package registry or a container registry.

Semantic Release with Gitlab CI/CD

We have integrated the Semantic Release tool with Gitlab CI/CD to automate the versioning and releasing of software components within the Emerald gitlab framework. To achieve this, we have adapted the TBC CI/CD pipeline to include the Semantic Release tool in our gitlab instance. The adapted components are available in our CI/CD Catalogue in the Component Semantic Release.

Usage

The usage of the Semantic Release CI/CD component involves two main steps: Installation and Releasing.

Installation

To install the Semantic Release CI/CD component, you need to add the following configuration to your .gitlab-ci.yml file:

  - component: git.code.tecnalia.com/smartdatalab/public/ci-cd-components/semantic-release/gitlab-ci-semrel@master
    inputs:
      semantic-release-job-tags: ["docker"]
      auto-release-enabled: true
      branches-ref: "/^(master|main)$/"

Appart from the configuration in the .gitlab-ci.yml file, you can also add a .releaserc.yaml file to the root of your repository if you require a specific configuration for the semantic release. The .releaserc.yaml file is a JSON file that contains the configuration for the semantic release tool. The configuration file can be used to specify the plugins that should be used by the semantic release tool, the branches that should be released, and other options that are available. The configuration file is optional, and if it is not present, the semantic release tool will use the default configuration. For example, if you want to include CHANGELOG generation in the release process, you can add the following configuration to the .releaserc.yaml file:

plugins:
  - '@semantic-release/commit-analyzer'
  - '@semantic-release/release-notes-generator'
  - '@semantic-release/gitlab'
  # generates the CHANGELOG.md
  - '@semantic-release/changelog'
  - - '@semantic-release/git'
    - assets:
        - 'CHANGELOG.md'
      # the commit MUST trigger a pipeline on tag (to perform publish jobs)
      # can be skipped on prod branch
      message: 'chore(semantic-release): release ${nextRelease.version} - [ci skip on prod]'
branches:
  - main
  - master
tagFormat: '${version}'

Besides, the installation of the Semantic Release CI/CD component requires some additional settings to be performed in the gitlab project settings. The following settings are required to be set in the gitlab project settings:

  • Generate a project access token with the api and write_repository scopes. The token should be stored in the gitlab CI/CD settings as a secret variable with the name GITLAB_TOKEN and it requires an account with the Maintainer role in the project. The variable can be set as protected and masked, but this is optional. The protected requires to work with the protected branches settings in the project.
  • Depending on the release custom configuration it may be problematic to use the protected tags feature. In this case, the protected tags feature should be disabled in the project settings. To set the protected tags feature Maintainer role is required in the project.
  • Another good to have setting is to disable the the "Squash commits" feature in the project settings. We use to configure it in an Allow mode. When the commits are squashed, the semantic release tool may not be able to determine the type of changes that have been made to the software component. To set the "Squash commits" feature Maintainer role is required in the project.

To see the full configuration, you can check a current instalations in:

Releasing

In this section we will explain how to trigger a new release of your software component using the Semantic Release CI/CD component. The release process is triggered by creating a commit with a specific message that describes the type of changes that have been made to the software component. The commit message should follow the Conventional Commits specification, which defines a set of rules for writing commit messages that describe the type of changes that have been made to the software component.

  • fix: this is the most common type of change, and it is used when a bug fix has been made to the software component. The fix type is used when a backwards-compatible bug fix has been made to the software component. For example, if a bug has been fixed in the software component, the commit message should start with fix: followed by a brief description of the bug that has been fixed.
    this will trigger a patch release of the software component, increasing the PATCH version number by one. The new version number will be MAJOR.MINOR.PATCH+1. For example, if the current version number is 1.0.0, the new version number will be 1.0.1.
    Example:
git commit -m "fix: fixed a bug in the software component"
  • feat: this type of change is used when a new feature has been added to the software component. The feat type is used when a backwards-compatible new feature has been added to the software component. For example, if a new feature has been added to the software component, the commit message should start with feat: followed by a brief description of the new feature that has been added.
    this will trigger a minor release of the software component, increasing the MINOR version number by one. The new version number will be MAJOR.MINOR+1.0. For example, if the current version number is 1.0.0, the new version number will be 1.1.0.
    Example:
git commit -m "feat: added a new feature to the software component"
  • BREAKING CHANGE: this type of change is used when an incompatible change has been made to the software component. The BREAKING CHANGE type is used when a backwards-incompatible change has been made to the software component. For example, if an incompatible change has been made to the software component, the commit message should start with BREAKING CHANGE: followed by a brief description of the incompatible change that has been made.
    this will trigger a major release of the software component, increasing the MAJOR version number by one. The new version number will be MAJOR+1.0.0. For example, if the current version number is 1.0.0, the new version number will be 2.0.0.
    Example:
git commit -m "BREAKING CHANGE: made an incompatible change to the software component"

NOTE: When merging, take care that the "squash commit" option is disabled. The squashed commits remove the commit messages, and the semantic release tool will not be able to determine the type of change been made to the software component.