Expressions are useful to calculate a value, sure.
Expressions are also useful in the places in YAML that explicitly support conditions, sure.
However, without the ability to do things conditionally based on the result of expressions, their usefulness is limited. For example:
It turns out this is possible using conditional insertion syntax, but it was extremely difficult to find because it's only documented in relation to templates. It should be documented, or at least referred to, in the documentation page for expressions, because a) it is actually not specific to using templates and b) this is the place you would be looking.
It works fine even without loading an external template to do this, for example, to conditionally set different properties of a task:
- task: DotNetCoreCLI@2
displayName: Package
inputs:
command: pack
packagesToPack: src/SomeProject/*.csproj
packDirectory: $(Build.StagingDirectory)
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
versioningScheme: byEnvVar
versionEnvVar: PACKAGE_VERSION
${{ if ne(variables['Build.SourceBranchName'], 'master') }}:
majorVersion: $(major)
minorVersion: $(minor)
patchVersion: $(patch)
versioningScheme: byPrereleaseNumber
It also works fine to do this to conditionally set variables:
variables:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
stackName: prod
${{ if ne(variables['Build.SourceBranchName'], 'master') }}:
stackName: dev
This information should not be buries in the documentation on templates, because it's not specific to templates and has more to do with expressions in general and how to apply them to do things conditionally.
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
On a related note (and I know this is more of a product feedback than a documentation issue) it's worth mentioning that it would be extremely useful to have an if() function available in the expression syntax.
So instead of:
variables:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
stackName: prod
${{ if ne(variables['Build.SourceBranchName'], 'master') }}:
stackName: dev
We could do:
variables:
stackName: ${{ if(eq(variables['Build.SourceBranchName'], 'master'), 'prod', 'dev' }}
It would also be very useful to have an else statement so we could do:
variables:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
stackName: prod
${{ else }}:
stackName: dev
This is VERY helpful. I bumped into this a while ago and couldn't find it again now that I need it.
One question: How would I use this to include/exclude an entire task (or even job)?
Example:
My first stage gets the 'latest' version to deploy to Smoke test but needs to maintain that version through the various other stages out to Production.
Well, to get variables from stage to stage I need to publish them as artifacts and then download them in the next stage.
As an audit process I need to use the same job template to deploy each environment. So I have to programatically add or exclude steps. Since I can't download an artifact that hasn't been published yet I need to know if this is stage 2 and only include the download task if it is. I know it has something to do with indentation but I'm not able to figure it out so far.
@DaRosenberg Thanks for pointing this out. I'm working on updating the docs. Can you post your product feedback to the developer community? That space is monitored by the product team.
@DaRosenberg, any idea why this works:
variables:
- ${{ if eq(variables['targetEnvironment'], 'dev') }}:
- template: variables.dev.yml
... this doesn't:
variables:
${{ if eq(variables['targetEnvironment'], 'dev') }}:
- template: variables.dev.yml
But then, as you say, this does?
variables:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
stackName: prod
@waltervos To be honest, I don't fully understand the semantics for when there should be leading hyphens and when there should not.
But my very uneducated guess would be something like this:
Most helpful comment
This is VERY helpful. I bumped into this a while ago and couldn't find it again now that I need it.
One question: How would I use this to include/exclude an entire task (or even job)?
Example:
My first stage gets the 'latest' version to deploy to Smoke test but needs to maintain that version through the various other stages out to Production.
Well, to get variables from stage to stage I need to publish them as artifacts and then download them in the next stage.
As an audit process I need to use the same job template to deploy each environment. So I have to programatically add or exclude steps. Since I can't download an artifact that hasn't been published yet I need to know if this is stage 2 and only include the download task if it is. I know it has something to do with indentation but I'm not able to figure it out so far.