Just Another Day

Automate those version numbers.

It's actually quite plausible to automate a lot of your manual, pre-CD, pre-CI setup, especially if you have the right tools. Automation is kind of key, especially when you are dealing with multiple projects and microservices, plus maintaining CD\CI pipelines, the build process, testing, package and releasing. There are three extensions I'd like to introduce you too, all unique, but can be made to work together to achieve quite a special goal.

I have created a few simple Azure DevOps build and release extensions to help me. They are all free, available on Visual Studio Marketplace, with the source code available on GitHub. Using these extensions, In a few simple steps, I'm able to automate the following steps:

  1. Increment my app's current version.
  2. Apply new version number to FileVersion.
  3. Apply new version number to AssemblyVersion.
  4. Ensure .Net pack uses your new version number when generating new packages.
  5. Make sure all new bugs that are sent to Bugsnag include the new version number.
  6. Finally, notify Bugsnag of my latest release, and it's new version number.

What this ultimately means is, I can check in my code, letting the CD\CI pipelines takeover, without giving thought to updating version numbers in my settings files or project files. I also don't need to figure out whether or not Bugsnag is associating my bugs to the correct AppVersion after release.

So, without any further ado, let me make my first introduction.

Build Task 1: Auto App Version

The first Build Task I want to introduce you too is Auto App Version or AAV for short. You can check out the docs for AAV, but ultimately, what AAV does is, based on a "version mask", a previously saved version number, and a version value held within in your project file, generates a new version number each time you run your build pipeline. The new version number is then saved back into the app's project file and, saved in a variable defined by you, in your build definition Variables tab, which allows the value to persist between builds.

My example AAV configuration

AAV Configuration

By checking Set Assembly Version and Set File Version, in one foul swoop, I have updated my project file's Version, AssmblyVersion and FileVerion values with a shiny, new version number. Nice!

Build Task 2: Set Json Property

Next I want to introduce to Set Json Property. This extension quite simply let's me pick a json file, specify a property path within the json file, then set the value of the property for that path.

The file in question is my appsettings.json file, and the property, well thats Bugsnag's AppVersion property. The Bugsnag section in my appsettings.json file looks like this:

  "Bugsnag": {
    "ApiKey": "my-super-official-bugsnag-api-key",
    "AppVersion": "1.0.0",
    "AutoCaptureSessions": true

I want to update the AppVersion value, so my property path is Bugsnag.AppVersion

AAV allowed me to specify and Environment Variable, to which it saves the newly generated version number. In the example configuration for AAV above, for the field "Environment Variable", you can see I set MyEnvVar. Passing this variable to "Set Json Property" after choosing my appsettings.josn file and specifying my property path as Bugsnag.AppVersion ensures that the correct version number will also be used by Bugsnag after this build has been released.

Here's something:
Set Json Property will work for any json file, and pretty much allow you to target any property. Even if that property is part of a list of objects, or some other collection.

My example 'Set Json Property' configuration

SJP Example Config

You can see from the screenshot above, I am passing the environment variable created by AAV, MyEnvVar, to set the 'Property Value' field.

So, by this stage, our app's project file is up to date. The Version, FileVersion and AssemblyVersion elements all have the latest version number. This means if there's .Net pack task further upstream, the latest version number will be ready and used by the package process. Finally, our Bugsnag AppVersion setting has been updated. Any new bugs that are caught by Bugsnag after this release will also have the latest version tagged onto the payload. Win, win, win... win!

My build pipeline

Agent Jobs

Use task groups
To make your pipelines reusable, and help keep them tidy, you can group tasks together using Task Groups . In the above screenshot, 'Publish .Net Core 2.2 App' is a collection of 8 other common tasks such as restore, build, test and Publish.

We could leave it there, but there is one more optional task. Bugsnag provides some additional, rich information when you inform them of your release. If you go one step further and include source control and commit information, the experience is very rich indeed. So let's go ahead and set that up.

Build Task 3: Bugsnag Notify

Finally, I'm going to notify Bugsnag of my new release using Bugsnag Notify.


Bugsnag notify can be used from within a build pipeline, or release pipeline.

All The Piccies

My build pipeline

Auto App Version setup

Set Json Property setup

Auto App Version console output

Set Json Property console output

My Release pipeline

Bugsnag Notify setup

Bugsnag Notify source control setup (unofficial Azure DevOps Git provider)

Bugsnag Notify console output

Bugsnag release card

Bugsnag release meta card