Search code examples
gitazure-devopscicdazure-pipelines-yaml

How can we specify the branch for Manual + PR builds in Resources:Repositories:Repository:Ref?


According to this documentation, the "Resources:Repositories:Repository:Ref" property supports template expressions, so that one can parameterize the ref property as follows:

resources:
repositories:
- repository: templates
   type: git
   name: Templates
   ref: ${{ variables['Build.SourceBranch'] }}

For our use case, this is so that we can check out the same branch across dependency repos in the pipeline:

MainRepo (develop) DependencyRepo1 (develop) DependencyRepo2 (develop)

or...

MainRepo (release) DependencyRepo1 (release) DependencyRepo2 (release)

Using ref: ${{ variables['Build.SourceBranch'] }} works great when the pipeline is triggered manually through the ADO GUI: if the develop branch is selected, the dependency repos also check out the develop branch and likewise for release.

The problem occurs with PR build triggers, since ${{ variables['Build.SourceBranch'] }} resolves to refs/pull/1/merge, rather than develop or release.

The dependency repos, naturally, do not have a corresponding refs/pull/1/merge branch, but even if they did, we want ${{ variables['Build.SourceBranch'] }} to resolve to the PR's target branch (either develop or release, so that the dependency repo's develop or release branch will also be checked out).

So, we have tried many ways to conditionally set the value for ref, for example, using a variable:

variables:
  - name: DependencyBranch
     ${{ if eq(variables['Build.Reason'], 'Manual') }}:
       value: $[variables.SourceBranchName]
     ${{ elseif eq(variables['Build.Reason'], 'PullRequest') }}:
       value: $[variables.System.PullRequest.targetBranch] *this sets the correct value for PRs
     ${{ else }}:
       value: develop

resources:
  repositories:
    - repository: templates
      type: git
      name: Templates
      ref: $(DependencyBranch)

This also works great for manual builds, but PR triggers still do not resolve the correct value.

Is there any way to implement support for checking out the same branch across dependency repos, for both Manual and PR builds?


Solution

  • According to predefined variables, we can use Build.SourceBranchName and System.PullRequest.targetBranchName to decide the DependencyBranch name.

    Please try the following yaml.

    variables:
    - name: DependencyBranch
      ${{ if eq(variables['Build.Reason'], 'Manual') }}:
        value: $(Build.SourceBranchName)
      ${{ elseif eq(variables['Build.Reason'], 'PullRequest') }}:
        value: $(System.PullRequest.targetBranchName)
      ${{ else }}:
        value: dev
    
    resources:
      repositories:
        - repository: library
          type: git
          name: CommonModules
          ref: $(DependencyBranch)
    
    steps:
    - checkout: library
    - ${{ if eq(variables['Build.Reason'], 'Manual') }}: 
      - script: |
          echo Build.Reason=$(Build.Reason)
          echo Build.SourceBranchName = $(Build.SourceBranchName)
          echo DependencyBranch=$(DependencyBranch)
    - ${{ elseif eq(variables['Build.Reason'], 'PullRequest') }}: 
      - script: |
          echo Build.Reason=$(Build.Reason)
          echo PullRequest.targetBranchName=$(System.PullRequest.targetBranchName)
          echo DependencyBranch=$(DependencyBranch)
    - ${{ else }}:
      - script: |
          echo Build.Reason=$(Build.Reason)
          echo DependencyBranch=$(DependencyBranch)