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.
Related
I have a called workflow that deploys the app to Heroku. It is triggered by a pr comment.
name: Preview App Deployment
on:
issue_comment:
types: [created]
jobs:
call-heroku-preview-app:
name: Deploy to Heroku
if: ${{ contains(github.event.comment.body, '/deploy') }}
uses: ./.github/workflows/heroku-preview-app.yml
However, it doesn't show up in the pr checks as it does for jobs that are triggered by
on:
pull_request:
types: [synchronize, opened, reopened, ready_for_review]
branches-ignore: [master, production]
which hurts visibility. Also, I'm planning to add another workflow triggered by a comment that runs unit and e2e tests. If the result won't be included in the Github checks it will be a problem.
So is it really impossible to include them there or I'm missing something?
PR Checks are attached to a commit, but when you're running a workflow on issue_comment what would the context be? Intuitively, comment in a PR is not a thing related to a commit.
In fact, when looking at ${{ github.sha }} inside a workflow triggered by issue_comment, the SHA is actually that of the default branch.
You could manually add a check using the Check Runs API.
However, when triggering this on issue_comment, you're going to have to replace the value github.sha with your own logic to identify the tip of the branch associated with the PR for which the comment was made.
- uses: actions/checkout#v3
- run: echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
- run: echo '{"name":"Test Check","head_sha":"${{ github.sha }}"}' | gh api /repos/{owner}/{repo}/check-runs --input -
Is there are reason you're only deploying when a comment is made? Why not deploy on every push? As you mentioned end-to-end tests as well, this would be another type of thing that is usually run automatically rather than when a person adds a comment.
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.
I have two workflows, the first one runs a build script and generates an artifact.
The first one is triggered when a pull request is created like this:
name: build
on:
pull_request:
types: [opened, edited, ready_for_review, reopened]
The second flow runs when the first is done, by using the workflow_runtrigger like this:
on:
workflow_run:
workflows: ["build"]
types:
- "completed"
The second flow has to be separate and run after the first one. When done it is supposed to post a comment on the PR that triggered the first workflow, but I am unable to find out how.
According to the Github Action Docs this is one of the typical use cases, as per this qoute:
For example, if your pull_request workflow generates build artifacts, you can create
a new workflow that uses workflow_run to analyze the results and add a comment to the
original pull request.
But I can't seem to find out how. I can get the first workflow's id in the 2nd workflow's context.payload.workflow_run.id, but workflow_run should also have about the pull request, but they`re empty.
What am I doing wrong, and where can I find the necessary info to be able to comment on my created pull request?
You're not doing anything wrong, it's just that the Pull Request datas from the first workflow are not present in the Github Context of the second workflow.
To resolve your problem, you could send the Pull Request datas you need from the first workflow to the second workflow.
There are different ways to do it, for example using a dispatch event (instead of a workflow run), or an artifact.
For the artifact, it would look like something as below:
In the FIRST workflow, you get the PR number from the github.event. Then you save that number into a file and upload it as an artifact.
- name: Save the PR number in an artifact
shell: bash
env:
PULL_REQUEST_NUMBER: ${{ github.event.number }}
run: echo $PULL_REQUEST_NUMBER > pull_request_number.txt
- name: Upload the PULL REQUEST number
uses: actions/upload-artifact#v2
with:
name: pull_request_number
path: ./pull_request_number.txt
In the SECOND workflow, you get the artifact and the Pull Request number from the FIRST workflow, using the following GitHub Apps:
- name: Download workflow artifact
uses: dawidd6/action-download-artifact#v2.11.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: <first_workflow_name>.yml
run_id: ${{ github.event.workflow_run.id }}
- name: Read the pull_request_number.txt file
id: pull_request_number_reader
uses: juliangruber/read-file-action#v1.0.0
with:
path: ./pull_request_number/pull_request_number.txt
- name: Step to add comment on PR
[...]
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'
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.