Working with a customer right now and trying to accomplish a number of tasks. First, is getting them accustomed to an enterprise branching strategy. The second, is helping them become familiar with Azure DevOps and configuring some build and deployment pipelines. The customer has their own versioning strategy – different across multiple projects – and they communicate with the business stakeholders features and resolved bugs in each release. Using a “one-size-fits-all” versioning configuration doesn’t work, and Azure DevOps only allows for a few custom placeholders in the Build Number. Luckily, Git-flow allows you to tag merges with custom versions so I simply had to configure Azure DevOps to use the latest tag on the
master branch for the build number.
Being that this isn’t a post about Git-flow, I’m not going to spend a lot of time on it. If you want more info, check out the cheatsheet or a great explanation by Atlassian.
Instead, as I stated in the first paragraph, I’m going to focus on how to use Git-flow tags for versioning in Azure DevOps.
If you are following the Git-flow process, you know that every time you finish a release or hotfix, a tag is placed on the
master branch. Of course, you’ll be pushing your tags from the local repository to the remote, as well. Essentially, what we’ll need to do is have Azure DevOps receive the latest tag and then apply it to the current build. Keep in mind that this build is building off of the
master branch and, therefore, assumes that a tag is present.
One final note…the customer I’m working with currently uses the version format ‘vX.X.X’ for this specific project. The code below takes the substring of that version starting with the second character. The resulting format is ‘X.X.X’.
Remove the Build Number
Azure DevOps will automatically set a build number format using the current date/time and a revision number. We don’t need any of that as we’re going to use our own. Additionally, if you leave the build number empty, the default build number will simply be the revision (which we’ll use in a second).
- In the build pipeline definition, click on the “Options” tab.
- Clear the textbox for the Build Number Format (second textbox) and leave it empty.
Now, we’ll use a PowerShell script to set the build number. Note, that you could use a bash script to do this, but, this particular customer was building a .NET Web Api so it made sense to use PowerShell.
- While still in the build pipeline definition, click on the “Tasks” tab.
- Add a new PowerShell task.
- Drag and move the new PowerShell task to the first task in the build configuration.
- Set the following configuration properties on the task:
Display name: Get Tag/Set Build Version
$git = "cmd.exe /C git describe --abbrev=0 --tags";
$tag = (Invoke-Expression -Command:$git).substring(1);
$rev = $env:BUILD_BUILDNUMBER;
$build = "$tag-$rev";
Write-Host "$("##vso[build.updatebuildnumber]") $($build)";
Here’s what’s going on in the script:
- PowerShell runs the
git command to grab the latest tag on the
- Get the substring (explained above) and strip out the preceding “v” from the tag (e.g. vX.X.X => X.X.X).
- Get the revision number from the Azure DevOps subsystem (read about this below).
- Create the newly formatted build number (e.g. X.X.X-XXX).
- Use the Azure DevOps output API to update the build number.
In the previous section, I explained that if we left the “Build Number Format” empty, then Azure DevOps would revert to the default build/revision number. Azure DevOps requires that each build have a unique build number. In our case, setting the build number to simply the last tag could cause a build failure if the build is attempted more than once for that tag. Therefore, we append the default build/revision number to our custom build number to ensure a successful build (at least in regards to the number, itself). My customer can still communicate the features and resolved bugs for the given build; they simply ignore the appended revision number.
While trying to figure this out took me quite a few hours (that last line in the code isn’t documented anywhere, grrrrhhhh!), the solution is very simple. If you decide to queue a build and monitor the logs simultaneously, you’ll see the build number update automatically after this task.