94

I want to build a docker image using a GitHub action, migrating from TeamCity.

In the build script, I want to tag the image with a combination of branch and commit, e.g. master.ad959de. Testing that locally, I get that information like this:

git_branch=`git symbolic-ref --short HEAD`
git_hash=`git rev-parse --short HEAD`
docker_version=${git_branch}.${git_hash}

This is the relevant part of the GitHub action:

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1

    - name: Create docker image
      run: ./docker-build.sh  

Running that script in that GitHub action results in this error:

fatal: ref HEAD is not a symbolic ref

How can I generate a tag like that inside a GitHub action?

Rüdiger Schulz
  • 2,588
  • 3
  • 27
  • 43

8 Answers8

117

from Using environment variables

github provides two variables that are useful here, you'll need to process them a bit to get the values you desire:

GITHUB_SHA: The commit SHA that triggered the workflow. For example, ffac537e6cbbf934b08745a378932722df287a53.

GITHUB_REF: The branch or tag ref that triggered the workflow. For example, refs/heads/feature-branch-1. If neither a branch or tag is available for the event type, the variable will not exist.

The short values can be extracted like this:

git_hash=$(git rev-parse --short "$GITHUB_SHA")
git_branch=${GITHUB_REF#refs/heads/}
anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • 17
    Note that if branch name contains `/` git_branch value will be incorrect. For example `ref/heads/actions/test` converts to `test` where as `actions/test` is actual branch name. Instead use `git_branch=${branch#refs/heads/}` . src: https://stackoverflow.com/a/58035262/9720375 – Shinebayar G Apr 10 '20 at 01:44
  • 2
    Maybe github added some more env vars since this answer was posted; `git_branch` should now be available as `GITHUB_REF_NAME` env var. – ssc Nov 07 '21 at 08:53
  • 2
    Note that if the trigger of the action is `pull_request` then `${{github.sha}}` is not the latest commit on the branch. See https://github.community/t/github-sha-isnt-the-value-expected/17903 – blackwolf123333 Jun 14 '22 at 12:49
91

Another approach is to use github context.

- name: Create docker image
  run: ./docker-build.sh ${{ github.head_ref }}.${{ github.sha }}

The benefit of this approach is that you don't have to add a step to set the values. Note that it uses the full version of the sha (not the short version).

ifoukarakis
  • 1,199
  • 8
  • 8
  • 21
    This should be the correct answer as `${{ github.sha }}` is the correct way to get commit SHA – Pietrek Nov 19 '21 at 09:00
  • @Pietrek It's unreliable as a blanket solution, since [`github.head_ref` is only defined on `pull_request` events](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-a-fallback-value). – Abandoned Cart May 19 '23 at 14:45
  • @AbandonedCart I am using ${{github.ref}} actually, but I do not know if that fits your needs – Pietrek May 22 '23 at 08:26
  • @Pietrek I use the `$(git rev-parse --short HEAD)` method. – Abandoned Cart May 22 '23 at 08:42
41

A handy way to get the currrent branch and commit sha on the workflow could be getting it and saving on a "variable".

  - name: Declare some variables
    shell: bash
    run: |
      echo "sha_short=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV"
      echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_ENV"
  
  - name: Another step
    run: |
      echo "Branch: ${{ env.branch }}"
      echo "Sha: ${{ env.sha_short }}"

Maybe your docker-build.sh could receive the branch and sha as parameter, os the full version as parameter.

  - name: Create docker image
     run: ./docker-build.sh "${{ env.branch }}.${{ env.sha_short }}"

OR JUST

  - name: Create docker image
     run: ./docker-build.sh "${GITHUB_REF#refs/heads/}.${GITHUB_SHA}"

On this action you can see it better.

Tiago Gouvêa
  • 15,036
  • 4
  • 75
  • 81
  • 1
    `set-output` has been deprecated. The new syntax is described here: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files The new way looks like `echo "SHORT_SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV`. Which would add the variable to the environment: `${{ env.SHORT_SHA }}` – Ivan P Jul 13 '23 at 20:01
9

Simplest way to get a shortened SHA using Environment variables:

- name: Build Docker Image
    run: ./docker-build.sh alpha.${GITHUB_SHA::6}
Azim Saiyed
  • 392
  • 1
  • 5
  • 15
  • 1
    What is this `alpha.` syntax? – Rüdiger Schulz Mar 26 '21 at 09:02
  • @Rüdiger it’s a parameter for the build script, most likely a tag for the Docker image. It has nothing to do with the actions syntax, but the evaluation of the expression will result in a parameter like “alpha.ec7ba90” being passed into the build script. – MorganP May 21 '21 at 14:36
  • 2
    Shouldn't you change 6→7 to get the 7-digit short SHA? – Ben Mares Dec 13 '21 at 17:17
  • 2
    What is this `::6` magic at the end? I've never seen this and Github Actions doesn't like it easier: `The workflow is not valid. Unexpected symbol: 'GITHUB_SHA::6'.` – Joshua Pinter Apr 25 '22 at 19:54
  • Just following up, I _think_ this is actually "parameter expansion" and has nothing to do with Github Actions, which makes much more sense. – Joshua Pinter Apr 25 '22 at 20:27
4

You can get it this way in your sh file -

BRANCH_NAME=$(echo $GITHUB_REF | cut -d'/' -f 3)
GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c1-7)
Artur A
  • 7,115
  • 57
  • 60
Abhinav Manchanda
  • 6,546
  • 3
  • 39
  • 46
3

Maybe Like this

name: CI 
on: push 
jobs:   
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1

    - name: Get Branch
      id: branch
      run: echo "git_branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_BRANCH

    - name: Check Branch
      run: echo "${{ env.branch }}"

    - name: Get Hash
      id: hash
      run: echo "git_hash=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_HASH

    - name: Check Hash
      run: echo "${{ env.hash }}"

    - name: Create docker image
      run: ./docker-build.sh ${{ env.branch }} ${{ env.hash }}
2

You should be able to access the SHA for the latest Git commit with ${{ github.event.pull_request.head.sha }}, assuming this is an Action triggered by a Pull Request

bodacious
  • 6,608
  • 9
  • 45
  • 74
1

Using https://github.com/tj-actions/branch-names provides an output which also works for push and pull_request events


...
    steps:
      - uses: actions/checkout@v2
      - name: Get branch names
        uses: tj-actions/branch-names@v2.1
        id: branch-names
      
      - name: Current branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.current_branch }}"
        # Outputs: "feature/test" current PR branch.
      
      - name: Current branch name
        if: github.event_name == 'push'
        run: |
          echo "${{ steps.branch-name.outputs.current_branch }}"
        # Outputs: "main" the default branch that triggered the push event.
      
      - name: Get Ref brach name
        run: |
          echo "${{ steps.branch-name.outputs.ref_branch }}"
        #  Outputs: "main" for non PR branches | "1/merge" for a PR branch

      - name: Get Head Ref branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.head_ref_branch }}"
        # Outputs: "feature/test" current PR branch.

      - name: Get Base Ref branch name
        if: github.event_name == 'pull_request'
        run: |
          echo "${{ steps.branch-name.outputs.base_ref_branch }}"
        # Outputs: "main" for main <- PR branch.

jackotonye
  • 3,537
  • 23
  • 31