Table of Contents
Over the years as I’ve participated in Agile software development projects, I’ve noticed a common thread of ambiguity, discontent, lack of care, or just plain forgetfulness when it comes to application versioning. I would look at the latest release of the application by analyzing its version and have a hard time understanding what has truly changed. Does the version have meaning that can be deciphered easily? Most of the time, it doesn’t appear so.
There were times where the version wasn’t even incremented while significant changes were made. As a Product Owner peering into the looking glass, how can you tell if version Y is truly different than version X if they both have the same version numbers? Having a system that allows you to identify meaningful change as software is built in an iterative process is extremely important. Therefore, adopting a versioning strategy that makes it easy for stakeholders to track change is essential.
The Semantic Versioning Specification
In order to bring meaningful information to software versions, Tom Preston-Werner created the Semantic Versioning Specification. The premise is simple – break up the version into subsets which designate a type of meaningful change. This involves the concept of major, minor, and patch versions separated by periods (e.g. major.minor.patch or 1.0.0). If a breaking change has occurred, meaning the public API has changed and is no longer compatible with the previous version, the major version should be incremented. In addition, if a new feature has been added which doesn’t break the public API, the minor version should be incremented. Finally, if a bug has been fixed or performance has been increased which doesn’t break the public API, the patch version should be incremented.
When organizations adopt Semantic Versioning, if done properly, meaningful and intelligent decisions can be made by looking at application versions throughout the Software Development Lifecycle (SDLC). However, humans make mistakes; we aren’t perfect. Therefore, having a process that automates application versioning and promotes a standard which clearly identifies the type of change being made is highly desirable.
Determining the Version from Meaningful Changes
Rather than making developers think about what the version will eventually be, instead make them think about each change (and its impact) that is introduced into the source control repository (in this case Git). As a best practice, each update that is introduced into the repository should be for a disparate change. In other words, if a new Login Screen has been created, all files, code, and work associated with this change should be lumped into one commit. It is bad practice to have one commit with multiple changes not belonging to the same situation (e.g. user story, bug, etc.).
When developers are able to properly label what change is being made to the repository, some wonderful things can happen. If the types of changes are being rubber stamped on each commit message, meaningful information can be determined to provide proper insights into the observed change.
For starters, when looking at the overall commits that belong to a repository, it is possible to truly understand what changes have been made. This is in part by associating a change type with each commit and by analyzing the commit message. When a change type is associated with a commit message, other possibilities emerge.
Say Hello to Eagle Versioner
In order to enforce a common standard which labels each disparate change by category which can then be used to automatically determine the version, I have developed a cross-platform/open-source application which uses a simple CLI built in Node.js named Eagle Versioner. It provides three important areas of functionality.
First, it can be used to make specialized commits which include tags inspired by Angular’s Commit Message Convention inserted into the commit message identifying the type of change that has been made and any special properties. Adopting Eagle Versioner among your development teams and initiating an edict to enforce the use of the tool (and the concepts within) will ensure a certain set of standards is followed so that meaningful information can be obtained by looking at commit messages.
Also, when creating commits using the vanilla Git CLI, a common issue is typos/spelling errors. This can take away from the professionalism of the software product at large and should be avoided. Therefore, Eagle Versioner includes a spell checker as a part of creating these specialized commits (interactive mode only) that ensures commit messages are spelled correctly.
The information contained in these commit messages can be used to automatically determine the version. Eagle Versioner will parse the commit history and based on which tags exist in applicable commit messages, the version can be calculated. This is powerful because developers will no longer need to think about what the version will be and rather only what tangible changes are being made.
In order for all of this to work, the minimum requirement is making sure each developer on the team uses Eagle Versioner to create commits, selecting the proper change type, and adding the relevant information. If the commit history in the repository contains the tags created by this command, then Eagle Versioner will be able to calculate the version.
Best of all, Eagle Versioner can be incorporated into any modern CICD pipeline and perform the version calculation automatically when a pull request has been made or a merge has taken place, taking the result and then changing the file(s) with the version data, and performing any other desirable task applicable to a version change. This will take the responsibility of incrementing the version away from the developers which is one less thing for them to worry about. However, developers can still do this work themselves if they want to and if the proper logic is setup in the CICD pipeline, it will detect that the version shouldn’t be incremented since it has already been done by the developer.
Just like calculating the version based on the commit message history, Eagle Versioner can also use the same information to generate or update a changelog. This works by parsing the commit message history and adding commits to the changelog which would affect the version. No longer will developers have to write the changelog themselves and can rely on Eagle Versioner to do it for them.
In addition, this too can also be automated and included in a CICD pipeline so the developers never have to think about the changelog again. This frees up developers to focus on more important things such as finishing their assigned user stories and adding value to the product being built/maintained.
Quickly Getting Started
Getting started with Eagle Versioner is easy. First, ensure Node.js is installed along with NPM and the latest version of Git (at least v2.22.0). Then, install Eagle Versioner by running the command npm install -g eagle-versioner. The -g flag will ensure it is installed globally so the main ev command can be accessed anywhere on the terminal.
Since Node.js is cross-platform, Eagle Versioner will work on any operating system supported by it. This means developers working on Windows or Mac can use it as well as the CICD pipeline running on Linux.
I’m very excited to share Eagle Versioner with you and hear your feedback. Adopting semantic versioning brings important meaning to any application version and no longer will you need to guess whether a breaking change was made, a new feature was added, or if a bug was fixed solely by looking at the incorrectly formatted version.
Finding ways to improve developer productiveness is important for any project. Simplifying versioning and other tasks associated with it will free up developers to work on more important things. Therefore, I highly encourage you to adopt Eagle Versioner and use it while developing your projects. If used correctly, it will save you time and money and provide more accurate information to provide better insights for stake holders and developers alike.