March 2, 2016 · travis-ci

Getting the current branch name during a Pull Request in Travis

TLDR - here's the .travis.yml


Be careful about using the $TRAVIS_BRANCH environment variable to access the name of the current HEAD branch during a build. The description from Travis' Environment Variables page might surprise you:

For builds not triggered by a pull request this is the name of the branch currently being built; whereas for builds triggered by a pull request this is the name of the branch targeted by the pull request (in many cases this will be master).

For example, if you create a PR named ferrari destined for master, Travis will kick-off 2 builds:

continuous-integration/travis-ci/push - $TRAVIS_BRANCH=ferrari  
continuous-integration/travis-ci/pr - $TRAVIS_BRANCH=master  

The push build acts how you'd think, while the pr build has $TRAVIS_BRANCH set to master. Building off the assumption that this variable will always be set to the branch currently being built can have some nasty consequences.

Don't ask git

One would think that a simple git command is enough to determine the current branch name, and they'd be right:

$ git rev-parse --abbrev-ref HEAD

Unfortunately, according to Travis' Building Pull Requests page:

Rather than test the commits from the branches the pull request is sent from, we test the merge between the origin and the upstream branch.

This means PR builds are in a detached state, causing the command to return undefined:

$ git rev-parse --abbrev-ref HEAD

Fortunately there is a way.

The .travis.yml recipe

Travis has finally added the environment variable $TRAVIS_PULL_REQUEST_BRANCH, which according to the docs contains:

the name of the branch from which the PR originated, if the current job is a pull request

We can use this variable in conjunction with $TRAVIS_BRANCH and $TRAVIS_PULL_REQUEST to determine the current branch:

language: go

  - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)

This creates an environment variable $BRANCH that is consistent between push and pr builds:

continuous-integration/travis-ci/push - $TRAVIS_BRANCH=ferrari $BRANCH=ferrari  
continuous-integration/travis-ci/pr - $TRAVIS_BRANCH=master $BRANCH=ferrari  

A better way

While this workaround is nice, it would be much nicer if Travis would simply add $TRAVIS_CURRENT_BRANCH.

I've created an issue here, please add your support with a +1: