azure-devopsazure-pipelines-yamlbuild-numbersuser-variablesazure-devops-services

Variable counter not working in YAML pipeline when it is part of the build name


I want to give a meaningful name to the build run by enriching it with the version of the application being built (Example: Major.Minor.Patch.Revision, where "Revision" is a counter)

So, in classic pipelines I configured the BuildNumber as (Edit classic pipeline-->Options--> Build number format) :

$(app.version.number).$(app.version.rv)+$(date:yyyyMMdd)$(rev:.r)

This way, with the following values (Edit classic pipeline-->Pipeline variables)

app.version.number = 1.5.0
app.version.rv = $[counter(variables['app.version.number'], 100)]

We can see the title of each build runs startarting with: "#1.5.0.1xx+20221007.1 • <Team's commit message>" - 1xx means 100, 101, 102... as the counter defines it, and the BuildId as usual (with an expected behaviour, it always ends in ".1").

In YAML pipelines I do almost the same but without the counter:

variables:
- name: version.major
  value: 7
- name: version.minor
  value: 0
- name: version.patch
  value: 0  
- name: 'app.fullVersion'
  value: '${{variables[''version.major'']}}.${{variables[''version.minor'']}}.${{variables[''version.patch'']}}'
...
...
# Build number
##############################################################
name: '$(app.fullVersion)+$(Date:yyyyMMdd).$(Rev:r)' 

An the output name of the builds are like: "#7.0.0+20211103.3 • <Team's commit message>"

Now, I want to introduce the revision counter to the version as I am doing in classic pipelines but it is not working. It just prints the name of the variable or counter definition, not its value.

This is the approach (I tried different ones, all without success):

variables:
- name: version.major
  value: 7
- name: version.minor
  value: 0
- name: version.patch
  value: 0  
- name: version.rv
  value: $[counter(format("{0}.{1}.{2}", variables['version.major'], variables['version.minor'], variables['version.patch']), 0)]
- name: 'app.fullVersion'
  value: '${{variables[''version.major'']}}.${{variables[''version.minor'']}}.${{variables[''version.patch'']}}.${{variables[''version.rv'']}}'
...
...
# Build number
##############################################################
name: '$(app.fullVersion)+$(Date:yyyyMMdd).$(Rev:r)'     

And the name of the build run is like: #7.0.0.$[counter(format('{0}.{1}.{2}', variables['version.major'], variables['version.minor'], variables['version.patch']), 0)]+20231005.1 •

I tried different ways of declaring the counter, not using the format function and counting over app.fullVersion variable, etc. without success. Any clues will be appreciated in how to solve it.

I apologize if the answer already it is in this library but I could not find it yet. Thanks in advance.


Solution

  • Upon checking your description, there seems to be some misunderstanding on the ways to reference variables.

    Kindly note that, template expression variables ${{ variables.var }} get processed at compile time, before runtime starts, while runtime expressions $[variables.var] also get processed during runtime but are intended to be used with conditions and expressions.

    For variable app.version.rv, its value is defined by runtime expressions; for variable app.fullVersion, we cannot go back to compile time to use template expression and evaluate its value.

    In addition, since we need to use counter function to define variable app.version.rv and this function is not recognized in template expression, we should opt to use runtime expressions to define both app.version.rv and app.fullVersion. Here is an example for your reference.

    name: '$(app.fullVersion)+$(Date:yyyyMMdd).$(Rev:r)'
    
    variables:
    - name: version.major
      value: 7
    - name: version.minor
      value: 0
    - name: version.patch
      value: 0
    - name: app.version.rv
      value: $[counter(format('{0}.{1}.{2}', variables['version.major'], variables['version.minor'], variables['version.patch']), 0)]
    - name: app.fullVersion
      value: $[format('{0}.{1}.{2}.{3}', variables['version.major'], variables['version.minor'], variables['version.patch'], variables['app.version.rv'])]
    
    steps:
    - script: |
        echo "The app.verison.rv is $(app.version.rv)"
        echo "The app.fullVersion is $(app.fullVersion)"
    
    

    enter image description here

    Besides, similar to your variable usage in classic pipeline, we can directly use the other variables directly as the build number without using app.fullVersion.

    name: '$(version.major).$(version.minor).$(version.patch).$(app.version.rv)+$(Date:yyyyMMdd).$(Rev:r)' 
    

    See the documents below for more guidance.

    Template expressions - Azure Pipelines | Microsoft Learn

    Define variables - Azure Pipelines | Microsoft Learn

    Expressions - Azure Pipelines | Microsoft Learn

    Pipeline run sequence - Azure Pipelines | Microsoft Learn