Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

GitVersion and GitHub with Azure DevOps build yaml

Posted on May 3, 2019

I like the idea that a build definition is code and can go under source control. Azure DevOps already has change control of build definitions so this outcome does not necessarily have to use Git. There is one scenario where the traditional build definition does not satisfy this though. It is when the state of the code in a branch requires different build logic than the code in another branch. The build yaml in Git is perfect for this.

One of the things I wanted to achieve when using build yaml was to get versioning to work they way I want it to. It took a lot of trial and error but I am happy with the results. This is how it works. I have GitVersion.yml under source control that defines how a build will come up with a version. The first thing that the build yaml needs to do is execute GitVersion in the build.

- task: GitVersion@4
  displayName: 'GitVersion'
  inputs:
    updateAssemblyInfo: true

Easy done.

Next I want the build number to use the NuGetV2 version generated by GitVersion because I don’t like the version format they use by default. This took a long time to get right.

The way this works is that a command executed in the build than renders a log output in the right format can update the build number. This is documented here and uses the following command:

##vso[build.updatebuildnumber]my-new-build-number

The primary issue with getting this to execute in a yaml pipeline is that # is a comment marker. I went through so many attempts to get this to work. Here is the one that finally landed the result.

- script: echo %Action%%BuildVersion%
  displayName: 'Set build version'
  env:
    Action: '##vso[build.updatebuildnumber]'
    BuildVersion: $(GitVersion.NuGetVersionV2)

The trick here is to put the ## combination required by the command comment into a variable and then use that variable as an input to the command that will then echo the result out to the build log. Now we have GitVersion coming up with the build and the build number reflecting the desired value.

Another outcome I wanted was to create a GitHub release for a build. In this scenario, I only want the GitHub release to be created for a master branch build. This is done by setting a condition that the current branch is refs/heads/master. I also wanted to mark the GitHub release with the prerelease flag. This is done by checking if the NuGetVersionV2 version number has a pre-release suffix on it.

- task: GitHubRelease@0
  inputs:
    gitHubConnection: 'GitHub'
    action: 'create'
    tagSource: 'manual'
    tag: 'v$(GitVersion.NuGetVersionV2)'
    title: 'v$(GitVersion.NuGetVersionV2)'
    isPreRelease: contains(variables['GitVersion.NuGetVersionV2'], '-')
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))

Creating the GitHub release was so simple using this step and the outcome was fantastic. It created the release with all the commit history related to the release and the packaged build output from the artefacts directory.