37

I am creating a workflow in GitHub which creates and uses a docker image. Therefore I have started my workflow file with a global environment variable for this docker image which is visible for all the jobs in my workflow:

name: continuous integration
on:
  push:
    branches:
      - '**'

env:
  IMAGE: docker.pkg.github.com/${{ github.repository }}/jactor-persistence:${{ github.sha }}

I want to replace ${{ github.sha }} with the short sha of the head commit, the same as the result of the following command git rev-parse --short HEAD

Is this possible?

Cœur
  • 34,719
  • 24
  • 185
  • 251
jactor-rises
  • 1,549
  • 1
  • 14
  • 34

4 Answers4

56

As VonC mentioned, you can just compute the string yourself in a previous step.

      - name: Set outputs
        id: vars
        run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
      - name: Check outputs
        run: echo ${{ steps.vars.outputs.sha_short }}
peterevans
  • 24,033
  • 6
  • 67
  • 72
  • 1
    Good addition to my answer. The problem is knowing that 7 is short enough, and not too short: https://stackoverflow.com/a/21015031/6309 – VonC Jan 20 '20 at 08:50
  • Does `git rev-parse --short` vary to make it unique? I can't quite tell from the documentation. – peterevans Jan 20 '20 at 09:06
  • 1
    Yet it does: that is what https://stackoverflow.com/a/21015031/6309 documents/illustrates. – VonC Jan 20 '20 at 09:42
  • Thanks. I've made that the answer instead of selecting the first 7 characters. – peterevans Jan 20 '20 at 09:47
  • 1
    Great answer, but this fails to work correctly when run on windows. Need to quote the echo string. `echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"` – MaxGhost Mar 21 '20 at 23:41
  • 1
    Thanks @MaxGhost. Updated the answer. – peterevans Mar 22 '20 at 00:52
  • 1
    Oh also - worth mentioning that the commit hash on HEAD during a PR will actually refer to a merge commit that is the result of merging the PR branch into the target branch. CI runs on that merge to ensure that the build wouldn't be broken even when taking into account possible merge conflicts. It's the right commit hash when CI is run on the mainline branch though. Usually not a problem, but it might be for you depending on the usecase. – MaxGhost Mar 22 '20 at 00:58
  • 6
    In addition to @MaxGhost's comment, if you want latest commit's hash of the branch instead of merge commit: `echo "::set-output name=sha_short::$(git rev-parse --short ${{ github.event.pull_request.head.sha }})"` – Yoon-Jae Jeong Aug 10 '21 at 03:48
27

You can also set an environment variable with the short sha:

    - name: Add SHORT_SHA env property with commit short sha
      run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV

SHORT_SHA can then be used like any other environment variable, e.g. like this:

    - name: My step
      run: myscript ${SHORT_SHA}
Lars Grammel
  • 1,806
  • 16
  • 21
9

Found a possible solution here, using bash's parameter substitution

- name: Step
  run: echo ${GITHUB_SHA::7}
ushuz
  • 111
  • 1
  • 7
  • this is still something (it seems) that you need to run in a step somehow... even though it seems quite simple, it seems that it is not possible to do as a global variable... – jactor-rises Sep 08 '21 at 09:08
  • 1
    @jactor-rises what you are looking for is not possible at the moment, unless github adds short sha to variable/context, so currently, shortest is the best IMO – ushuz Sep 18 '21 at 02:08
2

It does not seem to be available: the github context only includes github.sha as the full commit sha (that triggered the workflow run)

You would need to somehow compute the string you want (by selecting only the first n characters of ${{ github.sha }}.

That means you can:

  • define a variable as shown in peterevans's answer
  • write it to the disk
  • cat $my_var to use your VAR in every step

See actions/starter-workflows issue 68 and examples.

But since Oct. 2019, you now have "Env at the workflow and job level"

It is common to need define a set of environment variables that are used in multiple steps in a job and even multiple jobs in a workflow.

Now you can add an env map at both the workflow and job level.
Those environment variables will be merged with the env defined at any step lower in the hierarchy.

See:

Community
  • 1
  • 1
VonC
  • 1,129,465
  • 480
  • 4,036
  • 4,755
  • yes... this is what I came to a conclusion myself. But is this possible to do in a expression in the global variable (in here somewhere`${{ github.sha }}`), to avoid to duplicate this all places which is in need of the variable – jactor-rises Jan 21 '20 at 08:11
  • @jactor-rises Sure sure about global, but peterevans's [answer](https://stackoverflow.com/a/59819441/6309) uses a variable. – VonC Jan 21 '20 at 08:17
  • .... I now that, but I would like to have a global env. variable to avoid duplicating code in my jobs... – jactor-rises Jan 21 '20 at 12:31
  • @jactor-rises That would be using an env map: see my edited answer above. – VonC Jan 21 '20 at 12:47
  • yes... and I am using workflow environment (`env` at the top of the workflow file) so it is available to all my jobs in the workflow. But at the workflow stage, is it possible to manipulate `${{ github.sha }}` to be the short sha, or do I have to duplicate this logic in my jobs? – jactor-rises Jan 22 '20 at 07:51