A simple and flexible Slack integration with GitHub Actions.
- 
Advanced users can use a configuration file and Handlebars templates to configure every aspect of the Slack message.
 - 
In addition to "legacy" attachments, rich messages can be created using layout blocks for flexible message visualisation and interactivity.
 
Create a Slack Webhook URL using either the Incoming Webhooks App (preferred) or by attaching an incoming webhook to an existing Slack App (beware, channel override not possible when using a Slack App):
env:
  SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Only required if the SLACK_WEBHOOK_URL environment variable is not set.
  with:
    webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
The status must be defined. It can either be the current job status
using:
  with:
    status: ${{ job.status }}
or a hardcoded custom status such as "starting" or "in progress":
  with:
    status: in progress
The individual status of job steps can be included in the Slack message using:
  with:
    status: ${{ job.status }}
    steps: ${{ toJson(steps) }}
Note: Only steps that have a "step id" will be reported on. See example below.
To override the channel or to send the Slack message to an individual use:
  with:
    status: ${{ job.status }}
    channel: '#workflows'
Note: To override the channel the Slack webhook URL must be an Incoming Webhook URL. See https://api.slack.com/faq#incoming_webhooks
To override the slack message use:
  with:
    status: ${{ job.status }}
    channel: '#workflows'
    message: Deploying {{ env.GITHUB_REF_NAME }} branch
A configuration file can be used to customise the following Slack message fields:
usernameicon_urlpretexttitleandtitle_linktextfallbackplain text summary used for dumb clients and notificationsfieldstitle, value and short/longblocksincludingactions,context,divider,file,header,image,inputandsectionblocks- message 
footer - border 
colorsbased job statussuccess,failure,cancelled. valid colors aregood(green),warning(yellow),danger(red) or any hex color code eg.#439FE0 iconsfor step statussuccess,failure,cancelled,skipped, and a default
Default: .github/slack.yml
  with:
    status: ${{ job.status }}
    config: .github/config/slack.yml
