Build versioning made easy in Azure DevOps
Tags: azure, azuredevops, semver, devops
Published: 2021-09-17 20:41:15

# Introduction

Versioning is a very important part of creating, deploying and maintaining code. Having a understandable and readable version is required. 

Here are a few example of versioning systems:
- [SemVer](https://semver.org/)
- [Calendar Versioning (CalVer)](https://calver.org/)
- [Romantic Versioning (RomVer)](https://github.com/romversioning/romver)

And probably a few others are out there.  
I have only used the one that most people use: SemVer

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1uz09x2k1jcqqsg31xmq.png)
 
# The problem

I moved to [Azure DevOps](https://dev.azure.com) for building and releasing software.
After getting used to it there was one big thing that bugged me, the versioning of the builds and releases...

By default Azure DevOps uses `$(Date:yyyyMMdd).$(Rev:r)` as the build and release number.  

And that is something where you cannot do anything with...
Yes it is unique but there is absolutely no way for you to find out which build/release pipeline contained the version you wanted to look at.

The other issue I had was the fact that when building a PR the version that was used was the one from master/main (if branched from there) and most likely this version was already released. So creating an artefact for test deployment for instance would fail, it should be a unique version.

# The solution helper

So there must be a way to get the behaviour I wanted, after searching and searching I could not find an existing solution that was easy to use and wasn't polluting the templates.

So I created a little NPM module to help me: [simple-versioner](https://www.npmjs.com/package/simple-versioner)

## What it does

This helper reads the version from the file that contains the version, defaults to `package.json` 

There are two cases:
1. Stable release (ie: master, or other stable branch provided
It will use the version as is. IE `1.0.1`

2. Build is for a non stable branch and/or a Pull Request
The versioning specified will be postfixed with the branch name and the commit sha.
IE: `1.0.1-refs-heads-branch-8a9fee0b`

This way the version used in a Pull Request will always be unique, so that you can use the artefact.
And in the build pipeline overview you can easily find the build of your version:

![Screenshot 2021-09-17 at 22.14.29](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uuyodr6y6kfzvmao7qj.png)
 
*Extra bonus: It validates it the version already exists or not (git tag with that version exists) if it exists it will fail and therefor stopping the build*

## How you can use it

So hopefully I got your exited to also use it or at least give it a try. 

Well as the aim was to have a simple plugin, you only need to add two lines to your azure yml. (make sure to add it as one of the first tasks in your pipeline)

```yaml
- bash: 'npx simple-versioner'
  displayName: 'Get and set correct build version'
```
That's it. 
It will update the `Build.Buildnumber` parameter in Azure and the provided versioning file with the (new) correct version.

Done.

### Possible options

There are a few options available to customise the execution of the plugin. Please have a look at [simple-versioner](https://www.npmjs.com/package/simple-versioner) to see the latest possible options.

## For what can you use it?

Per default it expect a `package.json` that's because I created the plugin for that purpose.
But you can use it on any JSON file that has a `version` attribute.

So for instance the `vss-extension.json` which is used for Azure DevOps tasks.

Other files and or structure can easily be added, have a look at the code and PR's are welcome :) [simple-versioner](https://github.com/hvdb/simple-versioner)