Reputation: 20536
I'm trying to move my CI workflow from CircleCI to GitHub Actions. The last major struggle I'm facing is with deployment.
Currently my workflow is such that when I push a tag to my GitHub repo, it will run the tests, then run the deployment. Only thing is CircleCI filters tags to only run the job if the tag matches the regex: /v[0-9]+(\.[0-9]+)*/
.
How can I check to ensure the tag I pushed matches the regex pattern above before running the deployment?
I currently have the following GitHub Actions yml file:
name: CI
on: [create]
jobs:
# ...
deploy:
runs-on: ubuntu-latest
if: github.event.ref_type == 'tag' && github.event.ref == SOMETHING HERE
steps:
- uses: actions/checkout@v1
# ...
Under the if
block, I need to change github.event.ref == SOMETHING HERE
to be something else. I have looked in the Contexts and expression syntax for GitHub Actions documentation page. But due to how flexible and powerful GitHub Actions is, it seems like there should be a method or way to do this, or at least some type of workaround.
How can I ensure the tag (github.event.ref
) matches the regex pattern (/v[0-9]+(\.[0-9]+)*/
)?
Upvotes: 43
Views: 51435
Reputation: 3881
I have managed to achieve this with a two part approach. The first part consists of filtering the tags that you want to run on. The second part is to create a condition on your deploy
job.
A cut down version of my workflow looks like the following:
name: CI-CD
on:
push:
branches:
- stable
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+rc[0-9]+'
pull_request:
branches:
- stable
jobs:
test:
steps:
...
deploy:
needs: test
if: startsWith(github.ref, 'refs/tags')
steps:
...
I run my workflows on pushes, tags, and pull request to specific branches. You can get creative with how exactly you want to filter your tags. Check out the filter patterns.
The part I was struggling with a bit was how to set the right condition to run the deploy
job. I settled on the following:
needs: test
which ensures that it will only run when the test
job has succeeded.
Then I abuse the fact that github.ref
will be 'refs/heads/stable'
on a push to the branch and 'refs/tags/<your tag>'
on pushing a tag. So I simply test for that difference with the following condition.
if: startsWith(github.ref, 'refs/tags')
Works like a charm for me but may depend on your setup.
You can also create separate workflows, of course, but in my case I always wanted to run the test suite first.
EDIT: As @alex-povel comments below, a more explicit check is:
if: github.ref_type == 'tag'
Note that the symbol on the other side of the comparison should be a single quoted string. Using a double quoted string would lead to the error: Unexpected symbol: '"tag"'
.
Upvotes: 25
Reputation: 41980
Unfortunately, I don't think there is any way to do regex matching on if
conditional expressions yet.
One option is to use filtering on push
events.
on:
push:
tags:
- 'v*.*.*'
Another option is to do the regex check in a separate step where it creates a step output. This can then be used in an if
conditional.
- name: Check Tag
id: check-tag
run: |
if [[ ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "match=true" >> $GITHUB_OUTPUT
fi
- name: Build
if: steps.check-tag.outputs.match == 'true'
run: |
echo "Tag is a match"
Upvotes: 56