The following Slack message fields and block layouts support templating using Handlebars.js format:
pretexttitletextandmessagefallbackfieldstitleandvalueblocks
Supported Template variables
env.*, payload.*, jobName, jobStatus, jobSteps,
eventName, workflow, workflowUrl, workflowRunUrl, repositoryName, repositoryUrl, runId, runNumber, sha, shortSha, branch, actor, action, ref, refType, refUrl, diffRef, diffUrl, description, sender
Helper Functions
Apart from the standard helper functions such as #if and #each there are also a few custom
ones:
- 
iconconverts a job status into an icon eg.{{icon jobStatus}} - 
jsondumps the value as a JSON string eg.{{json payload.commits}} - 
truncatecuts the string at the limit eg.{{truncate sha 8}} - 
defaultallows a alternative or default value eg.{{default headRef "master"}} - 
pluralizeoutputs different text based on item count eg.{{pluralize requested_reviewers "reviewer" "reviewers"}}(if only singular form is given plural is derived by adding an "s") - 
eq,neq,not,and, andorcan be used as logical operators eg.{{#if (and (not has_issues) (or has_pages has_wiki))}}yes{{else}}no{{/if}} - 
#ifeqand#ifneqtest for variable equality or not eg.{{#ifneq event_name "create"}}yes{{else}}no{{/ifneq}} 
Example Using Config File
To generate the message format below use the slack.yml configuration file that follows.
Example Configuration File: slack.yml
username: GitHub-CI
icon_url: https://octodex.github.com/images/mona-the-rivetertocat.png
pretext: Triggered via {{eventName}} by {{actor}} {{or action "action"}} {{ref}} `{{diffRef}}`
title: GitHub Actions
title_link: https://support.github.com
text: |
  *<{{workflowRunUrl}}|Workflow _{{workflow}}_ job _{{jobName}}_ triggered by _{{eventName}}_ is _{{jobStatus}}_>* for <{{refUrl}}|`{{ref}}`>
  {{#if description}}<{{diffUrl}}|`{{diffRef}}`> - {{description}}{{/if}}
  {{#if payload.commits}}
  *Commits*
  {{#each payload.commits}}
  <{{this.url}}|`{{truncate this.id 8}}`> - {{this.message}}
  {{/each}}
  {{/if}}
fallback: |-
  [GitHub] {{workflow}} #{{runNumber}} {{jobName}} is {{jobStatus}}
fields:
  - title: Job Steps
    value: "{{#each jobSteps}}{{icon this.outcome}} {{@key}}\n{{/each}}"
    short: false
  - title: Workflow
    value: "<{{workflowUrl}}|{{workflow}}>"
    short: true
  - title: Git Ref
    value: "{{ref}} ({{refType}})"
    short: true
  - title: Run ID
    value: |-
      <{{workflowRunUrl}}|{{runId}}>
    short: true
  - title: Run Number
    value: "{{runNumber}}"
    short: true
  - title: Actor
    value: "{{actor}}"
    short: true
  - title: Job Status
    value: "{{jobStatus}}"
    short: true
footer: >-
  <{{repositoryUrl}}|{{repositoryName}}> {{workflow}} #{{runNumber}}
colors:
  success: '#5DADE2'
  failure: '#884EA0'
  cancelled: '#A569BD'
  default: '#7D3C98'
icons:
  success: ':white_check_mark:'
  failure: ':grimacing:'
  cancelled: ':x:'
  skipped: ':heavy_minus_sign:'
  default: ':interrobang:'
Notes:
- If template expressions occur at the start of a string the string must be double-quoted eg. 
pretext: "{{eventName}} triggered by {{actor}}" - Use YAML multiline string formats 
|,>,|-and>-or double-quotes"\n"to control new lines - Use 
~(tilde) character to control whitepace when looping see Whitespace control 
To ensure the Slack message is sent even if the job fails add the
always() function:
if: always()
or use a specific status function to only run when the job status matches. All possible status check functions are:
success()(default)always()cancelled()failure()
To send a Slack message when a workflow job has completed add the following as the last step of the job:
- uses: act10ns/slack@v1
  with: 
    status: ${{ job.status }}
  if: always()
To include statuses for each Job Step in the message include the
steps input (making sure to use the toJSON function):
- uses: act10ns/slack@v1
  with: 
    status: ${{ job.status }}
    steps: ${{ toJson(steps) }}
  if: always()
Only steps that have a "step id" assigned to them will be reported on:
- name: Build
  id: build
  run: |
    npm install
    npm run build
The default Slack channel for the configured webhook can be overridden
using either another channel name #channel or a username @username.
- uses: act10ns/slack@v1
  with: 
    status: ${{ job.status }}
    channel: '#workflows'
or
- uses: act10ns/slack@v1
  with: 
    status: ${{ job.status }}
    channel: '@nick'
name: Docker Build and Push
on:
  push:
    branches: [ master, release/* ]
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      REPOSITORY_URL: docker.pkg.github.com
      IMAGE_NAME: ${{ github.repository }}/alerta-cli
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
    steps:
      - uses: act10ns/slack@v1
        with:
          status: starting
          channel: '#workflows'
          message: Starting Docker Build and Push...
        if: always()
      - name: Checkout
        uses: actions/checkout@v2
      - name: Variables
        id: vars
        run: echo "::set-output name=SHORT_COMMIT_ID::$(git rev-parse --short HEAD)"
      - name: Build image
        id: docker-build
        run: >-
          docker build
          -t $IMAGE_NAME
          -t $REPOSITORY_URL/$IMAGE_NAME:${{ steps.vars.outputs.SHORT_COMMIT_ID }}
          -t $REPOSITORY_URL/$IMAGE_NAME:latest .
      - name: Docker Login
        env:
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
        run: docker login $REPOSITORY_URL --username "$DOCKER_USERNAME" --password "$DOCKER_PASSWORD"
      - name: Publish Image
        id: docker-push
        run: docker push $REPOSITORY_URL/$IMAGE_NAME
      - uses: act10ns/slack@v1
        with:
          status: ${{ job.status }}
          steps: ${{ toJson(steps) }}
          channel: '#workflows'
        if: always()
The above "Docker Build and Push" workflow will appear in Slack as:
To enable runner diagnostic logging set the ACTIONS_RUNNER_DEBUG secret to true.
To enable step debug logging set the ACTIONS_STEP_DEBUG secret to true.
- GitHub Actions Toolkit https://github.com/actions/toolkit/tree/main/packages/github
 - GitHub Actions Starter Workflows https://github.com/actions/starter-workflows
 - Slack Incoming Webhooks https://slack.com/apps/A0F7XDUAZ-incoming-webhooks?next_id=0
 - Env vars https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables
 - Webhook Payloads https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/webhook-events-and-payloads#webhook-payload-object-common-properties
 - GitHub Actions Cheat Sheet https://github.github.io/actions-cheat-sheet/actions-cheat-sheet.html
 - Slack Secondary message attachments https://api.slack.com/reference/messaging/attachments
 - Handlebars Language Guide https://handlebarsjs.com/guide/
 - YAML multiline string formats https://yaml-multiline.info/
 - Migrate your legacy message compositions to blocks https://api.slack.com/messaging/attachments-to-blocks
 
Copyright (c) 2020-2021 Nick Satterly. Available under the MIT License.


