Azure DevOps how to get custom build number format to YAML build pipelines?

Kamsiinov picture Kamsiinov · Dec 26, 2018 · Viewed 12.9k times · Source

I have a build number format "$(BuildDefinitionName)-$(Rev:.r)" which I can put into the visual designer options and it works great.

However, now I would like to start to use new YAML build pipelines but I cannot figure out how I could put that custom build number format in use with the "replace token" task.

Answer

jfarleyx picture jfarleyx · Aug 15, 2019

In addition to the chosen answer, you can also use the following function to apply a custom build number

steps:
  - script: echo "##vso[build.updatebuildnumber]$(CustomValue)"

As documented here: Azure DevOps Logging Commands

I found this helpful in my situation, where I wanted to read the semantic version from my binary and apply that to the name of the build.

Edit 2020-02-12:

To elaborate further regarding how you can leverage the updatebuildnumber function, here is an example of extracting the SemVer from a package.json file in a NodeJS API and using that to update the Azure DevOps build number. This example uses the yaml-style builds in Azure DevOps.

Example:

buildNumberUpdtaed

DevOps yaml script...

- job: GetSemVer
  displayName: Get Semantic Version from Application
  timeoutInMinutes: 3
  continueOnError: false
  steps:
  - task: NodeTool@0
    inputs:
      versionSpec: '12.13.0'
    displayName: Install Node
    continueOnError: false  
  - bash: |
      APPSEMVER=$(node -pe "require('./package.json').version")
      echo "##vso[task.setvariable variable=version;isOutput=true]$APPSEMVER"      
    name: App 

- job: CreateBuildVersion
  displayName: Create Build Identifier
  dependsOn: GetSemVer
  timeoutInMinutes: 2
  continueOnError: false
  variables:
    appVersion: $[ dependencies.GetSemVer.outputs['App.version'] ]
    buildIncrement: $[counter(variables['appVersion'], 0)] # create a counter that is used to increment build run for same app version
    buildVersion: "$(appVersion)$(optionalBuildTag)-$(buildIncrement)"
  steps:
    - bash: echo "##vso[build.updatebuildnumber]$(buildVersion)" # Update build number in Pipeline UI 

First, in job: GetSemVer, I extract the semantic version from the package.json and create a variable that will be passed to the next job...

- bash: |
  APPSEMVER=$(node -pe "require('./package.json').version")
  echo "##vso[task.setvariable variable=version;isOutput=true]$APPSEMVER"
name: App

Next, in job: CreateBuildVersion I use the app version from GetSemVer job to create a local variable, titled appVersion, a build-run counter, titled buildIncrement. The build-run counter is incremented each time a build is run for the same app semver. The counter will be included in the build number we will provide to Azure DevOps and helps avoid naming conflicts if we execute a build multiple times for the same app version.

appVersion: $[ dependencies.GetSemVer.outputs['App.version'] ]
buildIncrement: $[counter(variables['appVersion'], 0)] # create a counter that is used to increment build run count for same app version

Then, I construct a buildVersion variable, which is comprised of the app's semver, an optional build tag (e.g. "-alpha" for dev enviro) which is injected from an enviro variable in DevOps, and the build-run count. e.g. "1.1.6-alpha-0"

buildVersion: "$(appVersion)$(optionalBuildTag)-$(buildIncrement)"

Finally, I update the build number in azure by calling the build.updatebuildnumber function with my new buildVersion variable.

- bash: echo "##vso[build.updatebuildnumber]$(buildVersion)" # Update build number in Pipeline UI

Note: you can organize the steps above however you like. We separate getting the SemVer from constructing the buildVersion, because we use different languages and frameworks that make fetching the SemVer different from one app to the next. So, that step for us often changes. You could, however, do all of those steps in one "job".