Add short sha to GitHub context

It would be nice to have a variable in GitHub context with the “short sha” representation of the commit hash.

This is useful, for example when tagging Docker images to have a more manageable version of the commit hash.

From the command line you can get the short sha like this:

git rev-parse --short <commit_hash>

Thank you.

23 Likes

Thanks for the feedback.  We’ll give this some consideration.

1 Like

In run steps, you can simply use the following shortcut (I do the same to tag Docker images):

${GITHUB_SHA::8}

This will just pick the first 8 characters of the SHA. So in full context it looks like:

steps:
  - name: Build Docker image
    run: docker build -t some/image:${GITHUB_SHA::8} .

If you need it across multiple steps and want to simplify how it looks, you should be able to set it as workflow or job env var (although I have not tested this myself, I just use the full version everywhere):

name: My Workflow

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      SHA8: ${GITHUB_SHA::8}

    steps:
      - name: Build image
        run: docker build -t some/image:$SHA8 .
      - name: Build another image
        run: docker build -t other/image:$SHA8 .
24 Likes

you mean this right?

env:
SHA7: ${GITHUB_SHA:7}

 double colon failing in my case 

The double colon should get you the first 8 characters, but it might work differently on Windows/Mac runners.

The syntax is Bash substring syntax that looks like ${string:S:L}, where S is the Starting index of the string and L is the length. The double colon should be parsed as 0:N, and thus give you the first N characters. ${string:S} should give you the string from position S onwards, so ${GITHUB_SHA:7} would give you the SHA from the 7th character onwards and return a rather long string. But again, it might work differently on non-Linux runners.

1 Like

Neither ${string:S:L} nor ${string:L} worked for me.

I used the following cut command instead:

$(echo ${GITHUB_SHA} | cut -c1-8)

So, your Github Actions pipeline config file should look as follows:

name: My Workflow

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Build image
        run: docker build -t some/image:$(echo ${GITHUB_SHA} | cut -c1-8) .
      - name: Build another image
        run: docker build -t other/image:$(echo ${GITHUB_SHA} | cut -c1-8) .
4 Likes

Are you sure that doing a bash command in an env: declaration is supported:

env:
  SHA8: ${GITHUB_SHA::8}

 From my tests, it seems that what is happening is

SHA8='${GITHUB_SHA::8}'

And the bash expression is not being interpreted.

6 Likes

That’s not going to work, bash isn’t invoked during the yml parsing of this block. It’d be nice to be able to use [start:end] syntax on parts of the context like ${{ github.sha[0:8] }} but I can confirm this doesn’t work :slight_smile:

It’s work for me. Thanks.

The hash that github.sha has appears to be some merge commit that isn’t present in the PR. Is there a way to reference the commit sha as it appears in the PR UI?

I solved this by calculating the slug in a separate step and using the output in subsequent steps:

- name: Get short SHA
        id: slug
        run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"

      - name: Create release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{ steps.today.outputs.date }}-${{ steps.slug.outputs.sha8 }}
          release_name: Release v${{ steps.today.outputs.date }}-${{ steps.slug.outputs.sha8 }}
          draft: false
          prerelease: false
8 Likes

If I try

      - name: Get short SHA
        id: slug
        run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"

      - name: Publish artifact
        run: |
          echo "GITHUB_SHA_SHORT=${steps.slug.outputs.sha8}"
          echo "GITHUB_SHA_SHORT=$GITHUB_SHA"

I get:

Run echo "GITHUB_SHA_SHORT=${steps.slug.outputs.sha8}"
  echo "GITHUB_SHA_SHORT=${steps.slug.outputs.sha8}"
  echo "GITHUB_SHA_SHORT=$GITHUB_SHA"
  shell: /bin/bash -e {0}
  env:
    JAVA_HOME_11.0.8_x64: /opt/hostedtoolcache/jdk/11.0.8/x64
    JAVA_HOME: /opt/hostedtoolcache/jdk/11.0.8/x64
    JAVA_HOME_11_0_8_X64: /opt/hostedtoolcache/jdk/11.0.8/x64
    GITHUB_TOKEN: ***
/home/runner/work/_temp/51fcd234-440b-40c3-a684-d9f39ca8b5d3.sh: line 1: GITHUB_SHA_SHORT=${steps.slug.outputs.sha8}: bad substitution
##[error]Process completed with exit code 1.

What am I doing wrong?

Edit: apparently bash cannot understand that, you need to go throw env

Or even better this