331

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.

Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
aborilov
  • 7,416
  • 3
  • 21
  • 20
  • Use this action: https://github.com/EthanSK/git-branch-name-action it works for both pull_request and push trigger – Ethan SK Apr 18 '21 at 15:36
  • 4
    IMHO https://stackoverflow.com/a/64210623/680454 should be the accepted answer; it deals with @ambientlight's objection to the currently accepted answer, it avoids use of now-deprecated `setenv`, and it doesn't use any external includes. – michielbdejong Aug 17 '21 at 10:01
  • I opened up a [Feature Request](https://github.com/github/feedback/discussions/5251) with GitHub to add native support for this. Many other CI providers (Travis CI, CircleCI, Semaphore CI) have native support, so there's good precedence for adding something like this. Please upvote the feature request if you'd like to see this behavior added! – blimmer Aug 23 '21 at 17:53
  • 9
    `${{ github.ref_name }}` works for me – Neil McGuigan Nov 15 '22 at 21:19
  • https://docs.github.com/en/enterprise-cloud@latest/actions/learn-github-actions/variables#default-environment-variables – CatCatMcMeows Jan 20 '23 at 18:00
  • 1
    If I need to know the source branch name in case of push (from feature to master branch), which context can be used ? Because github.ref_name & github.head_ref are giving master as branch name . – DollyShukla Jan 25 '23 at 12:12

33 Answers33

284

I added a separate step for extracting branch name from $GITHUB_HEAD_REF/$GITHUB_REF¹ (pr and push) and set it to the step output:

- name: Extract branch name
  shell: bash
  run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
  id: extract_branch

after that, I can use it in the next steps with steps.<step_id>.outputs.branch:

- 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 }}

 


¹ $GITHUB_HEAD_REF on pull_request (pr) and $GITHUB_REF on push. Description:

Variable Description
GITHUB_HEAD_REF The head ref or source branch of the pull request in a workflow run. This property is only set when the event that triggers a workflow run is either pull_request or pull_request_target. For example, feature-branch-1. (source)
GITHUB_REF The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/<branch_name>, for pull requests it is refs/pull/<pr_number>/merge, and for tags it is refs/tags/<tag_name>. For example, refs/heads/feature-branch-1. (source)

Full description of these and all other Default environment variables - Learn Gihtub Actions (archived copy).

Looking for the Microsoft Github Action Context named github? See the answer by ysfaran and/or the answer by Dusan Plavak.

hakre
  • 193,403
  • 52
  • 435
  • 836
aborilov
  • 7,416
  • 3
  • 21
  • 20
  • 27
    $GITHUB_REF would look like (refs/pull/33/merge), $GITHUB_HEAD_REF would just store the source branch name while $GITHUB_BASE_REF would represent RP destination branch. Maybe you can update your answer to fallback to $GITHUB_HEAD_REF whenever it is set, what do you think? – ambientlight Nov 25 '19 at 07:51
  • 5
    GITHUB_HEAD_REF is the head ref, its in the same format, but only for pull requests. – Alex Barker Feb 02 '20 at 22:55
  • 3
    Shorter version: `run: echo "##[set-output name=branch;]${GITHUB_REF#refs/heads/}"` – kenorb Jun 27 '20 at 14:30
  • 1
    `set-output` has been deprecated now, so the first step should be ``` - name: Extract branch name shell: bash run: echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >>$GITHUB_OUTPUT id: extract_branch ``` and can use the `${{ steps.extract_branch.outputs.branch }}` in the next step as mentioned – Ali Kahoot Mar 14 '23 at 14:51
198

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

