Slack Notifications¶
If a test fails in the woods and no one is there to see it turn red, did it really fail?

Whilst your jobs can automatically trigger without a human, it isn't often helpful for them to fail without a human being notified. If you use Slack, or a different chat room where your team hangs out, then I suggest having your pipeline inform you of failures or successes.
Consider a job that quietly fails 50% of the time but doesn't notify anyone.
resources:
- name: tutorial
type: git
source:
uri: https://github.com/starkandwayne/concourse-tutorial.git
branch: develop
jobs:
- name: test
public: true
serial: true
plan:
- do:
- get: tutorial
trigger: true
- task: test-sometimes-works
config:
platform: linux
image_resource:
type: docker-image
source: {repository: busybox}
inputs:
- name: tutorial
run:
path: tutorial/tutorials/miscellaneous/slack-notifications/test-sometimes-works.sh
Create this pipeline and run the test job a few times. Sometimes it will succeed and other times it will fail.
cd tutorials/miscellaneous/slack-notifications
fly -t bucc set-pipeline -p slack-notifications -c pipeline-no-notifications.yml
fly -t bucc unpause-pipeline -p slack-notifications
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
Custom Resource Types¶
Specifically for Slack there is a custom Resource Type cfcommunity/slack-notification-resource (see source on Github). We can add any custom Resource Types to our pipeline.yml with the top-level resource_types.
resource_types:
- name: slack-notification
type: docker-image
source:
repository: cfcommunity/slack-notification-resource
resources:
- name: notify
type: slack-notification
source:
url: ((slack-webhook))
Join a Slack organization¶
You want to send slack notifications. First you'll need to create an organization or be invited.
In the examples below I will use the defunct https://concourseci.slack.com organization. Update concourseci to your organization.
Slack Web Hooks¶
Visit the /services/new/incoming-webhook for your Slack organization. For example, for concourseci organization:
https://concourseci.slack.com/services/new/incoming-webhook/
Choose a public or private channel into which your notifications will be delivered. For this tutorial, choose your own personal channel "Privately to you".

Click "Add Incoming WebHooks integration" button.
On the next page, you will be given a unique secret URL. Triple click to select, then copy it to your clipboard.

Each pipeline might have its own ((slack-webhook)) parameter to send notifications to different Slack channels. So we will store the URL in a pipeline-specific location in Credhub (remember to run bucc credhub in your bucc project to re-login to Credhub):
credhub set -n /concourse/main/slack-notifications/slack-webhook -t value -v https://hooks.slack.com/services/T02FXXXXX/B8FLXXXXX/vfnkP8lwogK0uYDZCxxxxxxx
Notification on Job Failure¶
If you haven't already, add to your pipeline.yml the resource_types section and additional resources section introduced in Custom Resource Types above.
Next, we need to introduce the on_failure section of all build plan steps.
Any get, put, or task step of a build plan can catch failures and do something interesting. From the Concourse CI documentation:
plan:
- get: foo
- task: unit
file: foo/unit.yml
on_failure:
task: alert
file: foo/alert.yml
In our pipeline, we will add on_failure to our task: test-sometimes-works:
- task: test-sometimes-works
config:
...
run:
path: tutorial/tutorials/miscellaneous/slack-notifications/test-sometimes-works.sh
on_failure:
put: notify
params:
text: "Job 'test' failed"
We use the on_failure to invoke the slack-notification resource named notify which will send a message to our ((slack-webhook)) web hook.
Update your pipeline and trigger the test job until you get a failure:
fly -t bucc set-pipeline -p slack-notifications -c pipeline-slack-failures.yml
fly -t bucc trigger-job -j slack-notifications/test -w
Your lovely failure will now appear as a notification in Slack:

Dynamic Notification Messages¶
In the preceding section the notification text was hardcoded within the pipeline-slack-failures.yml file. It is possible to generate dynamic messages for your notifications.
It is also possible to emit success notifications.
In the example below there are two notifications (Slack combines messages from the same sender to save space). Each message contains information that is dynamically

From the README of the slack-notification-resource being used, we can see there is a text and a text_file parameter https://github.com/cloudfoundry-community/slack-notification-resource#out-sends-message-to-slack
text: Static text of the message to send.text_file: File that contains the message to send. This allows the message to be generated by a previous task step in the Concourse job.
We will switch from text to text_file.
We will also add an on_success step hook to explicitly catch both success and failure outcomes of the task: test-sometimes-works step and display a message.
jobs:
- name: test
public: true
serial: true
plan:
- get: tutorial
trigger: true
- task: test-sometimes-works
config:
platform: linux
image_resource:
type: docker-image
source: {repository: busybox}
inputs:
- name: tutorial
outputs:
- name: notify_message
run:
path: tutorial/tutorials/miscellaneous/slack-notifications/test-sometimes-works-notify-message.sh
on_success:
put: notify
params:
text_file: notify_message/message
on_failure:
put: notify
params:
text_file: notify_message/message
Above, the notify-message folder is created by the task: test-sometimes-works step as an output, and consumed by put: notify resource. See the Basics section on Passing task outputs to another task to revise this topic.
The task: test-sometimes-works step runs the test-sometimes-works-notify-message.sh script, which is the same as test-sometimes-works.sh but also creates a file notify_message/message.
value=$RANDOM
if [[ $value -gt 16384 ]]; then
cat > notify_message/message <<EOF
Unfortunately the \`test\` job failed. The random value $value needed to be less than 16384 to succeed.
EOF
exit 1
else
cat > notify_message/message <<EOF
Hurray! The \`test\` job succeeded. The random value $value needed to be less than 16384 to succeed.
EOF
exit 0
fi
On failure, the message will start with "Unfortunately...". On success, the message will start with "Harray!".

Visit https://api.slack.com/incoming-webhooks to learn more about contents of Slack messages.
To upgrade your pipeline and run the test job a few times to see success and failure notifications:
fly -t bucc set-pipeline -p slack-notifications -c pipeline-dynamic-messages.yml
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
Custom Slack Message Metadata¶
Our Slack notifications above are pretty bland:

Let's spice them up with custom image and username:

Also, we can condense the on_success and on_failure sections into a shared ensure block:
- task: test-sometimes-works
...
ensure:
put: notify
params:
username: starkandwayne-ci
icon_url: https://www.starkandwayne.com/assets/images/shield-blue-50x50.png
text_file: notify_message/message
To upgrade your pipeline and run the test job a few times to see success and failure notifications:
fly -t bucc set-pipeline -p slack-notifications -c pipeline-custom-metadata.yml
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w
fly -t bucc trigger-job -j slack-notifications/test -w