How to get just the tag name?

I trigger my workflow using

on:
  push:
    tags:

and I just want the name of the current tag that is just building.

Sadly, the github context variable’s ref has this value:

"ref": "refs/tags/0.3.1"

However, I only want the last part, 0.3.1.

There exists no function in GitHub Actions that allows me to extract that.

Am I overlooking something? How do I get that?

7 Likes

You can use paramter expansion:

${GITHUB_REF##*/}

https://stackoverflow.com/questions/9532654/bash-expression-after-last-specific-character

7 Likes

Nothing indicates that GitHub Actions use bash to evaluate their variables. Are you quite that this is supposed to work?

2 Likes

You could use actions/github-script

jobs:
  test:
    runs-on: ubuntu-18.04
    steps:
      - name: Extract tag name
        id: tag
        uses: actions/github-script@0.2.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            return context.payload.ref.replace(/\/refs\/tags\//, '');
      - name: Echo
        run: echo ${{ steps.tag.outputs.result }}
6 Likes

Have you tested this? This produced an empty value for me for some reason.

1 Like

This is how I’m currently doing it:

- name: Get the version
  id: get_version
  run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)

Then you have the output of that step and any later step in the job can use this by referring to it either in the run part or in an input. 

${{ steps.get_version.outputs.VERSION }}
9 Likes

Note that tags can contain a / character in them.  For completeness, I’d actually recommend explicitly removing the refs/tags/ instead of splitting on the / as a delimeter.  For example:

- name: Get the version
  id: get_version
  run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
28 Likes

Thanks. Could you add that as a general context/environment variable? It seems to me to be a very common use case and this step of truncating the string is just really annoying IMO.

18 Likes

At the moment we’re basically populating the data from the webhook.  If we start adding additional data beyond that then this seems like a good candidate.  Thanks for the feedback!

3 Likes

I prefer this syntax:

- name: Get the version
  id: get_version
  run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
8 Likes

My approach is setting three vars:

SOURCE_NAME : The branch or the tag

SOURCE_BRANCH : The branch or empty

SOURCE_TAG : The tag or empty

- name: Branch name
        id: branch_name
        run: |
          echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}
          echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}
          echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}

And to use it, just declare as ENV vars in each task

- name: Build base image
        run: |
          echo $SOURCE_NAME
          echo $SOURCE_BRANCH
          echo $SOURCE_TAG
        env:
          SOURCE_NAME: ${{ steps.branch_name.outputs.SOURCE_NAME }}
          SOURCE_BRANCH: ${{ steps.branch_name.outputs.SOURCE_BRANCH }}
          SOURCE_TAG: ${{ steps.branch_name.outputs.SOURCE_TAG }}
7 Likes

This is awefull and annoying, I been wasting my time and breaking my head over this for hours. Gitlab has a dead simple straight forward to the point

CI_COMMIT_SLUG

that gives you a short represenstation of the current build without any charcters you do not want for filename and the likes. Just [a-z0-9-] the fact that we have to use this super ugly and annoying to read syntax

echo ::set-output name=SOURCE_NAME::${...

BELOW THE job env declaration sucks. And its not finished there, still need to cut out characters.

Github shoud just copy Gitlab here and provide a slug.

If anyone has a idea hwo I in a most siple way copy wtat gitlab may to to output the slug I would appreciate it.

3 Likes

@ethomson how would you do for a Windows runner ?

I’m not very familiar with PowerShell, so what I’d do is just run it in bash on Windows.  You can do this by setting shell: bash for that run step.

2 Likes

> Note that tags can contain a / character in them.

Can they? When I run docker build . -t foo:bar/baz I get invalid argument "foo:bar/baz" for "-t, --tag" flag: invalid reference format due to the forward slash.

I use this for windows

$SOURCE_NAME = ${env:GITHUB_REF} -replace ‘refs/\w+/’, ‘’
$SOURCE_BRANCH = ${env:GITHUB_REF} -replace ‘refs/heads/’, ‘’
$SOURCE_TAG = ${env:GITHUB_REF} -replace ‘refs/tags/’, ‘’

echo “::set-env name=SOURCE_NAME::$SOURCE_NAME”
echo “::set-env name=SOURCE_BRANCH::$SOURCE_BRANCH”
echo “::set-env name=SOURCE_TAG::$SOURCE_TAG”

With Windows ( runs-on: windows-latest ) it would be

- name: Get the version
  id: get_version
  run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
  shell: bash

and you can use it with PowerShell e.g.

- name: Zip .exe
  run: Compress-Archive -Path some.exe -DestinationPath Release_${{ steps.get_version.outputs.VERSION }}.zip -CompressionLevel Optimal
2 Likes

Any idea how to get the tag name to the artifact file name? I have been trying to use this steps.tag.output.result to the artifact filename but its returing null.

Any update on that? I’m strugglin because I want to publish artifacts from the build but for some reason they have to be unique. Okay, I can use tag, but there is no variable for it. And I cannot use suggested workarounds becuase i need to use tag in matrix, before all the jobs are run.

This accepted solution doesn’t seem to work on windows-latest; the version always comes off empty.