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 onecurrent
: used to extract the current versionhelp
: used to print the usage of thevesion
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 versionextract
: used to extract a section from the changelog associated with a specific versionhelp
: used to print the usage of thechangelog
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 sectionstitle
is the title used when generating the changelogmatcher
is the string that the commit changelog trailer has to contain in order to match the sectionbump
tells the tool which section of the version to bump when a commit changelog trailer matches the sectionpriority
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