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:

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