microsoft / azure-pipelines-yaml

Azure Pipelines YAML examples, templates, and community interaction
MIT License
1.19k stars 926 forks source link

Are multi-line template expressions possible? #533

Closed LachlanMarnham closed 3 years ago

LachlanMarnham commented 3 years ago

Dear community,

I have the following template expression inside a variables block:

${{ if and(eq(variables['Build.Reason'], 'IndividualCI'), startsWith(variables['Build.SourceBranchName'], 'test_')) }}

Which I would love to be able to write like this:

variables: 
  - name: version
       ${{ if 
             and(
                     eq(variables['Build.Reason'], 'IndividualCI'), 
                     startsWith(variables['Build.SourceBranchName'], 'test_')
                    ) 
       }}
         value: test
...

but after reading the documentation I was unable to work out how to do this.

Alternatively, I would be happy to instead write:

variables:
  - name: newCommits
     value: $[ eq(variables['Build.Reason'], 'IndividualCI') ]
  - name: isTestBranch
     value: $[ startsWith(variables['Build.SourceBranchName'], 'test_') ]
  - name: ${{ if and(variables.newCommits, variables.isTestBranch) }}

But I've had issues accessing variables.newCommits and variables.isTestBranch inside the templates. This doesn't fail per se, but does not give the correct behaviour (I think this is because the execution order of $[...] vs ${...} maybe?).

Are either of these two methods possible? Many thanks.

max-zaytsev commented 3 years ago

Hi @LachlanMarnham, multi-line template expressions are not supported. And, yes, there is some difference in expanding variables in Template expressions and Runtime expressions (Please see more details here)

In your case, I think you can try this:

variables:
  ${{ if eq(variables['Build.Reason'], 'IndividualCI') }}:
    newCommits: True
  ${{ if startsWith(variables['Build.SourceBranchName'], 'test_') }}:
    isTestBranch: True
  ${{ if and(eq(variables['newCommits'], True), eq(variables['isTestBranch'], True)) }}:
    version: Test
  ${{ if not(and(eq(variables['newCommits'], True), eq(variables['isTestBranch'], True))) }}:
    version: Prod
anatolybolshakov commented 3 years ago

@LachlanMarnham I'm closing this since it looks resolved - please feel free to ask any further questions.

quasarea commented 2 years ago

Yaml has multiline keys support, those should be wrapped with ?:

This works for me in my templates:

  - stage: Sign
    ? ${{ if or(
        in(parameters.BuildType, 'nuspec'),
        and(
          not(in(variables['Build.SourceBranchName'], 'master', 'main')),
          not(startsWith(variables['Build.SourceBranch'], 'refs/heads/support/')),
          not(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))
        )
      ) }}
    : displayName: Sign - Skipped
    ${{ else }}:
      displayName: Sign
    jobs:
      - ? ${{ if or(
            in(parameters.BuildType, 'nuspec'),
            and(
              not(in(variables['Build.SourceBranchName'], 'master', 'main')),
              not(startsWith(variables['Build.SourceBranch'], 'refs/heads/support/')),
              not(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))
            )
          ) }}
        : - job: Skipped
            steps:
              - checkout: none
      - ${{ else }}:
          - template: sign.yml