hey
hey

Reputation: 3242

How to get a branch name with a slash in Azure DevOps?

Azure Devops offers two variables containing information about the current git branch name: $(Build.SourceBranchName) and $(Build.SourceBranch).

While SourceBranch contains the full reference to the branch, SourceBranchName is expected to contain only the short branch name.

Unfortunately, the behavior is a bit unexpected when the branch name contains a slash (/):

+---------------------------------------------------------------------------------------------------------+
| Situation                     | Git branch name  | Build.SourceBranch          | Build.SourceBranchName |
|---------------------------------------------------------------------------------------------------------|
| branch name contains no slash | mybranch         | refs/heads/mybranch         | mybranch               |
| branch name contains slash    | release/mybranch | refs/heads/release/mybranch | mybranch               |
+---------------------------------------------------------------------------------------------------------+

The part of the branch name before the slash is not considered as part of the branch name. My colleague pointed out that this is the documented behavior of Azure Devops:

Git repo branch or pull request: The last path segment in the ref. For example, in refs/heads/master this value is master. In refs/heads/feature/tools this value is tools.

I am not sure if this behavior is particularly useful: I want to checkout the branch, and need the branch name to include the slash. Also, If the part before the slash is stripped off, there might well be confusion about the actual path, as the name could be ambiguous.

I need the branch name including the slash. Is there any simple way to get it? Do I always have to work with the full ref in order to be on the safe side?

Upvotes: 58

Views: 67097

Answers (7)

JGutierrezC
JGutierrezC

Reputation: 4513

Extending from @TSR's answer, which is the accurate one actually, what worked for me was:

variables:
  - group: production-shared-variables
  - name: branch_name
    value: $[replace(variables['Build.SourceBranch'], 'refs/heads/', '')]

if I had it as he put in the snippet i was receiving the following error

/azure-pipelines.yml (Line: 15, Col: 5): Unexpected value 'branch_name'

Then in my steps i to checkout the branch, i have the following

- task: CmdLine@2
  displayName: 'Checkout branch'
  inputs:
    script: |
      cd $(Build.SourcesDirectory)/my_project

      git fetch origin $(branch_name) && git checkout $(branch_name)

Upvotes: 0

TSR
TSR

Reputation: 20416

You can use replace expression to remove refs/heads/ from Build.SourceBranch

  variables:
    BRANCH_NAME: $[replace(variables['Build.SourceBranch'], 'refs/heads/', '')]

Use like this (edited typo)

$(BRANCH_NAME)

Upvotes: 58

jdhao
jdhao

Reputation: 28359

I have a same needs, but I need to get the branch name in a bash script and run the script. Here is what I come up with:

# remove the "refs/heads/" part from the branch name
branch_name=${BUILD_SOURCEBRANCH#"refs/heads/"}

Notice that the predefined variable any.variable will be turned to env variable ANY_VARIABLE in the shell environment (source here). So the pre-defined variable Build.SourceBranch becomes BUILD_SOURCEBRANCH in bash script.

Upvotes: 0

kartik
kartik

Reputation: 2135

Can be used below in the azure-pipelines.yml

branch=$(Build.SourceBranch)
export branch=$(echo "${branch}" | sed 's/refs\/heads\///g')

Upvotes: 0

Oli Girling
Oli Girling

Reputation: 763

It's wild there is no proper solution to this yet.

Here is what we have, based on combining a few things I've found googling. This is for branches and PR's

variables:

  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}:
    BRANCH_NAME: $[ replace(variables['Build.SourceBranch'], 'refs/heads/', '') ]
    DOCKER_IMAGE_TAG: $[ replace(replace(variables['Build.SourceBranch'], 'refs/heads/', ''), '/', '_') ]

  ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}:
    BRANCH_NAME: $[ replace(variables['System.PullRequest.SourceBranch'], 'refs/heads/', '') ]
    DOCKER_IMAGE_TAG: $[ replace(replace(variables['System.PullRequest.SourceBranch'], 'refs/heads/', ''), '/', '_') ]

BRANCH_NAME will include the slash. So refs/heads/mybranch will be mybranch but refs/heads/feature/mybranch will be feature/mybranch.

Also added DOCKER_IMAGE_TAG here as we needed to replace the / with _ for docker images tags

Upvotes: 11

Shamrai Aleksander
Shamrai Aleksander

Reputation: 16018

I always use Build.SourceBranch in my scripts. Just assign it to a new variable and remove refs/heads/ from the start. I use only for CI and PR:

  1. For CI. I use Build.SourceBranch variable without refs/heads. I work with PowerShell:

$branchSource = "$(Build.SourceBranch)"
$branchSourcePath = $branchSource -replace "refs/heads/", ""

  1. For PRs. I use System.PullRequest.SourceBranch variable without refs/heads because Build.SourceBranch contains the path to the remote PR. The replacement is the same as in the first option just use the right variable.

$branchSource = "$(System.PullRequest.SourceBranch)"
$branchSourcePath = $branchSource -replace "refs/heads/", ""

Upvotes: 38

PatrickLu-MSFT
PatrickLu-MSFT

Reputation: 51093

When you build on a PR, you could use System.PullRequest.SourceBranch and System.PullRequest.TargetBranch variables.

System.PullRequest.TargetBranch

The branch that is the target of a pull request. For example: refs/heads/master. This variable is initialized only if the build ran because of a Git PR affected by a branch policy.

Use Predefined Build Variables

Besides, you could also define your own variable based on your needs if you want to use full or short path.

Just create a bash script that assigns the shorter branch name to a variable.

# Bash script
BRANCH_NAME=$(echo "$(System.PullRequest.TargetBranch)" | awk -F/ '{print $NF}')
echo "##vso[task.setvariable variable=PullRequest_Target_Branch;]$BRANCH_NAME"

Then you could reference $(PullRequest_Target_Branch) in your pipeline later.

Upvotes: 15

Related Questions