How to get the current branch within Github Actions?

I'm building Docker images with Github Actions and want to tag images with the branch name.

I found the GITHUB_REF variable, but it results in refs/heads/feature-branch-1 and I need only feature-branch-1.

3

27 Answers

I added a separate step for extracting branch name from $GITHUB_REF and set it to the step output

- name: Extract branch name shell: bash run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" id: extract_branch 

after that, I can use it in the next steps with

- name: Push to ECR id: ecr uses: jwalton/gh-ecr-push@master with: access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} region: us-west-2 image: eng:${{ steps.extract_branch.outputs.branch }} 
3

I believe GITHUB_REF is the only environment variable that includes the branch name.

You can extract just the branch name from the rest of that string like this:

${GITHUB_REF##*/} 

Example:

$ GITHUB_REF=refs/heads/feature-branch-1 $ echo ${GITHUB_REF##*/} feature-branch-1 

Update: Added a complete workflow example.

Workflow

name: CI on: push jobs: build: runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v1 - name: Branch name run: echo running on branch ${GITHUB_REF##*/} - name: Build run: docker build -t tedmiston/tag-example:${GITHUB_REF##*/} . 

Source:

Sample output - master branch

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} . docker build -t tedmiston/tag-example:${GITHUB_REF##*/} . shell: /bin/bash -e {0} Sending build context to Docker daemon 146.9kB Step 1/1 : FROM alpine latest: Pulling from library/alpine 9d48c3bd43c5: Pulling fs layer 9d48c3bd43c5: Verifying Checksum 9d48c3bd43c5: Download complete 9d48c3bd43c5: Pull complete Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb Status: Downloaded newer image for alpine:latest ---> 961769676411 Successfully built 961769676411 Successfully tagged tedmiston/tag-example:master 

Log:

Sample output - non-master branch

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} . docker build -t tedmiston/tag-example:${GITHUB_REF##*/} . shell: /bin/bash -e {0} Sending build context to Docker daemon 144.9kB Step 1/1 : FROM alpine latest: Pulling from library/alpine 9d48c3bd43c5: Pulling fs layer 9d48c3bd43c5: Verifying Checksum 9d48c3bd43c5: Download complete 9d48c3bd43c5: Pull complete Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb Status: Downloaded newer image for alpine:latest ---> 961769676411 Successfully built 961769676411 Successfully tagged tedmiston/tag-example:branch-name-test 

Log:


See this answer for more on parameter expansion syntax.

For reference the page Virtual environments for GitHub Actions lists all of the environment variables available in the execution environment.

12

Be aware that if you are executing your GitHub action on pull request trigger, then GITHUB_REF variable will contain something like refs/pull/421/merge so if you will try to git push to that name it will most likely fail.

What you can use though are references on the GitHub context in your YAML. Something like: ${{ github.head_ref }}

Github action context refs

3

Using setenv is now deprecated. It is advised to use environment files. Building on @youjin's answer, while still allowing feature/ branches (replacing all occurences of / with -), I am now using this:

jobs: build: runs-on: ubuntu-latest steps: - name: Get branch name (merge) if: github.event_name != 'pull_request' shell: bash run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV - name: Get branch name (pull request) if: github.event_name == 'pull_request' shell: bash run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV - name: Debug run: echo ${{ env.BRANCH_NAME }} 
2

You could use

# Just add this => - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v3.x # And you get this => - name: Print slug/short variables run: | echo "Slug variables" echo " - ${{ env.GITHUB_REF_SLUG }}" echo " - ${{ env.GITHUB_HEAD_REF_SLUG }}" echo " - ${{ env.GITHUB_BASE_REF_SLUG }}" echo " - ${{ env.GITHUB_REPOSITORY_SLUG }}" # output e.g. : master feat-new-feature v1.0.0 product-1.0.0-rc.2 new-awesome-product echo "Slug URL variables" echo " - ${{ env.GITHUB_REF_SLUG_URL }}" echo " - ${{ env.GITHUB_HEAD_REF_SLUG_URL }}" echo " - ${{ env.GITHUB_BASE_REF_SLUG_URL }}" echo " - ${{ env.GITHUB_REPOSITORY_SLUG_URL }}" # output e.g. : master feat-new-feature v1-0-0 product-1-0-0-rc-2 new-awesome-product echo "Short SHA variables" echo " - ${{ env.GITHUB_SHA_SHORT }}" # output e.g. : ffac537e 
2

Just use:

env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 

The trick is that github.head_ref is only set when the workflow was triggered by a pull_request and it contains the value of the source branch of the PR. github.ref_name will than only be used if the workflow was not triggered by a pull_requestand it also just contains the branch name.

Update

GitHub now supports the GITHUB_REF_NAME, which stands for: The branch or tag name that triggered the workflow run.

GitHub docs on this

3

How to get the current branch within Github Actions?

Assuming ${{ github.ref }} is something like refs/heads/mybranch, you can extract the branch name using the following method:

steps: - name: Prints the current branch name run: echo "${GITHUB_BRANCH##*/}" env: GITHUB_BRANCH: ${{ github.ref }} 

If your branch includes slashes (such as feature/foo), use the following syntax:

steps: - name: Prints the current branch name run: echo "${GITHUB_REF#refs/heads/}" 

Credits: @rmunn comment

Or use the method from the accepted answer, here is much shorter version (lint friendly):

steps: - name: Get the current branch name shell: bash run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}" id: myref 

Then refer in other steps as ${{ steps.myref.outputs.branch }}.

Notes:

1

The GitHub Action FranzDiebold/github-env-vars-action exposes several useful environment variables, such as current branch name and their slug values. I made this action exactly for this use case.

Usage

steps: - uses: FranzDiebold/github-env-vars-action@v1.2.0 - name: Print environment variables run: | echo "GITHUB_REPOSITORY_SLUG=$GITHUB_REPOSITORY_SLUG" echo "GITHUB_REPOSITORY_OWNER=$GITHUB_REPOSITORY_OWNER" echo "GITHUB_REPOSITORY_OWNER_SLUG=$GITHUB_REPOSITORY_OWNER_SLUG" echo "GITHUB_REPOSITORY_NAME=$GITHUB_REPOSITORY_NAME" echo "GITHUB_REPOSITORY_NAME_SLUG=$GITHUB_REPOSITORY_NAME_SLUG" echo "GITHUB_REF_SLUG=$GITHUB_REF_SLUG" echo "GITHUB_REF_NAME=$GITHUB_REF_NAME" echo "GITHUB_REF_NAME_SLUG=$GITHUB_REF_NAME_SLUG" echo "GITHUB_SHA_SHORT=$GITHUB_SHA_SHORT" 

enter image description here

A demo for all Operating systems (Linux, macOS and Windows) is also available in the demo workflows file of the repository!

To set it as an environment variable, I use this syntax:

- name: Extract branch name shell: bash run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')" - name: Test run: echo "${BRANCH_NAME}" 

I found this syntax here: Github actions - starter worflows#How to define env variable? #68

Rmq: the sed 's/\//_/g' is to replace / by _ in the branch name

3

I just made a simple test within GitHub Actions using a bash script:

#!/bin/bash echo Reserved for REPO_NAME=${GITHUB_REPOSITORY##*/} echo GITHUB_REF=${GITHUB_REF} echo EXTRACT_GITHUB_REF=${GITHUB_REF##*/} echo EXTRACT_GITHUB_REF_HEADS=$(echo ${GITHUB_REF#refs/heads/}) cd $REPO_NAME git checkout ${GITHUB_REF##*/} git checkout $(echo ${GITHUB_REF#refs/heads/}) 

Here is screenshot of the output:

enter image description here So both ${GITHUB_REF##*/} and $(echo ${GITHUB_REF#refs/heads/}) are correct

0

Heres a complete workflow that works for both push and pull_request events

name: whichBranch on: [pull_request, push] jobs: which_branch: runs-on: ubuntu-latest steps: - name: Extract branch name on push if: github.event_name != 'pull_request' shell: bash run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/})" id: extract_branch - name: Extract branch name on pull request if: github.event_name == 'pull_request' run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_HEAD_REF})" - name: Print branch name run: echo 'The branch name is' $BRANCH_NAME 

For those just finding this thread, you can now use GITHUB_REF_NAME e.g. ${{ github.ref_name }}.

So if your triggered action workflow branch is main this variable will be set to main. This is useful if you have multiple repos with release and main branches, for instance.

0
${{ github.ref_name }} 

Seems to work fine for for pushes at least.

If you're using V2 of actions/checkout then you can always just run git branch --show-current to just get the name of the branch currently checked out.

Now ${{github.ref}} is the correct way to get branch name. Please remember ${{github.ref}} has refs/heads/.. prefix

1

Solution to deal with both pull_request and push events. Implements the workaround to save obtained branch name for further steps, since set-env is deprecated. Doesn't require third-party actions.

name: CI on: [ pull_request, push ] jobs: build: runs-on: ubuntu-latest steps: - name: "Get branch name and save to env" env: IS_PR: ${{ github.EVENT_NAME == 'pull_request' }} run: | if ${IS_PR}; then BRANCH_NAME="${GITHUB_HEAD_REF}" else BRANCH_NAME="${GITHUB_REF##*/}" fi echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV - name: "Another step uses branch name" run: echo "Branch name is ${{ env.BRANCH_NAME }}" 

Runtime Variables in GitHub Actions

To also deal with the pull_request event (in which case the $GITHUB_REF contains something not useful like refs/pull/519/merge) you can use this one liner:

 - name: Set branch name run: echo "::set-output name=branch_name::$(echo ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}})" 

Use branch name on GitHub actions

Convenience action for using current branch name. Usage

name: build on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - run: npm ci - uses: nelonoel/branch-name@v1 # Use branch name for whatever purpose - run: echo ${BRANCH_NAME} 

For people using Windows image to run actions, a few key points to know about:

  1. It's incorrect to assume that GitHub actions use CMD shell. They use PowerShell by default.
  2. You can specify the shell to use the following way:
- run: | ... shell: cmd 
  1. You can use the value 'bash' to execute a command in the context of a bash shell.

So, all in all, you don't need to waste potentially hours trying to figure out how to do things in dilapidated cmd way (like I did).

And for the simple purpose of getting the name of the current branch, you can either use the popular solutions while setting the shell to 'bash', or use for example the following simple way to set a variable in the default PowerShell shell:

$branchName = $Env:GITHUB_REF -replace "refs/heads/", "" 

I made an action that gets the branch name regardless of pull_request trigger or not.

Just repeating here for better visibility what others have written as simple comments in previous replies:

The branch name for pull requests only is exposed in this environment variable:

GITHUB_HEAD_REF Only set for pull request events. The name of the head branch.

In GitHub actions, the corresponding context key is:

github.head_ref 
if: github.ref == 'refs/heads/integration' && github.event_name == 'push' 

You can use the above command and replace whatever branch or event you want to run for.

1

Running on Windows?. Windows default command is a PowerShell terminal.

 - name: SET CURRENT_BRANCH run: | $branchName = "${{github.ref}}".Split("/")["${{github.ref}}".Split("/").Length -1] echo "::set-env name=CURRENT_BRANCH::$(echo $branchName)" 
1

Here's a snippet which set's an environment variable based on $GITHUB_REF, which defaults to dev if not present.

Adjust the sed command as per your requirements.

export GIT_BRANCH=$(echo ${GITHUB_REF:-dev} | sed s/.*\\///g) 

Normally, I always have a script written in either nodejs or python, which gets invoked from the workflow.yaml. The script normally takes care of works like getting proper branch reference.

I have a function like below, in a prepare-deployment.js script-

const VALID_REF_PREFIX = 'refs/heads/'; ... function getBranchRef(isProd = false) { let branchRef = 'origin/master'; if (isProd) { return branchRef; } /** * When the workflow is invoked from manual flow, the branch name * is in GITHUB_REF, otherwise, we have to look into GITHUB_BASE_REF */ if (GITHUB_REF.startsWith(VALID_REF_PREFIX)) { // coming from a manual workflow trigger branchName = `origin/${GITHUB_REF.replace(VALID_REF_PREFIX, '')}`; } else { // coming from a PR branchRef = `origin/${GITHUB_HEAD_REF}`; } return branchRef; } 

This takes care of the following scenarios-

  1. I want to deploy changes from a PR to my dev env
  2. I want to deploy changes from any branch I want into my dev env, via a manual trigger
  3. I want to deploy changes from master into my prod env

There's a very simple git command to get the current branch:

git rev-parse --abbrev-ref HEAD

To get the output in an env file variable simply put:

 - name: Set CURRENT_BRANCH run: echo "CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV

To get the output from the env variable:

 - name: Get CURRENT_BRANCH run: echo ${{ env.CURRENT_BRANCH}}

Source:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like