Search code examples
azure-devopsazure-pipelinesazure-pipelines-yaml

azure yaml pipeline - name property from variables template file


I have several build pipelines that have the same name property pattern:

name: $(date:yy).$(minorVersionPrefix)$(date:MMdd)$(rev:.r)

Instead of defining it in every file, I wanted to use global variables template yaml file and get build name defined from that file.

So what I would like to have is, in the pipeline yaml:

name: $(buildName)
variables:
- template: global.yaml

And inside global.yaml:

variables:
  minorVersionPrefix: '0'
  buildName: $(date:yy).$(minorVersionPrefix)$(date:MMdd)$(rev:.r)

The problem is that the syntax inside the global.yaml file does not work. I also tried template syntax but, for example, date is not defined there (variables.date is null).

Is there a way to generate build name globally and inject it as a variable value, or maybe it is possible to set name variable pattern from global variable as string in pre-processing phase so it is then interpreted as if it was in the pipeline file?


Solution

  • Confirm that the date variable is unavailable in Variable templates. However, we can use the counter function in variable templates. It evaluates a number that is incremented with each run of a pipeline.

    For example:

    Variable template Yaml: vars.yml

    variables:
    - name: major
      value: '1'
    - name: minor
      value: '0'
    - name: patch
      value: $[counter(format('{0}.{1}-{2}', variables['major'], variables['minor'], variables['Build.SourceBranchName']), 1)]
    

    azure-Pipelines.yml

    name: $(major).$(minor)-$(patch).$(Build.SourceBranchName)
    
    trigger: none
    
    variables:
    - template: templates/vars.yml  # Template reference
    
    pool:
      vmImage: Windows-latest
    
    steps:
    - script: |
        echo xxx
    

    In this way we still have to add the name in every yaml file. But we just need to adjust the value of the variables in template. It will apply the values to all pipelines using the variable template.

    The build number is set like this:

    enter image description here

    Alternately, we can add a steps template with a script extending Pipelines functionality to update the build number by running logging command. See I want to do something that is not supported by expressions. What options do I have for extending Pipelines functionality?.

    For example:

    Steps template: global.yml

    steps:
    - task: PowerShell@2
      displayName: 'Preparing Build Number'
      inputs:
        targetType: 'inline'
        script: |
          #Set the minorVersion prefix per your requirement
          $minorVersionPrefix = "0" 
          Write-Host "minorVersionPrefix:" $minorVersionPrefix
          Write-Host "Original BuildNumber:" $(Build.BuildNumber)
          Write-Host "BuildId:" $(Build.BuildId)
          
          #splits the $(rev:.r)
          $MAJOR_RUN=$(echo $(Build.BuildNumber) | cut -d '.' -f1)
          echo "This is the major run number: $MAJOR_RUN"
          echo "##vso[task.setvariable variable=major]$MAJOR_RUN"
    
          $MINOR_RUN=$(echo $(Build.BuildNumber) | cut -d '.' -f2)  #By default, if you do not explicitly set the pipeline name with custom format, the value should be $(rev:.r) value. So we can set it as revision.
          echo "This is the minor run number: $MINOR_RUN"
          echo "##vso[task.setvariable variable=minor]$MINOR_RUN"
          
          #Set date variables
          $currentDate = $(Get-Date)
          $year = $currentDate.Year
          $month = $currentDate.Month
          $day = $currentDate.Day
          Write-Host $currentDate
          
          #Set new buildNumber
          $buildNumber = "$year.$month.$day.$minorVersionPrefix.$MINOR_RUN"
          Write-Host "Setting the name of the build to $buildNumber."
    
          #Update the buildNumber with the new value
          Write-Host "##vso[build.updatebuildnumber]$buildNumber"
    

    azure-pipeline.yml:

    trigger: none
    
    pool:
      vmImage: Windows-latest
    
    steps:
    - template: templates/global.yml
    

    In this way we do not need to add name in pipelines, the script will update the buildNumber automatically using the patterns defined in the script. So, we just need to update the patterns in global.yml to make it take effect.

    The build number will be updated like this:

    enter image description here enter image description here

    UPDATE:

    The included variable template can only be used to define variables but cannot pass variables. See Variable reuse for details.

    We can use variables inside of templates and can be used in expressions only, but doesn't include $(date) and $(rev:.r), they are not available here. See How can I use variables inside of templates? for details.

    The simplest way for you is to only set the minorVersionPrefix: '0' in variable template (global.yml). Then use the name: $(date:yy).$(minorVersionPrefix)$(date:MMdd)$(rev:.r) in your pipelines. Thus, you can control the minor version in global.yml.