how to define workflow to run based on two push rules - github

Is there a way to define 2 push rules in same workflow file or work around ?
How to combine and write below rules into single workflow file :
Run when any file is pushed on non master branch
On:
push:
branches-ignore:
- 'master'
paths:
- 'path-to-package/**'
Run Only when particular(package.json) file pushed in master branch
On:
push:
branches:
- 'master'
paths:
- 'path-to-package/package.json'

Your specific request doesn't appear to be supported by the syntax.
According to the workflow syntax for GitHub Actions documentation, two trigger configurations appear unrelated.
GitHub allows free users to open support requests. You could always make a feature request at support.github.com/contact
The closest workaround I know at the moment would be something like the workflow below, using a conditional inside your jobs.
on:
push:
paths:
- 'path-to-package/package.json'
jobs:
build_pom:
runs-on: ubuntu-latest
steps:
- run: echo 'this is master'
if: github.ref == 'refs/heads/master'

Related

Azure Devops Pipeline Trigger on tag and specific Branch

I exhausted all the options here and its only Tuesday.
I have a repository with 3 branches:
development
staging
master
I am trying to set the triggers to behave differently based on the branch. What i mean it this:
development = trigger on everything (commit, pr and tags)
Staging = Trigger only on tags created on this branch
Master = Same as staging.
I have the 3 pipelines as follow:
Development branch:
trigger:
branches:
include:
- development
Staging Branch:
trigger:
batch: true
tags:
include:
- 'v*'
branches:
include:
- staging
exclude:
- '*'
Master Branch
trigger:
batch: true
tags:
include:
- 'v*'
branches:
include:
- main
exclude:
- '*'
Everything works just fine when i push a normal commit on development, only development triggers. but if i create a tag on development all the pipelines trigger(staging and master). As far as i understand the Tags and Branches are conditions that as long as one of them is true, they trigger. I dont understand why microsoft is doing it this way if the pipelines resides in different branches but i am looking for a work around this limitations. I thought on excluding the branches but that will go out of control easily.
Any advice or a better solution please?
Thank you so much for any help you can provide me with
From this doc, it seems you could not let tags filter with branch filters that include file paths.
But considering that includes are processed first, and then excludes are removed from that list.
Therefore, you could try to write clearly the tag as an explicit include and exclude in the triggers part to see whether it could meet your requirement:
New a repo with three empty branches: stage, main, dev
In dev you should write tag include in trigger if you would like it be triggered by tags in dev branch:
for example, 2.yml in dev branch
trigger:
branches:
include:
- dev
tags:
include:
- v*
azure-pipelines.yml in main branch:
trigger:
batch: true
branches:
include:
- main
- refs/tags/v*
exclude:
- dev
- stage
tags:
include:
- v*
exclude:
- dev/*
- stage/*
paths:
exclude:
- /*
and 1.yml in stage branch:
trigger:
batch: true
branches:
include:
- stage
- refs/tags/v*
exclude:
- dev
- main
tags:
include:
- v*
exclude:
- dev/*
- main/*
paths:
exclude:
- /*
Then here are results test from my side:
commits on dev triggers 2.yml pipeline
adding tag v* on dev will triggers 2.yml pipeline
commits on stage doesn't trigger 1.yml pipeline
adding tag v* on dev triggers 1.yml pipeline
commit on main trigger azure-pipelines.yml pipeline
add tag v* on main trigger azure-pipelines.yml pipeline
Please kindly see and try whether it is what you want.
You could also consider the following two methods:
Alternative 1: As your first step, conditionally abort the build as "cancelled" if the branch name is not what you expect. You could see this for more details.
Alternative 2: Add a condition like eq(variables['Build.SourceBranchname'], 'master') or contains(variables['build.sourceBranch'], 'refs/heads/main') to every single step in your pipeline. This is tedious, but simple. You could see the doc for more details.

Trigger diferent jobs depending on pull request type

I'm trying to reduce the amount of files I have for my workflows from 4 to 1. And with that my on is like this:
on:
pull_request:
types: [opened, synchronize, closed]
push:
branches: [master]
I know it's possible to use if in workflows but looking at the documentation I didn't find which parameters I should use to trigger the correct jobs when:
Pull request is opened
Pull request is closed
Push is made to a existing pull request
Push is made to a brach
The piece of documentation that touches on how to use if is this one.
You can use it at the job level. Consider the following example to execute a job only when the PR has been closed and merged (not just closed):
name: Build Your App
on:
pull_request:
types: [ closed ]
jobs:
build:
# this job will only run if the PR has been merged, not just 'closed'
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout#v2
with:
fetch-depth: '0'
And you can also use it at the step level, to execute or not the step based on the {{ expression }} evaluation, as the documentation shows.
Based on your ask, I would use the information on the github.event.* payload. To do that I use to re-create the conditions and triggers on a test repository and print it to the console. Then I know what I have to look for in each kind of event. It's like debugging the events. This is the documentation to do that.

Github Actions - trigger another action after one action is completed

I have one action (a yaml file) for deploying a docker image to Google Cloud Run.
I would like to receive Slack or Email messages informing the build and push results.
How could the message action be triggered after build action is completed?
Is it possible to get the result of the build action?
There are 2 options of doing this:
Use a second job inside the same workflow.yml together with the needs keyword
Create a separate notify.yml workflow that uses the workflow_run event as a trigger
1. Same workflow, separate job with needs keyword
In your workflow.yml file you simply define two jobs like this (leveraging the needs: build configuration in the second job):
name: CI build and notify
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Deploy Docker image to Google Cloud Run
run: ...
notify:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Notify Slack and send eMail
run: ...
As the docs state, the second notify job will only start if the first build job succeeded:
Identifies any jobs that must complete successfully before this job
will run.
Here's a screenshot of how this approach can look like practically from my own project (I have a second publish-snapshot job instead of your notify job - but the concept stays the same):
There's also a way to always let the notify job run, even if the build job failed. You have to enhance the needs with a if: always() configuration then.
2. Separate workflow, using the workflow_run event as a trigger
Using the workflow_run event as a trigger we end up having 2 separate GitHub Actions workflow yaml files:
build.yml
name: CI build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Deploy Docker image to Google Cloud Run
run: ...
notify.yml
name: CI notify
# Only trigger, when the build workflow succeeded
on:
workflow_run:
workflows: ["CI build"]
types:
- completed
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Notify Slack and send eMail
run: ...
A crucial point here is that the name: CI build definition of the first yaml file must exactly match the workflow_run: workflows: ["CI build"] definition in the second yaml file. Another point is that this approach needs to be done on the default branch (which is mostly main or master) as the docs state:
Note: This event will only trigger a workflow run if the workflow file
is on the default branch.
Here's also a full example project using the 1st option if you're interested.
First, you are mixing terms here. According to GitHub Actions documentation a single YAML file is called a workflow (not an action) and consists of jobs. Jobs contain a sequence of steps (including actions) that are executed one after another. A particular workflow execution is called a run. Having that in mind lets go the questions.
How could the message workflow be triggered after build workflow is completed?
You can use GitHub API to trigger a webhook event called repository_dispatch (only for the base branch) or workflow_dispatch. This can be easily done using a dedicated Repository Dispach action in your build workflow.
Is it possible to get the result of the build workflow?
Yes, the result of the workflow run can be obtained using given GitHub API
But if you only want to send the build result notification of the currently executed workflow you don't need to create a separate workflow and trigger it from the parent. You can use dedicated Slack actions or e-mail actions.
you can try in step 2 the following directive:
needs: step-1-job-name
just after job name
The best method i've found for reusable workflows in the same repository is https://docs.github.com/en/actions/using-workflows/reusing-workflows
In the workflow you want to re-use (let's call it wf1):
# wf1.yml
on:
workflow_call:
In the workflow you want to call wf1 from (let's call this wf2)
# wf2.yml
jobs:
call-wf1:
uses: ./.github/workflows/wf1.yml
secrets: inherit
In order to get data from one workflow to another, check out https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-outputs-from-a-reusable-workflow.
First, set up your reusable workflow to output the data:
name: Reusable workflow
on:
workflow_call:
# Map the workflow outputs to job outputs
outputs:
firstword:
description: "The first output string"
value: ${{ jobs.example_job.outputs.output1 }}
secondword:
description: "The second output string"
value: ${{ jobs.example_job.outputs.output2 }}
jobs:
example_job:
name: Generate output
runs-on: ubuntu-latest
# Map the job outputs to step outputs
outputs:
output1: ${{ steps.step1.outputs.firstword }}
output2: ${{ steps.step2.outputs.secondword }}
steps:
- id: step1
run: echo "::set-output name=firstword::hello"
- id: step2
run: echo "::set-output name=secondword::world"
Now use it in the calling workflow:
name: Call a reusable workflow and use its outputs
on:
workflow_dispatch:
jobs:
job1:
# local repo
# uses: .github/workflows/called-workflow.yml#v1
# other repo
uses: octo-org/example-repo/.github/workflows/called-workflow.yml#v1
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- run: echo ${{ needs.job1.outputs.firstword }} ${{ needs.job1.outputs.secondword }}
How could the message action be triggered after build action is completed?
This should now (August 2020) be possible with "GitHub Actions improvements for fork and pull request workflows"
Another frequently-requested feature for Actions is a way to trigger one workflow based on the completion of another workflow.
For example, you may want to take the results of a CI workflow and run some further analysis.
The new workflow_run event enables you to trigger a new workflow when one or more workflows are requested or completed.
Runs triggered by the workflow_run event always use the default branch for the repository, and have access to a read/write token as well as secrets.
As an example, as a maintainer you could set up a workflow that takes the artifacts generated by the pull request workflow, do some analysis, and post comments back to the pull request.
This event is also available as a web hook.

How to run a Github Action when a pull requestion is merged to master?

I am new to Github actions and I have searched all over to answer my question. I have an action setup to run on all push events but apparently that does not count for merging pull requests. So I wanted to know how I can run an action when a pull request is merged.
name: CI
on: push
jobs:
test:
name: test
...
deploy:
name: Deploy
needs: [test] # will wait until test finished
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
...
One way is to use if condition.

Have a unique check-run for github actions workflow

I'm trying to enforce labelling PR's using enforce-label-action.
name: Enforce PR label
on:
pull_request:
types: [labeled, unlabeled, opened, edited]
jobs:
enforce-label:
runs-on: ubuntu-latest
steps:
- uses: yogevbd/enforce-label-action#master
with:
REQUIRED_LABELS_ANY: "bug,enhancement,feature"
The problem is that each time PR is labeled, a new check-run getting created and the old one's still having a failing status which cause the check-suite to show: Some checks were not successful.
Is it possible for github-actions to discard the old check-runs when a workflow check with the same name is getting triggered?
This is now fixed, it was a bug on GitHubs end.