If your branch name does not contain a / in it (for example deploy/abc), then 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: https://github.com/tedmiston/x/blob/master/.github/workflows/workflow.yml

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: https://github.com/tedmiston/x/commit/cdcc58a908e41d3d90c39ab3bf6fef1ad2c4238a/checks#step:4:16

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: https://github.com/tedmiston/x/commit/4e8d31259f861aaa2c30375756fc081c3659bddf/checks#step:4:16


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.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
  • 3
    this will work in a shell script but won't work in the workflow YAML file – aborilov Sep 20 '19 at 21:08
  • @aborilov Are you sure it's not working? If I understand your goal correctly, it worked for me in the MVP I just created. I've updated my answer to include the sample workflow yaml code and sample run links for convenience. Hope this helps! – Taylor D. Edmiston Sep 21 '19 at 03:09
  • 1
    yes, this will work for `run` steps, but I also need branch name in ENV vars when I push an image to ECR – aborilov Sep 21 '19 at 05:05
  • @aborilov I'm not sure that I follow -- the `GITHUB_REF` environment variable should already exist in all of the containers, so you can just read it with the parameter expansion syntax in each place you need it. – Taylor D. Edmiston Sep 21 '19 at 21:00
  • Can I use it here `image: eng:${{ steps.extract_branch.outputs.branch }}`? I tried and it's not working for me – aborilov Sep 22 '19 at 08:15
  • 93
    Note that if you use Gitflow-style branch names like `feature/foo`, the `${GITHUB_REF##*/}` syntax will not do what you want: it will strip the `feature/` from the branch name and just return `foo`. I'd recommend using `${GITHUB_REF#refs/heads/}` instead of `${GITHUB_REF##*/}`, so that `refs/heads/feature/foo` will turn into `feature/foo`. That won't work if your ref is a PR, where instead of `refs/heads/branchname` the value of `$GITHUB_REF` would be `pull/123/merge`... but if your workflow script is expecting a PR, you probably know it (e.g. you're triggering on `pull_request`). – rmunn Sep 23 '19 at 03:26
  • this didnt work for me. I did `echo "####$(echo ${GITHUB_REF#refs/heads/})"` but there is no output – pyofey Apr 30 '21 at 23:50
  • @pyofey Does it work if you use just `echo ${GITHUB_REF#refs/heads/}` like @rmunn suggested? – Taylor D. Edmiston May 03 '21 at 18:19
  • I think this answer has the same problem as https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions/58034787#comment104298828_58035262 - it won't work for pull requests. – michielbdejong Aug 17 '21 at 09:54
  • @michielbdejong I see that the question at the top doesn't mention PRs. For a PR use case, does using `GITHUB_HEAD_REF` in place of `GITHUB_REF` solve the issue for you? If not, can you provide more concrete info around what you have done (if you have solved this) so I can update the answer? Docs for that are here - https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables. – Taylor D. Edmiston Aug 17 '21 at 18:26
  • Yes! You're right. That solves it for the PR case. And then something like https://stackoverflow.com/a/64210623/680454 covers both situations. That is what I did in the end, see: https://github.com/solid/node-solid-server/blob/c06c23d/.github/workflows/ci.yml#L24-L32 – michielbdejong Aug 18 '21 at 19:33
  • 46
    We can simply use `GITHUB_REF_NAME` now. Extracting from `GITHUB_REF` isn't needed. More [info](https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables). – Maneet Nov 19 '21 at 09:15
178

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 }}

https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context

Github action context refs

Dusan Plavak
  • 4,457
  • 4
  • 24
  • 35
154

TL;DR

This works for every trigger that you can specify under on (e.g push or pull_request):

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

Explanation

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_request and it also just contains the branch name.

GitHub Documentation

Detailed explanation from official GitHub docs:

github.ref_name string The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1.

github.head_ref string The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.

ysfaran
  • 5,189
  • 3
  • 21
  • 51
  • 9
    This was the only one that worked for me trying to get the branch name for a github action that is triggered when a new commit is pushed to a pull request. – Peter Brown Aug 11 '22 at 18:05
  • This doesn't work correctly when action is triggered by tag (it returns tag name) – Andris Silis May 17 '23 at 12:44
  • Awesome one-liner solution. Just to note that if the desired was the **target branch** of the pull request, one should set the env `BRANCH_NAME: ${{ github.base_ref || github.ref_name }}` instead, because `github.head_ref` returns the source branch (e.g. 'feat/to-be-merged') not the target (e.g. 'main'). – rffontenelle Jun 06 '23 at 16:17
  • What about `workflow_dispatch` trigger? – Sumit Jun 22 '23 at 17:41
63

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 https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables

jwalton
  • 5,286
  • 1
  • 18
  • 36
Federico Moya
  • 722
  • 5
  • 5
  • Which all events is this available for? – Anshul Sahni Dec 08 '21 at 07:15
  • @AnshulSahni I believe it's available for all the events. For those cases where a certain variable is available only for a particular set of events, the docs point to which events. Like with `GITHUB_HEAD_REF`, quoting; "Only set for pull request events. The name of the head branch." – Federico Moya Dec 08 '21 at 22:48
  • 6
    This is the most relevant answer in 2022! – Kevin Wang Jun 11 '22 at 22:41
  • 2
    You can also use it in the github action with `${{ github.ref_name }}` – Dantheman91 Jul 13 '22 at 19:07
  • 2
    `if: ${{ github.event_name == 'pull_request' }} run: echo "This is a PR for ${{ github.ref_name }}"` Unfortunately this doesn't print out the branch name :( My branch name is `feature/foo`, but I get this instead: `This is a PR for 438/merge` – Jeremy Jao Dec 07 '22 at 00:12
  • What if I want the branch name whenever its release/tag which triggers the action ? – linSESH Dec 20 '22 at 09:37
