3

I need help figuring something, I am trying to trigger 2 different workflows based on 2 different release tags. I want prod-* to trigger the production workflow and dev-* for the development workflow.

The problem is both tags trigger both workflows and I have no idea how to fix this

enter image description here

(I've canceled both actions but they triggered as you can see) enter image description here

Carlos Silva
  • 101
  • 2
  • 9

2 Answers2

6

The tags element is not valid for release events. In consequence, the workflow is triggered for every release event of type published no matter the tag. There is no direct filter for tags with the release event as there is for push and pull_request events.

So you can leverage the if conditional on jobs in combination with the github.ref in the context which contains the tag of the release.

name: Deploy

on:
  release:
    types: [published]

jobs:
  deploy-dev:
    name: Deploy to development
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/dev-')
    steps:
      # [...]

  deploy-prod:
    name: Deploy to production
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/prod-')
    steps:
      # [...]
Matt
  • 12,848
  • 2
  • 31
  • 53
  • 1
    We both did the same thing in different ways. However your solution looks easier (without using `outputs`) for being less verbose. Great answer – GuiFalourd Jul 29 '21 at 13:04
  • @GuiFalourd Thank you. Yes, the idea is basically the same and it is always great to see how things can be solved in different ways. – Matt Jul 29 '21 at 13:06
4

The published trigger is used in both cases here (independently of the tag), because your workflow will start for published OR tags (with the informed pattern) events.

To perform an operation only for a specific tag, you would have to extract the tag version from the $GITHUB_REF (env-var), for example using a step as below with an output in a first job:

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

And then use an if condition on 2 others jobs to check if the tag version contains prod- or dev- (needing the first job) to perform the operation you want for each scenario.

Here is an complete example of what could be used:

name: Example

on:
  release:
    types: [published]

jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      tag_version: ${{ steps.get_tag_version.outputs.version }}
    steps:
     - name: Get the version 
       id: get_tag_version 
       run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//}

   job2: # will be executed on for dev- tag
    runs-on: ubuntu-latest
    needs: [job1]
    if: contains( needs.job1.outputs.tag_version , 'dev-')
    steps:
     [...]

   job3: # will be executed on for prod- tag
    runs-on: ubuntu-latest
    needs: [job1]
    if: contains( needs.job1.outputs.tag_version , 'prod-')
    steps:
     [...]
   

I coded a workflow to test the implementation above and it worked as expected creating a prod-2 release tag:

Example

EDIT: Note that you could also use a startWith instead of a contains function for the if expression.

GuiFalourd
  • 15,523
  • 8
  • 44
  • 71