Devops YAML - set build name using expression

5.9k Views Asked by At

In a yaml build, is it possible to set the build name using an expression; it would be advantageous if I could match the release pipeline with the actual build id.

Example:

trigger:  
- master

variables:  
    major: 2  
    minor: 3  
    offset: 2000  
    bid: $[$build.BuildID -as [int] + $offset]

name: "$(major).$(minor).$(bid)"

4

There are 4 best solutions below

1
deadlydog On BEST ANSWER

You can use the UpdateBuildNumber command to dynamically set the name as part of a bash or PowerShell script.

For more details you can see this blog post, but the gist of it is something like this:

name: 'Set dynamically below in a task'

variables:  
    major: 2  
    minor: 3  
    offset: 2000

steps:
- task: PowerShell@2
  displayName: Set the name of the build (i.e. the Build.BuildNumber)
  inputs:
    targetType: 'inline'
    script: |
      [int] $buildIdWithOffset = ([int] $(Build.BuildId)) + ([int] $(offset))
      [string] $buildName = "$(major).$(minor).$buildIdWithOffset"
      Write-Host "Setting the name of the build to '$buildName'."
      Write-Host "##vso[build.updatebuildnumber]$buildName"
6
Yang Shen - MSFT On

The example won't work for syntax error.

You can check the MSDN doc Expressions and there's no mathematical operations like summation provided.

A better work around would be quiting the offset:

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  major: 2  
  minor: 3  
  #offset: 2000  

name: $(major).$(minor).$(build.BuildID)

This will return you the name as 2.3.101 for example.

1
Alex K On

There's yet another way to set the build number without using the scripts. The advantage of this method is that the build name is set from the beginning, unlike the script that changes the original name during the build. And the sequence number generation is cleaner (see the $(Rev:r) piece that works only in the "name" property of the pipeline.

You must use the "format" expression instead of ($Variable) syntax, because the build name is created during the Compile stage when the $(Variable) syntax does not work yet. Otherwise the variables will not be evaluated and will go into the build name as $(Variable).

name: '$(buildNumber).$(Rev:r)'
variables:
  majorVersion: '1'
  minorVersion: '0'

  ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
    buildNumber: ${{ format('{0}.{1}',  variables['majorVersion'], variables['minorVersion']) }}
  ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
    buildNumber: ${{ format('{0}.{1}.PR-{0}', variables['majorVersion'], variables['minorVersion'], variables['System.PullRequest.PullRequestId']) }}

More about expressions here: Azure Pipelines Reference

1
James Law On

If you want the use the generated expression to automatically increment the counter function (which can only be used as part of a variable declaration) for each unique value, you can use the following:

jobs:
- job: VERSION_BUILD
  displayName: Version Build
  variables:
    - name: pipeline_start_date
      value: $[format('{0:yyyy}-{0:MM}-{0:dd}', pipeline.startTime)]
  steps:
  - checkout: none
  - task: PowerShell@2
    name: generate_minor_version
    displayName: Generate Minor Version
    inputs:
      targetType: 'inline'
      script: |
        Write-Host "Pipeline start date is '$(pipeline_start_date)'."
        [int] $minorVersion = [math]::floor(((New-TimeSpan -Start '2022-02-01' -End '$(pipeline_start_date)').Days) / 14) + 1
        Write-Host "Minor version is '$minorVersion'."
        Write-Host "##vso[task.setvariable variable=minor_version;isOutput=true;]$minorVersion"
- job: VERSION_BUILD_2
  displayName: Version Build 2
  dependsOn:
  - VERSION_BUILD
  variables:
    - name: minor_version
      value: $[dependencies.VERSION_BUILD.outputs['generate_minor_version.minor_version']]
    - name: major_minor_version
      value: $[format('{0}.{1}', variables['major_version'], variables['minor_version'])]
    - name: build_version
      value: $[counter(variables['major_minor_version'], 0)]
  steps:
  - checkout: none
  - task: PowerShell@2
    displayName: Update Build Number
    inputs:
      targetType: 'inline'
      script: |
        Write-Host "Major-minor version is '$(major_minor_version)'."
        Write-Host "Build version is '$(build_version)'."
        [string] $buildNumber = "$(major_version).$(minor_version).$(build_version)"
        Write-Host "Setting the name of the build to '$buildNumber'."
        Write-Host "##vso[build.updatebuildnumber]$buildNumber"

This particular script calculates the $minor_version as the number of 2 week intervals (iterations) from a given point in time. So in theory, on every other Tuesday, the pipeline will increment the minor version of the build number by 1 and reset the build version of the build number to 0, which will then automatically increment for each subsequent build in that two-week period.