GitLab Flavored Semantic Versioning

Goal

This project tries to achieve automatic semantic versioning not basing the version bump on the conventional commits standars, but rather on a Changelog value on the trailer of commit messages.

This works well if a project follows a similar workflow to the one used at GitLab, where each change must not be made on a development branch, never on the release branch and needs to get merged through a merge request.

The beauty of this project is that you don't need to use the conventional commits specification, so you can have commits more similar to

Added new feature A to address this requirement

instead of

feat(<type>): added new feature A to address this requirement

This translates to:

  • no "wasted" characters for that message prefix
  • more readable commit messages
  • a nicer Changelog

    New features:
    - Added new feature A to address this requirement
    - Added feature B
    

vs

```plaintext
New features:
- feat(<type>): added new feature A to address this requirement
- feat: added feature B
```

Setup

The only tool you need to setup this project on your local environment is Ruby, which can be downloaded using asdf. The Ruby version required is 3.2.4.

Once Ruby is present on your system you can install the dependencies by running

bundle install

Testing

At the moment there's no built-in testing platform, but I'm planning to use rspec to add unit tests.

Usage

Installation

This project is available as a Ruby gem, so to be able to use it is enough to run

gem install gfsm

Once that command completes, the gem will be available and you can invoke it from the command line with

gfsm help

Important: git must be avaiable on the system for the gem to work.

The main way this project can be used though, is inside a CI pipeline where you can invoke it to bump the version and/or update the changelog.

To facilitate this, a docker image is published with every release of this tool. Here is a list of all the available images.

Available commands

The main commands available are:

  • gfsm version: this command takes care of the project's verioning.
  • gfsm changelog: this command takes care of the project's changelog.
  • gfsm help: this command will display the available commands and their usage.

To use these commands, you can invoke the gfsm executable from the command line. For example:

gfsm version <subcommand>
gfsm changelog <subcommand>

gfsm version

The version command has its own subcommands:

  • bump: used to bump the version to the next one
  • current: used to extract the current version
  • help: used to print the usage of the vesion command itself

All subcommands are configurable through either CLI flags or environment variables, that have precedence over the CLI flags.

CLI flag Environment variable Accepted values Default Description
--force FORCE_BUMP If there are no commits with a changelog trailer, the version will still be bumped.
--force-version FORCE_BUMP_VERSION major, minor, patch patch If the version needs to be force-bumped, this flag instructs the tool which section of the version to bump.
--prerelease PRERELEASE Turns on prerelease generation, which by default appends -pre to the generated version.
--prerelease-name PRERELEASE_NAME Any string without whitespaces pre When prerelease generation is enabled, this overrides the default pre value appended as suffix to the generated version.
--configuration CONFIGURATION_FILE A file path ./gfsmrc.yml The path to the YAML configuration file.
--path REPOSITORY_PATH A folder path . The path to the folder containing the Git repository.
--from FROM_COMMIT A commit SHA or a tag name The latest reachable tag The commit SHA or the tag name from where to start scraping for commit messages.
--to TO_COMMIT A commit SHA or a tag name HEAD The commit SHA or the tag name where to stop scraping for commit messages.
--initial-version INITIAL_VERSION A semantic version value 0.0.0 The version used when the project doesn't have one yet, useful for the first initialization of the project.

gfsm changelog

The changelog command has its own subcommands:

  • generate: used to generate a changelog for the latest version
  • extract: used to extract a section from the changelog associated with a specific version
  • help: used to print the usage of the changelog command itself

All subcommands are configurable through either CLI flags or environment variables, that have precedence over the CLI flags.

The changelog command supports all the flags and environment variables of the version command, with the following additions.

CLI flag Environment variable Accepted values Default Description
--output-file OUTPUT_FILE A file path The path to the CHANGELOG.md file, which will be created if not existing. If not specified the changelog will be written to stdout. Only usable with generate.
--input-file INPUT_FILE A file path ./CHANGELOG.md The path to the CHANGELOG.md file. Only usable with extract.
--no-incremental NO_INCREMENTAL When provided, the output file will always be overridden and will contain only the changelog entries for the latest version.
--only-new-entries ONLY_NEW_ENTRIES When provided, the output will always be written to stdout and will only contain the changelog for the latest changes without the version header.
--extract-version EXTRACT_VERSION A version name When provided, this specifies the version that extract will extract the release notes from. If not provided, or set to latest, it will extract the release notes from the latest version.

Configuration

GFSM can be cofigured by providing a YAML configuration file which will contain informations about the supported changelog trailers, the section they belong to and their priority.

The schema is the following:

change_types:
  <identifier>:
    title: string
    matcher: string
    bump: major|minor|patch
    priority: number

Where:

  • <identifier> is used only to separate the different sections
  • title is the title used when generating the changelog
  • matcher is the string that the commit changelog trailer has to contain in order to match the section
  • bump tells the tool which section of the version to bump when a commit changelog trailer matches the section
  • priority is used to order the sections when generating the changelog, the higher the priority the higher up the section will be in the changelog

Here is an example:

change_types:
  new_features:
    title: "New features"
    matcher: added
    bump: minor
    priority: 6
  feature_removals:
    title: "Feature removals"
    matcher: removed
    bump: major
    priority: 5
  deprecations:
    title: "Deprecations"
    matcher: deprecated
    bump: minor
    priority: 4
  feature_changes:
    title: "Feature changes"
    matcher: changed
    bump: minor
    priority: 3
  fixes:
    title: "Fixes"
    matcher: fixed
    bump: patch
    priority: 2
  security_fixes:
    title: "Security fixes"
    matcher: security
    bump: patch
    priority: 1
  other:
    title: "Other"
    matcher: other
    bump: patch
    priority: 0