azure-devopsazure-pipelines

Pull request trigger is not returning the target branch name in Azure Devops


I am trying to clone the target branch ( main ) when PR is opened from feature branches. However I am facing System.PullRequest.SourceBranch: command not found error

pipeline code

pr:
 - '*'

pool:
  vmImage: 'ubuntu-latest'

stages:
  - stage:  PRValidation
    displayName:  PR Validation
    jobs:
    - job: CloneTargetBranch
      displayName: 'Clone Target Branch on PR'
      steps:
        - task: Bash@3
          displayName: 'Debug PR Variables'
          inputs:
            targetType: 'inline'
            script: |
              echo "PR Target Branch : $(System.PullRequest.TargetBranch)"
              echo "PR Source Branch : $(System.PullRequest.SourceBranch)"
              echo "Build Source Branch: $(Build.SourceBranch)"
              printenv | sort

        - task: Bash@3
          displayName: 'Clone Target  Branch'
          env:
            TARGET_BRANCH: $(System.PullRequest.TargetBranch)   # PR Target branch
            ACCESS_TOKEN: $(System.AccessToken)
            REPO_URL: $(Build.Repository.Uri)
          inputs:
            targetType: 'inline'
            script: |
              echo "Cloning Target Branch: ${TARGET_BRANCH#refs/heads/}"

              # Clone the target branch
              git -c http.extraheader="Authorization: Bearer $ACCESS_TOKEN" \
              clone "$REPO_URL" --branch "${TARGET_BRANCH#refs/heads/}" --single-branch /tmp/target-branch

              echo "Cloning completed successfully!"

code someone throw some light on what is missing in the pipeline code ?


Solution

  • Few things to unpack:

    If you're using a git repository in Azure DevOps and you want this pipeline to run as part of a pull request, you need to setup a branch policy for the target branch (branch you are merging into) and set this pipeline up as a Build Validation.

    Regarding why you're seeing this error, prior to execution of your script, the system replaces the contents of your inline script with the values from the Predefined Variables. It then writes the resulting content to a temporary file and then executes it. In your case, the $(System.PullRequest.SourceBranch) variable does not exist because it's not executing as part of a build validation pipeline, so the literal value $(System.PullRequest.SourceBranch) is written into this temporary file. Because this is a bash script, bash is trying to execute this as command-substitution syntax $(<expression>) and "System.PullRequest.SourceBranch" isn't a command that bash recognizes.

    Also, for context... when a pipeline runs as part of a pull request (build validation), Azure DevOps creates a temporary branch /refs/pull/<pr-id>/merge which contains the latest from the target branch and your changes in the source branch. Unless you explicitly add checkout: none step to your pipeline all pipelines automatically clone the repo for the triggering commit. I mention this because the steps you've included in your question are done for you automatically so maybe this will save you some time.