115

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?

Ryan
  • 1,482
  • 2
  • 11
  • 19
CSSer
  • 2,131
  • 2
  • 18
  • 37

5 Answers5

232

There are 2 options of doing this:

  1. Use a second job inside the same workflow.yml together with the needs keyword
  2. 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):

build-job-triggers-publish-job

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.

jonashackt
  • 12,022
  • 5
  • 67
  • 124
  • 1
    The first approach (_with same workflow, separate job with needs keyword_) would not address the problem described: **I would like to receive Slack or Email messages informing the build results** as the dependent _notify_ job will **only** be triggered when the _build_ job succeeds but will not be triggered when it fails. – Marcin Kłopotek Jan 21 '21 at 10:32
  • 5
    Yeah, but as I wrote beneath the first approaches screenshot: "There's also [a way to always let the `notify` job run](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#example-not-requiring-dependent-jobs-to-be-successful), even if the `build` job failed. You have to enhance the `needs` with a `if: always()` configuration then." So using `if: always()` right before the `needs: build` will do the trick also with the first approach. – jonashackt Jan 21 '21 at 12:08
  • I would use workflow_dispatch rather than using workflow_run... Depends on the control u need when calling notify.yml... if I need to supply some values the next workflow i don't think it's possible via workflow_run... – niklodeon Jan 30 '21 at 23:03
  • 1
    `workflow_dispatch` is [a action you need to manually trigger](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch). That's an interesting approach I use myself in other contexts (e.g. release processes) - see this example https://github.com/jonashackt/github-actions-release-maven . But I guess it's not relevant in this very Q&A since the question was: "How could the message action be triggered after build action is completed?". This can't be done with the `workflow_dispatch` event because of it's manual nature. – jonashackt Feb 03 '21 at 12:27
  • 8
    Note that `workflow_run: completed` works regardless of upstream workflow failed or not. – Shinebayar G Feb 24 '21 at 18:41
  • 19
    Per https://docs.github.com/en/actions/reference/events-that-trigger-workflows you need to add `if: ${{ github.event.workflow_run.conclusion == 'success' }}` if you only want to trigger the workflow on the *success* of the first. – elithrar May 16 '21 at 13:34
  • Doea the second approach runs the workflows in different hardware or they are the same? Are the changes made with the first workflow are applied when the second runs? – Rafaelplayerxd YT Sep 21 '21 at 01:58
  • By `different hardware` you mean `different virtual machine` I guess? Yeah, using the second approach with 2 separate GitHub workflows will result in 2 separate VMs booted up. If you setup tools or prepare things on VM 1, they will not be available on VM 2. – jonashackt Sep 21 '21 at 09:44
15

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 }}
SgtPooki
  • 11,012
  • 5
  • 37
  • 46
  • All the other methods require way too much setup and work. – SgtPooki Jun 22 '22 at 01:09
  • Also, here's an example using this method: https://github.com/ipfs/ipfs-webui/blob/main/.github/workflows/node-versions.yml. This particular workflow is called on a schedule or manually via the github UI. – SgtPooki Jul 09 '22 at 05:11
  • 1
    Worth mentioning, do NOT use `runs-on` on the same job that you called the workflow with `uses` – Francisco Gomes Dec 04 '22 at 01:27
  • Ah, `secrets: inherit`. It just saved me from banging my head after 2 weeks of debugging without searching the internet. Upvoted! – theycallmepix Mar 04 '23 at 15:33
  • 1
    Local repo paths must start with ./ and may not reference versions – TheAl_T Mar 04 '23 at 16:16
13

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.

Marcin Kłopotek
  • 5,271
  • 4
  • 31
  • 51
9

you can try in step 2 the following directive:

needs: step-1-job-name 

just after job name

svirins
  • 131
  • 2
  • 2
3

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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250