How to specify triggers using variables in Azure DevOps Services pipeline yaml

8.1k Views Asked by At

The following azure pipeline code gives error

'A template expression is not allowed in this context'

variables:
  major: 2020
  minor: 3
  patch: 1
  major_minor_patch: $(major).$(minor).$(patch)

trigger:
- master
- Dev
- release/R${{variables.major_minor_patch}}
- release/${{variables.major_minor_patch}}/*

My intention is to use the major, minor and patch variables to specify the branches that would form the CI trigger, instead of hard coding it in the pipeline YAML.

  1. What am I missing because I can't find documentation which addresses my scenario?
  2. If what ever I am trying to do is unsupported, are there suggested ways of achieving the same?

Thanks

3

There are 3 best solutions below

1
On BEST ANSWER

Variables in trigger block is not supported. See document here for more information.

Trigger blocks can't contain variables or template expressions.

If you do not want the pipeline be triggered by other branches, you can try below workaround.

Create an additional pipeline to check if the source branch match release/major_minor_patch. And trigger the main pipeline in this additional pipeline.

variables:
  major: 2020
  minor: 3
  patch: 1
  triggerMain: false

trigger:
 branches:
   include:
    - releases/*
       
steps:
- powershell: |
     $branch = "$(Build.SourceBranchName)"
     if ($branch -match "$(major).$(minor).$(patch)") {
       echo "##vso[task.setvariable variable=triggerMain]True"  #set variable triggerMain to true if matches.
     }

- task: TriggerBuild@3
  inputs:
    definitionIsInCurrentTeamProject: true
    buildDefinition: '56'  #{id of your main pipeline}
    queueBuildForUserThatTriggeredBuild: true
    ignoreSslCertificateErrors: false
    useSameSourceVersion: true
    useSameBranch: true
    waitForQueuedBuildsToFinish: false
    storeInEnvironmentVariable: false
    authenticationMethod: 'Personal Access Token'
    password: '$(system.accesstoken)'
    enableBuildInQueueCondition: false
    dependentOnSuccessfulBuildCondition: false
    dependentOnFailedBuildCondition: false
    checkbuildsoncurrentbranch: false
    failTaskIfConditionsAreNotFulfilled: false
  condition: eq(variables['triggerMain'], 'True')

In above pipeline. It will be triggered first to check if the source branch match the farmat. And if it matches, then task TriggerBuild will be executed to trigger the main pipeline.

0
On

I had the same problem and my approach was something like this:

trigger:
  batch: true
  branches:
    include:
    - dev
    - master
    - releases/*

jobs:
  - job: Job    
    condition: eq(variables['Build.SourceBranch'], variables['TARGET_BRANCH'])
    steps: ...

On the same pipeline I make a conditional job, it gets fired on each branch but it only executes the steps in my target branch.

1
On

I haven't found the proof of that either, but I think this is the correct behavior by design. The trigger is something that initiates the run of the pipeline. Before this run is initiated, variables can't be calculated. When they can, it's already too late - the whole thing is triggered.

That's why, I think, you'll have to adjust and try to achieve your goal with wildcards only. If the pipeline should be triggered for release branches with versions in their names, perhaps this wildcard pattern might work: release/R?.?.?