5

I'm trying to insert an extra parameter in my pipeline based on a commit message fragment, running Azure DevOps Server 2020. I tried to implement it with the following code, without luck:

variables:
  - name: commitMessage
    value: $(Build.SourceVersionMessage)
steps:
  - template: myTemplate.yaml
    parameters:
      ${{ if contains(variables['commitMessage'], 'SPECIAL_MESSAGE') }}:
        specialParam: 'someValue'

During investigation, I found that the expressions behave somewhat unexpected:

variables:
  - name: commitMessage
    value: $(Build.SourceVersionMessage)
steps:
  - bash: | 
      echo "${{ variables['commitMessage'] }}"
      echo "${{ contains(variables['commitMessage'], 'SPECIAL_MESSAGE') }}"
      echo "${{ contains('test SPECIAL_MESSAGE', 'SPECIAL_MESSAGE') }}"

The script output is:

test SPECIAL_MESSAGE
False
True

The first line of the script outputs the commit message correctly. But the contains() function in the second line of the script seems to be unable to process the variable, even though the commit message contains the SPECIAL_MESSAGE, the expression returns False.

However, if I set my variable to a static string instead of the $(Build.SourceVersionMessage) variable, the expression returns True, and I am able to add the extra parameter:

variables:
  - name: commitMessage
    value: 'test SPECIAL_MESSAGE'

Any idea why the pipeline behaves like this, or how to make it work?

JSON Derulo
  • 9,780
  • 7
  • 39
  • 56

2 Answers2

1

You can change to like as below:

variables:
- name: commitMessage
  value: ${{ variables['Build.SourceVersionMessage'] }}

The expression '${{ variables['Build.SourceVersionMessage'] }}' would pass the value to the custom variable 'commitMessage' at compile time. This is equivalent to manually assigning the static value before running the pipeline.

And the expression '$(Build.SourceVersionMessage)' is at runtime.

I have tested with the expression '${{ variables['Build.SourceVersionMessage'] }}', it would be able to work as expected.

For more details, you can reference the document about "Understand variable syntax".

Bright Ran-MSFT
  • 5,190
  • 1
  • 5
  • 12
  • Unfortunately that doesn't work for me, the `commitMessage` variable becomes empty. Actually my first try was to work directly with the `Build.SourceVersionMessage` variable, like `${{ if contains(variables['Build.SourceVersionMessage'], 'SPECIAL_MESSAGE') }}:`, but for me it returns empty string. Any idea? Could it be a bug in Azure DevOps Server 2020? – JSON Derulo May 04 '22 at 08:32
  • I just learned from the [docs](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml) that the `Build.SourceVersionMessage` variable "is not extracted until the job had started and checked out the code", so I'm starting to think that what I'm trying to do is not possible. – JSON Derulo May 04 '22 at 08:43
  • Hi @JSONDerulo, When I used the expression `$(Build.SourceVersionMessage)`, I can get the same issue as you reported. After changing to the expression `${{ variables['Build.SourceVersionMessage'] }}`, the pipeline can work as expected. It's odd that it does not work in your pipeline. – Bright Ran-MSFT May 05 '22 at 08:16
1

The documentation states about the Build.SourceVersionMessage variable:

The variable is only available on the step level and is neither available in the job nor stage levels (i.e. the message is not extracted until the job had started and checked out the code).

This means that it's not possible to properly use this variable in compile time expressions, when it comes to conditionally inserting steps or parameters. There is a feature request to make this variable fully available at compile time: https://developercommunity.visualstudio.com/t/post/10029833

JSON Derulo
  • 9,780
  • 7
  • 39
  • 56