Search code examples
azureazure-devops

Azure Devops - extending from template using source pipeline branch


I am triggering a second pipeline from a first pipeline in another devops project - which is working fine. However I want to use the branch from the which the first pipeline is run from. For example if the first pipeline is triggered from a branch called "trigger-sample" the second pipeline should reference the same branch - the following pipeline echos refs/heads/trigger-sample which is correct, however the ci-cd-infrastructure/azure-pipeline-templates is used from refs/heads/master not refs/heads/trigger-sample even though I am using ref: ${{ variables['resources.pipeline.test-trigger-windows-service.sourceBranch'] }}.

The commented out lines dont work complaining that windows-service/test.yml@templates does not exist - it does as its a new file on that branch!!

resources:
  repositories:
    - repository: templates
      type: git
      name: ci-cd-infrastructure/azure-pipeline-templates
      trigger: 
        batch: true
      ref: ${{ variables['resources.pipeline.test-trigger-windows-service.sourceBranch'] }}

  pipelines:
    - pipeline: test-trigger-windows-service
      source: trigger-windows-service
      project: ci-cd-infrastructure
      trigger: true
pool:
    vmImage: ubuntu-latest
jobs:
- job: Display
  steps:
    - script: echo $(resources.pipeline.test-trigger-windows-service.sourceBranch)
# extends:
#   template: windows-service/test.yml@templates

Solution

  • Test the same YAML sample and I can reproduce the same issue.

    The variable: resources.pipeline.test-trigger-windows-service.sourceBranch will expand at runtime.

    And the ref field in the resource repo will expand at compile time.

    So the Pipeline resource variable is not able to pass to the ref field successfully.

    When the Pipeline is triggered by resource Pipeline, the ref field will get an empty value and it will use the master branch by default.

    I am afraid that there is no out-of-box method can directly meet your requirement(Get the resource branch from the Pipeline resource and pass the variable to the resource repo ref field).

    For a workaround, you can add a powershell task in first Pipeline to run the Rest API to trigger the pipeline and pass the source branch value to the second pipeline. The second pipeline can use parameters to accept the value and pass to the ref field.

    The Parameters Value can pass to ref field at compile time

    For example:

    First Pipeline:

    steps:
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $token = "$(pat)"
          echo $newvalue
          $url="https://dev.azure.com/orgname/projectname/_apis/pipelines/{PipelineID}}/runs?api-version=5.1-preview"
          
          $token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
          
          $JSON = "
          {
            
          
          
            `"resources`": {
              `"repositories`": {
                `"self`": {
                  `"refName`": `"refs/heads/master`"
                }
              }
            },
            `"templateParameters`": {
              `"refname`":`"$(Build.SourceBranch)`"
             },
          
          
          
          }"
          
          
          $response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json
    

    Second Pipeline:

    parameters:
    - name: refname
      type: string
      default: test
    resources:
      repositories:
        - repository: templates
          type: git
          name: ci-cd-infrastructure/azure-pipeline-templates
          trigger: 
            batch: true
          ref: ${{ parameters.refname }}
       pipelines:
        - pipeline: test-trigger-windows-service
          source: trigger-windows-service
          project: ci-cd-infrastructure  
          trigger: none
    pool:
      vmImage: ubuntu-latest
    
    extends:
      template: windows-service/test.yml@templates