Combining Git Hooks & Slack’s Incoming Web Hooks
TL;DR — 🚀. Triggering Slack’s Incoming Web Hooks with custom scripts which are automatically invoked by Git Hooks.
Arsenal
- Git
- Node JS
- Slack’s Incoming Webhooks Integration
- Husky (npm module for managing git hooks )
Goal
Publishing commit messages to Slack channel every time a team member commits.
Flow
- Developer commits changes.
- post-commit hook is invoked and will execute the node script.
- Node script obtains the details of the head commit with a bash script, and applies some styling(optional) and triggers web hook with commit message details.
Long Story
- Add Slack’s Incoming Webhooks application to any of your Slack Channel.
You will get a webhook url for your channel. There is a sample request you will find at the end of the integration which looks like the one below.
curl -X POST --data-urlencode "payload={\"channel\": \"#commits-ci\", \"username\": \"webhookbot\", \"text\": \"This is posted to #commits-ci and comes from a bot named webhookbot.\", \"icon_emoji\": \":ghost:\"}" https://hooks.slack.com/services/SOME/KEY
If you compare the sample request and preview below, you can see that username, text & icon can be overridden.
- Install Husky under dev-dependencies
Husky is an easy way to manage git hooks. Hooks are initially located under .git/hooks inside repo’s root directory. You need to update the directory to use hooks bla bla, lot of unnecessary effort. Husky saves that effort Allows you to manage your hooks inside package.json and share with team members. You can read more about git-hooks from here.
- Following command displays details of the latest commit in the repository. (author, commit id, commit message, etc.)
- Create a bash script named “curlwebhook”. Place your webhook sample request. Later you will pass arguments obtained from git log -n 1 HEAD command to this curlwebhook script.
- Create a node script named “invoke-slack” to execute the bash script.
Note: Do not forget to run “chmod +x <script_name>” for each script you create. Otherwise they will not be executable.
The reason behind why we are using an additional script is, it is way more easier to manipulate the commit message, icon or the name with Node js. For example you can parse the commit author and update the username section in the payload and the author will be displayed as username instead of webhookbot in the slack channel.
At this point, there is a bash script and a node script. According to Husky docs, following image shows the usage of post-commit hook. ( keep reading, scripts are included)
This means, every time someone commits changes, post-commit hook will execute invoke-slack script.
Long Story Short
Create Slack’s incoming webhook for your desired slack channel.
Get Husky module & Add post-commit hook inside your package.json.
Create following scripts.
invoke-slack.jsvar exec = require('child_process').exec, child;
var shellscript = exec('git log -n 1 HEAD');
shellscript.stdout.on('data', (data) => {
// data is commit details
// this is where you can change slack message details
exec('sh curlwebhook.sh ' + data);
});
shellscript.stderr.on('data', (data) => {
console.error(data);
});
curlwebhook.shcurl -X POST --data-urlencode "payload={\"channel\": \"#commits-ci\", \"username\": \"webhookbot\", \"text\": \" $1 \", \"icon_emoji\": \":ghost:\"}" https://hooks.slack.com/services/SOME/KEY
— note that $1 inside curlwebhook.sh is the “data” argument we passed.
You are done.
Use Cases
Well there are integration tools which are automatically doing this, but this might be useful
- if you are into customizing these kinds of integrations,
- if you are working with private repositories with restricted internet access.
Thanks For Reading
My name is Hüseyin. If you have any questions, feedbacks or suggestions, I would like to hear .