51

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 }}
sshow
  • 8,820
  • 4
  • 51
  • 82
  • Nice thanks. Beware if working directory is different, it can end up with "Error: No such file or directory". Setting `working-directory: .` should do it in case a different path was set as default. – lzap Jan 29 '21 at 17:15
  • This unfortunately doesn't work for me. See also [this GitHub issue](https://github.com/actions/runner/issues/480). – petezurich Nov 18 '21 at 10:11
39

You could use https://github.com/rlespinasse/github-slug-action

# 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
Antoine
  • 4,456
  • 4
  • 44
  • 51
23

For those just finding this thread, you can now use GITHUB_REF_NAME e.g. ${{ github.ref_name }}. https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables

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.

Christopher Cook
  • 780
  • 8
  • 16
18

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:

kenorb
  • 155,785
  • 88
  • 678
  • 743
18

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!

Franz Diebold
  • 555
  • 6
  • 21
17
${{ github.ref_name }}

Seems to work fine for for pushes at least. See ref_name for more details. It says:

The branch or tag name that triggered the workflow run.

Nae
  • 14,209
  • 7
  • 52
  • 79
14

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

petezurich
  • 9,280
  • 9
  • 43
  • 57
LE GALL Benoît
  • 7,159
  • 1
  • 36
  • 48
  • Here's how to do it if you're running your step in windows: ```- run: echo ("::set-env name=BRANCH_NAME::" + $env:GITHUB_REF.replace('refs/heads/', ''))```. Shell for this command should be powershell which is the default. – Sal May 06 '20 at 15:27
  • 3
    This is deprecated – eljefedelrodeodeljefe Nov 19 '21 at 19:05
  • Depracated, returns: ``Error: Unable to process command '::set-env name=BRANCH_NAME::ci' successfully. Error: The `set-env` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ `` – GuySoft Mar 08 '22 at 12:33
12

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
Jan Aagaard
  • 10,940
  • 8
  • 45
  • 80
youjin
  • 2,147
  • 1
  • 12
  • 29
11

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

eQ19
  • 9,880
  • 3
  • 65
  • 77
6

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.

sid_dev
  • 61
  • 1
  • 2
5

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

Pietrek
  • 1,420
  • 14
  • 18
  • [You can also use `github.ref_name` to get the branch or tag name without the prefix.](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context) – techpeace Jan 27 '22 at 22:31
4

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

Dmitry
  • 59
  • 3
3

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/}})"
petezurich
  • 9,280
  • 9
  • 43
  • 57
aiso
  • 31
  • 4
2

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}
VAIBHAV GOUR
  • 167
  • 1
  • 3
1

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/", ""
Leaky
  • 3,088
  • 2
  • 26
  • 35
1

I made an action that gets the branch name regardless of pull_request trigger or not. https://github.com/EthanSK/git-branch-name-action

Ethan SK
  • 736
  • 8
  • 12
1

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: https://www.techiedelight.com/determine-current-branch-name-git/

  • This does not work when operating within a detached head for example, which typically is the case when you're running a github action pipeline. – doublespaces Jun 28 '22 at 21:26
1

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

https://docs.github.com/en/actions/learn-github-actions/environment-variables

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
Marcello Romani
  • 2,967
  • 31
  • 40
0
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.

kenorb
  • 155,785
  • 88
  • 678
  • 743
0

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)"
DJ.
  • 528
  • 7
  • 16
  • I simply did `$branchName = $Env:GITHUB_REF -replace "refs/heads/", ""`. I'm not a powershell export, so I'm open to your reasoning – Airn5475 Nov 02 '20 at 19:49
0

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)
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
0

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
Munim
  • 2,626
  • 1
  • 19
  • 28
0

We currently have a separate job, that runs before all other jobs. That step determines in what environment it runs, based on the branch name. Our branches are associated with specific environments to deploy infrastructure and code bases. Each environment also has its own secrets (github enterprise feature).

The output environment variable can be used in all other consecutive jobs. You can use that variable within a step, to set it as NODE_ENV for example, or tag a docker image with it. You could also set a concurrency on that specific variable to ensure that only a single job or workflow using the same value will run at a time. This makes it very powerful.

Below is an example of what I described above:

