action-slack icon indicating copy to clipboard operation
action-slack copied to clipboard

Single notification for workflow

Open jasonvarga opened this issue 4 years ago • 10 comments

Is it possible to send a single notification for the entire workflow?

For example, if my workflow has multiple jobs running test suites and all of them fail, my Slack channel gets bombarded with notifications.

If my test suite fails, one notification is enough.

It would be nice for an option for something like "prevent sending if already sent".

jasonvarga avatar Jun 18 '20 14:06 jasonvarga

I see. I've certainly felt that too. I can't think of a very quick way to do it, but I'll try to think of a way.

8398a7 avatar Jun 18 '20 14:06 8398a7

Are there any sort of caches available to the action? (Sorry, don't really know much about Action internals yet) Perhaps a flag can be stored along with the workflow ID and checked every time it runs?

jasonvarga avatar Jun 18 '20 14:06 jasonvarga

Cache is also a good idea. But state management can be complicated, so I'm thinking of other ideas.

My proposal needs to be narrowed down to the following notation. The point is twofold.

  • A ensures that other jobs will be completed by with.after_jobs
  • Separate jobs for action-slack only
name: example
on: push

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
     - run: test
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: lint
  action-slack:
    runs-on: ubuntu-latest
    steps:
      - uses: 8398a7/action-slack@v3
        with:
          after_jobs: test,lint
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

In this case, I'd like to do a slack notification after the test and lint jobs are completed. In GitHub Actions, you can control the order of jobs by needs, but this is inappropriate for the requirement because subsequent jobs are skipped when the previous step fails.

We will add a parameter called after_jobs to satisfy the requirement. action-slack monitors the status of the other jobs until the specified job is completed. Internally you will be monitoring the state of the job by polling, as other job states can be seen in the Get a job for a workflow run.

It might be possible to achieve this with a simpler mechanism by separating the workflow, but I haven't given it much thought yet.

8398a7 avatar Jun 20 '20 08:06 8398a7

confirming that adding this to a final step in my workflow as below works - sends a single notification for a number of different jobs:

  slack-notification:
    needs: [put,other,job,ids,here]
    if: ${{ failure() }}
    name: Slack Notification
    runs-on: ubuntu-latest
    steps:
      - uses: 8398a7/action-slack@v3
        with:
          status: ${{ needs.tests.result }}
          fields: author,action,ref,workflow
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
        if: always() # Pick up events even if the job fails or is canceled.

jfunke-well avatar Jun 24 '20 20:06 jfunke-well

needs specified job must be successful. In this case, no failure notification is given.

8398a7 avatar Jun 25 '20 04:06 8398a7

Oops, I was missing out.

    needs: [put,other,job,ids,here]
    if: ${{ failure() }}

By writing needs and if together, can I wait until the job is finished and still run the job if it fails?

8398a7 avatar Jun 25 '20 05:06 8398a7

Yes I have it working in my workflow. My tests all run before this job and if any have failed, the job I pasted will send a slack notification.

The Needs line specified that this job will wait until the specified jobs are complete, the if statement can be changed to always() if you want it to run every time regardless of the whole workflow success/failure/cancel Also make sure to include the final if: always () at the end edit: actually i thought i had this working but it's still skipping.

jfunke-well avatar Jun 25 '20 06:06 jfunke-well

check out https://github.com/technote-space/workflow-conclusion-action for the best working solution to this

jfunke-well avatar Jun 25 '20 18:06 jfunke-well

The workflow-conclusion-action method worked really well for me. Personally, I'd be fine with just doing that, and not needing anything else added to action-slack.

To clarify, the key seems to be that you can make a separate job that needs your other jobs, rather than just another step in an existing job.

jobs:
  this-job: ...

  that-job: ...

  slack:
    runs-on: ubuntu-latest
    needs: [this-job, that-job]

    # this is required, otherwise it gets skipped if any needed jobs fail. 
    # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idneeds
    if: always()

    steps:
      - uses: technote-space/workflow-conclusion-action@v1
      - name: Send Slack notification
        uses: 8398a7/action-slack@v2
        if: env.WORKFLOW_CONCLUSION == 'failure'
        with:
          status: failure
          author_name: ${{ github.actor }}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Thanks @8398a7 and @jfunke-well !

jasonvarga avatar Jun 26 '20 02:06 jasonvarga

I think this approach does not work if you want to include output of steps in other jobs by using environment variables, as variables written in $GITHUB_ENV are only available to the later steps in the same job.

hoxu avatar Jun 28 '21 08:06 hoxu