Semantic Versioning
By: Spokeo Engineering
Tags: Git, Software Engineering, Semantic Versioning, Jenkins, Software Development

Anyone who opens any software at all is familiar with versioning. It’s a concept people understand — newer versions of software have higher numbers. Think about all those iOS updates required for your iPhone. It might seem like a simple thing to come up with — each update comes with an increased number with the highest number being the most current version . For software development teams, this is not as simple as it seems.

Semantic Versioning Specification (SemVer) is a universal system for automating and tracking performance versioning of software. This framework for specifying changes uses a three-part number system in a major.minor.patch format. For example, version 4.7.6:

(4) Major version: API changes, backwards incompatible with previous versions

(7) Minor version: New features, functionality enhancement

(6) Patch: Bug fix, maintenance release

Think about what a version number actually means. Most people would understand that when the same software, version 4.7.7, is released, it’s not very different from version 4.7.6. However, version 5.0.0 is probably very different. For an agile development team releasing software frequently, it takes time and effort to get those versions right. Someone on the planning side has to make a decision about whether a change is big or small. Agile development organizations often try to embrace change more often, which requires constant evaluation to determine the version change when evaluating new software patches .

This system keeps development and QA cycles organized by removing the burden of centrally tracking the current version in progress for the pertinent application. SemVer provides a nice and clean way of tracing releases to versioned strings and associating those with certain enhancements or fixes to the application code itself. When a team is evaluating whether a given version is appropriate for them to use, they can trust that the numbers “summarize” the nature of the changes between versions. Version 5.0.0 is indeed much different than 4.7.6, so upgrading should be done with proper planning.

The SemVer System

At Spokeo, the engineer writing the code decides what constitutes a major, minor, or breaking change. They implement a ticket and commit that code to Git using “Conventional Commits,” which are a way of standardizing the notation of code changes. When the developer commits a change, it needs to be prefixed by the type of the change:

BREAKING CHANGE: Anything not be backwards compatible with previous functionality

feat: Adding something new

fix: bug fix

Conventional commit says that when automating semantic versioning, we have to map these different prefixes to the right parts of the versions. For example if “fix:” is part of a commit message in the version control’s pull request, then you should bump the Z in X.Y.Z.

Tools for SemVer Automation

Although someone could check the commit history to decide what a new version number should be, that’s hard to scale for the number of software projects and pretty boring! Spokeo automates this task away using Git, Jenkins, and Bumpversion. As developers are commiting code with Git, they include messages that can help decide version changes. Jenkins is configured to watch specific branches in all of our relevant repositories where we’ve implemented semantic versioning. It’s only watching specific branches because we only want to tag and update the X.Y.Z version strings that we planned on during a release. When Jenkins detects changes to the designated branch of the source repository, it kicks off scripts that make a version number update. Bumpversion actually keeps track of which number version is being deployed via its .bumpversion.cfg configuration file, which is in the same repository as the code and looks something like this:

The current version is specified by the “current_version” key inside this file. The other scripts Jenkins is running can modify this and then run bumpversion. Commit key tells bumpversion to commit the changes to Git after running “bumpversion” executable. This process ensures that files and changes are staged, committed and ready to be pushed upstream. Tag tells bumpversion to create a (git) tag in order to reference it later as the build/deploy associated with these code changes. If we looked back at the commit history after this runs, we would see that the bumperversion file changed. Now we know what version our freshly-baked release is.

Conclusion

To wrap things up, Spokeo is using semantic versioning in an automated fashion to facilitate tagging and naming of our applications. This process provides a nice and clean way of tracing releases to versioned strings and associating those with certain enhancements or fixes to software. Automating the versioning based on a developer’s commits means the developers are empowered to make the right choice for the version number, and no one has to slow down and crunch the math on what version should be released. The version number tells our developers what update they’re getting at a quick glance. Since we already had all the tools used in automation working in tandem with our QA and production environments, we could easily integrate everything once we had the initial workflow finalized. If you have any questions about setting up or maintaining Semantic Versioning, drop them in the comments below!

Follow us on Twitter, LinkedIn and Instagram!

Featured in Built in LA’s “100 Best Places to Work”

We’re hiring, check out our open jobs!

Author: