loading...
Cover image for Slack Notifications with GitHub Actions

Slack Notifications with GitHub Actions

adamkdean profile image Adam K Dean ・4 min read

My Workflow

When I first started working with GitHub about a month ago, there were already quite a few Slack notification actions available, but I found each to either be cumbersome to use, or lacking what seemed like simple features such as status based messages.

So I created adamkdean/simple-slack-notify to try and address those issues, and this post will show you how to use it.

The main features are:

  • As simple or complex as you need it to be
  • Status based messages meaning one step handles job successes, failures, and cancellations
  • JavaScript strings for embedding environment variables or custom logic into notification strings
  • Easy to add fields based on standard Slack JSON inputs

 Example usage

The simplest use would consist of relying on the webhook's defaults and simply providing some text.

- name: Simple notification
  uses: adamkdean/simple-slack-notify@master
  with:
    text: 'This is the simplest notification'

Overriding the channel is sometimes needed, such as to separate out builds, deployments, and alerts perhaps.

- name: Channel specific notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#alerts'
    text: 'Something is happening and someone should probably panic'

The above works well, but what would really make someone panic is if we make the alert red, right?

You can use danger, warning, good, or a hex code such as #d90000.

- name: Panic inducing notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#alerts'
    text: 'Something is happening and someone should probably panic'
    color: 'danger'

Perhaps you also want to change the username?

- name: Panic Bot notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#alerts'
    username: 'Panic Bot'
    text: 'Something is happening and someone should probably panic'
    color: 'danger'

The action also supports fields, but due to the limitations of GitHub actions only passing in inputs as strings, we can't use yaml arrays. So, this is how you'd specify a field:

- name: Specifying what to panic about notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#alerts'
    username: 'Panic Bot'
    text: 'Something is happening and someone should probably panic'
    color: 'danger'
    fields: |
      [{ "title": "Reason to panic", "value": "Deployed failed halfway through" }]

If there were multiple reasons to panic, you'd add more objects to the fields array:

- name: Specifying what to panic about notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#alerts'
    username: 'Panic Bot'
    text: 'Something is happening and someone should probably panic'
    color: 'danger'
    fields: |
      [{ "title": "Reason to panic", "value": "Deployed failed halfway through", "short": true },
       { "title": "Timestamp", "value": "${Date.now()}", "short": true }]

Did you notice that some JavaScript snook in? Input strings are evaluated as a JavaScript strings, which means you can put environment variables into your messages, such as the GITHUB_WORKFLOW variable or GITHUB_RUN_NUMBER etc. The environment is stored within the env variable so to access environment variables in your strings, you simply use ${env.GITHUB_REPOSITORY} etc. Here's an example:

- name: Environment variable notification
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#example'
    text: '${env.GITHUB_WORKFLOW} (${env.GITHUB_RUN_NUMBER}) has finished'
    fields: |
      [{ "title": "Repository", "value": "${env.GITHUB_REPOSITORY}", "short": true },
       { "title": "Branch", "value": "${env.BRANCH}", "short": true }]

Now, each job has a status, which can be success, failed, or cancelled. Most other notification plugins use multiple blocks with if: success() and if: failed() etc but we don't need to do that. We can simply pass in the status and set status specific text. We use if: always() so that it runs regardless of whether the job is successful or not.

- name: Build notification
  if: always()
  uses: adamkdean/simple-slack-notify@master
  with:
    channel: '#builds'
    status: ${{ job.status }}
    success_text: '${env.GITHUB_WORKFLOW} (${env.GITHUB_RUN_NUMBER}) build completed successfully'
    failure_text: '${env.GITHUB_WORKFLOW} (${env.GITHUB_RUN_NUMBER}) build failed'
    cancelled_text: '${env.GITHUB_WORKFLOW} (${env.GITHUB_RUN_NUMBER}) build was cancelled'
    fields: |
      [{ "title": "Repository", "value": "${env.GITHUB_REPOSITORY}", "short": true },
       { "title": "Branch", "value": "${env.BRANCH}", "short": true }]

Below I show how I'm using this in an actual build & deployment workflow.

Submission Category:

  • Maintainer Must-Haves

Yaml File or Link to Code

The following example Yaml file shows adamkdean/simple-slack-notify being integrated into a build & deploy pipeline.

name: Build & Deploy
on: push
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
    - name: Build project
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.DEPLOY_HOST }}
        username: ${{ secrets.DEPLOY_USER }}
        key: ${{ secrets.DEPLOY_SSH_KEY }}
        port: ${{ secrets.DEPLOY_PORT }}
        script_stop: true
        script: |
          # Your build commands here
          example_build_project

    - name: Build notification
      if: always()
      uses: adamkdean/simple-slack-notify@master
      with:
        channel: '#builds'
        status: ${{ job.status }}
        success_text: 'Build (#${env.GITHUB_RUN_NUMBER}) completed successfully'
        failure_text: 'Build (#${env.GITHUB_RUN_NUMBER}) failed'
        cancelled_text: 'Build (#${env.GITHUB_RUN_NUMBER}) was cancelled'
        fields: |
          [{ "title": "Action URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}"}]

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    needs: build
    steps:
    - name: Deploy project
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.DEPLOY_HOST }}
        username: ${{ secrets.DEPLOY_USER }}
        key: ${{ secrets.DEPLOY_SSH_KEY }}
        port: ${{ secrets.DEPLOY_PORT }}
        script_stop: true
        script: |
          # Your deploy commands here
          example_deploy_project

    - name: Deploy notification
      if: always()
      uses: adamkdean/simple-slack-notify@master
      with:
        channel: '#deployments'
        status: ${{ job.status }}
        success_text: 'Deployment (#${env.GITHUB_RUN_NUMBER}) completed successfully'
        failure_text: 'Deployment (#${env.GITHUB_RUN_NUMBER}) failed'
        cancelled_text: 'Deployment (#${env.GITHUB_RUN_NUMBER}) was cancelled'
        fields: |
          [{ "title": "Host", "value": "${{ secrets.DEPLOY_HOST }}"},
           { "title": "Action URL", "value": "${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}"}]

Additional Resources / Info

GitHub logo adamkdean / simple-slack-notify

Slack notification action that just works

Simple Slack Notify

GitHub release (latest by date) GitHub Release Date License js-standard-style

Slack notification action that just works

Introduction

I've attempted to use a few of the Slack notification actions that are currently available, but they all seem to have limitations or be quite verbose, so I set out to create a simple yet effective action that just does what you need and nothing else. In the examples below, I'll show a few different variations of how the action could be used.

The main features are:

  • Status based messages meaning one step handles job successes, failures, and cancellations
  • JavaScript strings for embedding environment variables or custom logic into notification strings
  • Easy to add fields based on standard Slack JSON inputs

Be sure that you set the SLACK_WEBHOOK_URL environment variable, either in the job or in the step.

Example usage

The simplest use would consist of relying on the webhook's defaults and simply providing some text.

- name: Simple notification

Notes

I just wanted to point out for anyone new to GitHub Actions that while above I'm referring to the master branch (i.e. adamkdean/simple-slack-notify@master), if you're using this in production, it's always wiser to use a version. As of writing, the latest version is 1.0.4 so we would use adamkdean/simple-slack-notify@1.0.4.

Posted on by:

adamkdean profile

Adam K Dean

@adamkdean

Principal Network Engineer / Master of Engineering (Mechanical) student

Discussion

markdown guide
 

Great job, I've been thinking about writing something similar and now I don't have to :)

Some screenshots would go a long way, especially to visualize what fields collection does :)