3

I have the following variable in my pipeline script:

variables:
  is_main: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]

And I want to use it like this:

- script: npm run build -- --source-map=$(is_main)

Unfortunately that leads to an error because "True" is not allowed:

> ng build "--source-map=True"

Cannot parse arguments. See below for the reasons.
    Argument --source-map could not be parsed using value "True".Valid type(s) is: boolean
##[error]Bash exited with code '1'.
Finishing: Angular build

I need to lowercase the boolean, and I want to do so in the script step to keep the variable in the pipeline as a true boolean (as opposed to a string) until the last possible moment. I've tried several options. To summarize:

Option 1 $(is_main) leads to:

Argument --source-map could not be parsed using value "True".Valid type(s) is: boolean

Option 2 $[lower($(is_main))] leads to:

lower(True): syntax error in expression (error token is "(True)")

Option 3 $[lower(variables('is_main'))] leads to:

 lower(variables('is_main')): syntax error in expression (error token is "(variables('is_main'))")

Option 4 $[lower(variables['is_main'])] leads to:

 lower(variables['is_main']): syntax error in expression (error token is "(variables['is_main'])")

Option 5 ${{ lower(variables.is_main) }} (which should not work as far as I could tell from documenation, because it is not used for runtime evaluation, but hey....) leads to:

eq(variables['build.sourcebranch'], 'refs/heads/main'): syntax error in expression (error token is "(variables['build.sourcebranch'], 'refs/heads/main')")

I've read through the "Expressions" documentation on Azure Pipelines MSDN pages and my above attempts are based on it already.

What is the proper way to convert a boolean variable in an Azure Devops pipeline to a lowercase string to be used inside a script step?


Footnote:

For now I use this workaround:

variables:
  is_main: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
  generate_source_maps: $[lower(variables['is_main'])] # script step requires lowercase boolean

And use it like this:

- script: npm run build -- --source-map=$(generate_source_maps)

Quite suboptimal because generate_source_maps is a string whereas the name suggests it's a boolean, and the conversion to lowercase happens very far from the place in the yml where it is relevant and obvious that this is needed. But it works.

Jeroen
  • 60,696
  • 40
  • 206
  • 339

2 Answers2

3

My team and I encountered a similar problem just now [A], and convertToJson worked for us as a way to convert a Pipeline boolean value to lowercase string literal.

Since your initial value is a non-static variable, I don't think you can inline this expression into your script line though [B] - you probably still need an extra variable.

Perhaps this would work for you?

variables:
  is_main: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
  is_main_str: $[convertToJson(variables['is_main'])]

- script: npm run build -- --source-map=$(is_main_str)

[A]: Specifically, we wanted to pass a Pipeline parameter value of type boolean to an ARM template parameter via overrideParameters on an AzureResourceManagerTemplateDeployment@3 task.

[B]: According to the docs, Compile time expressions can be used anywhere; runtime expressions can be used in variables and conditions., and only runtime expressions can access non-static variables. Looks like the $() macro syntax cannot evaluate an expression.

pmalmsten
  • 426
  • 3
  • 3
1

Use boolean variable as lowercase string in Azure Devops YML pipeline script

You could try to below scripts:

variables:
  is_main: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]

- script: npm run build -- --source-map=$(echo "$(is_main)" | tr "[:upper:]" "[:lower:]")

If above not work for you, please try to use below scripts:

variables:
  Branch: $[eq(variables['Build.SourceBranch'], 'refs/heads/Dev_Test5')] 
  is_main: $(echo "$(Branch)" | tr "[:upper:]" "[:lower:]")

- script: npm run build -- --source-map=$(is_main)
Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • Thanks for your advice. Can confirm the first one works. – Jeroen Apr 04 '22 at 06:34
  • Can you explain why/how it works? Possibly tell me where to find the documentation on this? The [expressions documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops) doesn't show anything on this, does it perhaps rely on doing the lowercase conversion with some shell magic instead of yml? – Jeroen Apr 04 '22 at 06:36
  • 1
    Ah, yeah, I reckon it comes from [this POSIX way of doing things](https://stackoverflow.com/a/2264537/419956)? – Jeroen Apr 04 '22 at 06:38
  • @Jeroen, Yes, I also refer from it. Glad to know that help you, you could accept it as answer. – Leo Liu Apr 04 '22 at 06:49
  • 1
    Cheers. I did upvote your answer and am grateful, but I think I will stick with my initial workaround which I found a tad more maintainable, while I wait/hope for an alternative answer that's YML / DevOps based. (I really hope there's just a syntax I missed allowing me to inline my workaround in a task.) – Jeroen Apr 04 '22 at 06:53
  • 1
    @Jeroen, I got you. I tried it, but there seems to be no such method, looking forward to whether other community members will give surprises. – Leo Liu Apr 04 '22 at 07:07
  • Agreed! And thx again for your help, much appreciated ! – Jeroen Apr 04 '22 at 07:11