name: Build pipeline
on:
  push:
    branches:
      - feature/*
      - develop
      - release/*
      - main

jobs:
  environments:
    name: Set environment
    runs-on: ubuntu-latest
    steps:
      - run: echo "Setting $ENVIRONMENT.."
    outputs:
      # Defaults to 'dev' in case of a feature branch
      # You could also use the contains expression if needed
      environment: ${{ github.ref == 'refs/heads/main' && 'prd' || (startsWith(github.ref, 'refs/heads/release/') && 'acc' || github.ref == 'refs/heads/develop' && 'tst' || 'dev') }}

  build:
    name: Docker build
    runs-on: ubuntu-latest
    needs: [environments]
    environment: ${{ needs.environments.outputs.environment }} # Enterprise only
    concurrency: ${{ needs.environments.outputs.environment }}
    env:
      ENVIRONMENT: ${{ needs.environments.outputs.environment }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Build
        run: |
          docker build . \
            -t hello/world:${{ needs.environments.outputs.environment }}

Note: because extracting the environment name is not done in bash or powershell, you are bound to the limited expressions github actions offers. If you need more fancy stuff you could do it differently, there is no single truth. However, I always like to keep things simple and readable.

Alternative (quick) option

If you don't mind using other people's github actions, you could use one of the many actions from the marketplace that do a find a replace. An example can be found here, that looks like:

on: [push]

jobs:
  replace-job:
    runs-on: ubuntu-latest
    name: 'Find and replace'
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Remove refs/heads/ from string
        uses: mad9000/actions-find-and-replace-string@1
        id: findandreplace
        with:
          source: ${{ github.ref }}
          find: 'refs/heads/'
          replace: ''
      - name: Branch name
        run: echo "The branch name is ${{ steps.findandreplace.outputs.value }}"
Cloudkollektiv
  • 11,852
  • 3
  • 44
  • 71
0

To get the ref name on a delete event I ended up using sed.

on:
  delete:
...
steps:
  - name: Do something
    shell: bash
    run: |
      refname=$(sed -e s:refs/heads/::g -e s:/:-:g <<< ${{ github.event.ref }})

cut refs/heads/ and convert slashes to dashes, .e.g. refs/heads/feature/somefeature to feature-somefeature

Jane
  • 428
  • 3
  • 10
0

I have had to do this several different times for events that run on the PR sync event and then on push to main (e.g. building tagged container images) and I don't particularly like:

  1. Using 3rd party actions on private repos.
  2. Using the expression syntax as I find it to be a rather poor development experience.
  3. Having to remember how variable expansion substitution works since I also tend to use / separated branches, e.g. fix/123.

I thought I would add a small bash snippet that will work on push and pull_request events since I didn't see one here:

echo "${GITHUB_REF_NAME}" | grep -P '[0-9]+/merge' &> /dev/null && export ref="${GITHUB_HEAD_REF}" || export ref="${GITHUB_REF_NAME}"

The $ref variable will hold the branch name on push and pull_request events and will handle gitflow/style/branches.

This works on the assumption that GH actions creates a (typically unexpected) {pr number}/merge branch for actions that run on PR sync, the grep call will only return 0 when the branch name matches the (Perl-style) regex and follow the && path to export ref as the value of GITHUB_HEAD_REF. Or, for branches that don't match the regex (like main).

The output redirect on grep just prevents the case of a regex match printing to stdout.

Naturally, this won't work if you need the push event on a branch that matches the regex.

tykom
  • 659
  • 5
  • 8
0

It's simple to get the current branch and the below code works if the event was triggered by a push event.

github.ref_name is a predefined variable to get the branch name.

jobs:
  main-branch-build:
    if: github.ref_name == 'main'
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
  feature-branch-build:
    if: github.ref_name != 'main'
    runs-on: ubuntu-latest
    steps:
    - name: Check out code
      uses: actions/checkout@v3
paleonix
  • 2,293
  • 1
  • 13
  • 29
Nanda Thota
  • 322
  • 3
  • 10
0

Use $GITHUB_REF_NAME

Documentation: https://docs.github.com/en/actions/learn-github-actions/variables

Rochadsouza
  • 888
  • 10
  • 10
0

This works locally (using git, not the Github action environment variables) and in Github actions in its reincarnations pull request, push and merge:

#!/bin/bash
echo "${GITHUB_HEAD_REF:-$(git branch --show-current)}"

In a Github action:

- run: echo "${GITHUB_HEAD_REF:-$(git branch --show-current)}" >> $GITHUB_OUTPUT
  shell: bash
  id: branch
Jonas Eberle
  • 2,835
  • 1
  • 15
  • 25