Posting a Slack message from Travis CI
As part of my ongoing mission to rewrite our CI system, the final step is letting QA know that a new build is available. They can’t test it if they don’t know it’s there!
We’ll be using our CI’s bash script for this, the start of this article describes how to create one if you haven’t already.
Not interested in the full tutorial? Here’s the final Gist, and here’s what we’ll end up with:
Formatting a Slack message
The first step is telling Slack how our message should look. Slack has a really nice online visualiser for messages using their “Block Kit” syntax. Using one of their templates, it’s very easy to quickly build a message with example data and preview it on desktop or mobile.
Here is the template I created, it might be helpful as a starting point for your own.
In my messages, I display metadata QA / other devs might find useful: branch name, build number, commit message, commit hash, debuggable state.
I’ve also included 4 buttons. One for the Google Play Internal App Sharing link (guide to setting it up), one for help installing, one for the Travis build, and one for the commit’s link on GitHub.
Getting a Slack webhook
Slack has an official guide to creating a webhook URL, but it is much more complicated than necessary. The essential steps are:
- Create a new app.
- Add the “Incoming WebHooks” app to your Slack workspace by clicking “Add to Slack” from the app management page (this will be “Request Configuration” if you’re not an admin).
- Select which room the messages should go to (picture). It might be helpful setting this to a private message with yourself whilst testing!
- Once added, scroll down to “Integration settings” (picture), and customise the name and avatar (emoji or uploaded image).
- Copy the “Webhook URL”.
- Save settings.
Posting messages to Slack
From your existing bash script (guide to setting it up if you need to), we just need to do a simple POST to our webhook. This assumes you’ve defined your Slack message’s JSON ($DATA
) & webhook URL ($WEBHOOK_URL
) already:
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
--header "Content-type: application/json" \
--request POST \
--data "$DATA" \
"$WEBHOOK_URL")
HTTP_BODY=$(echo ${HTTP_RESPONSE} | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS=$(echo ${HTTP_RESPONSE} | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
if [[ ${HTTP_STATUS} != 200 ]]; then
echo -e "Sending Slack notification failed.\nStatus: $HTTP_STATUS\nBody: $HTTP_BODY\nExiting."
exit 1
fi
This short script will send the custom message to Slack, and display any errors if they occur.
Putting it all together
You should now have everything you need to create a function that you can invoke in your scripts.
We’ll put a few placeholders (e.g. $BRANCH
) in our message, and replace them when the script runs. I’m defining all of my environment variables at the start, so the script can be easily migrated to another CI if necessary, but some variables still need to be passed to the function.
Here’s the full Gist, make sure you define / pass all your variables!
Further improvements
It might be useful to tag user(s) in your message. This can be done by adding their user ID somewhere in your message in this format: <@theiruserid>
, which can be found by:
- Clicking the user whose ID you want to find.
- Clicking “View full profile”
- Pressing the 3 dot icon, you can then copy their member ID:
Another improvement would be stopping the “warning” icon that appears next to a clicked button. This appears because Slack is trying to transfer (empty) data to the arbitrary URL we’re using, which isn’t accepting it.
Unfortunately there doesn’t seem to be an easy fix, since we’re using simple webhooks and not anything more advanced.