3 # Slack (slack.com) notification post-receive hook.
5 # Based on: https://github.com/joemiller/git-hooks Campfire notification post-receive hook. Author: Joe Miller
6 # (http://joemiller.me)
8 # Based on post-receive.irc by Mikael Fridh <frimik@gmail.com> https://gist.github.com/1821358
12 echo "Required config settings:"
13 echo " git config hooks.slack.webhook-url 'https://hooks.slack.com/services/...'"
14 echo " git config hooks.slack.channel 'general'"
15 echo " git config hooks.slack.show-only-last-commit 'true' #optional"
16 echo " git config hooks.slack.username 'git' #optional"
17 echo " git config hooks.slack.repo-nice-name 'MyRepo' #optional"
20 function notify_slack() {
21 oldrev=$(git rev-parse $1)
22 newrev=$(git rev-parse $2)
29 if expr "$oldrev" : '0*$' >/dev/null
33 if expr "$newrev" : '0*$' >/dev/null
41 # --- Get the revision types
42 newrev_type=$(git cat-file -t $newrev 2> /dev/null)
43 oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null)
44 case "$change_type" in
47 rev_type="$newrev_type"
51 rev_type="$oldrev_type"
55 # The revision type tells us what type the commit is, combined with
56 # the location of the ref we can decide between
61 case "$refname","$rev_type" in
65 short_refname=${refname##refs/tags/}
69 refname_type="annotated tag"
70 short_refname=${refname##refs/tags/}
72 if [ -n "$announcerecipients" ]; then
73 recipients="$announcerecipients"
79 short_refname=${refname##refs/heads/}
81 refs/remotes/*,commit)
83 refname_type="tracking branch"
84 short_refname=${refname##refs/remotes/}
85 echo >&2 "*** Push-update of tracking branch, $refname"
86 echo >&2 "*** - no notification generated."
90 # Anything else (is there anything else?)
91 echo >&2 "*** Unknown type of update to $refname ($rev_type)"
92 echo >&2 "*** - no notification generated"
96 # plural suffix, default "", changed to "s" if commits > 1
99 # Repo name, either Gitolite or normal repo.
100 if [ -n "$GL_REPO" ]; then
101 # it's a gitolite repo
102 repodir=$(basename `pwd`)
105 repodir=$(basename `pwd`)
106 if [ "$repodir" == ".git" ]; then
107 repodir=`dirname $PWD`
108 repodir=`basename $repodir`
113 repoprefix=$(git config hooks.slack.repo-nice-name || git config hooks.irc.prefix || git config hooks.emailprefix || echo "$repo")
114 onlylast=`git config --get hooks.slack.show-only-last-commit`
115 onlylast=$onlylast && [ -n "$onlylast" ]
117 # Get the user information
118 # If $GL_USER is set we're running under gitolite.
119 if [ -n "$GL_USER" ]; then
125 case ${change_type} in
127 header="New ${refname_type} *${short_refname}* has been created in ${repoprefix}"
128 single_commit_suffix="commit"
131 header="$(tr '[:lower:]' '[:upper:]' <<< ${refname_type:0:1})${refname_type:1} *$short_refname* has been deleted from ${repoprefix}"
132 single_commit_suffix="commit"
135 num=$(git log --pretty=oneline ${1}..${2}|wc -l|tr -d ' ')
136 branch=${3/refs\/heads\//}
138 if [ ${num} -gt 1 ]; then
139 header="${num} new commits *pushed* to *${short_refname}* in ${repoprefix}"
140 single_commit_suffix="one"
143 header="A new commit has been *pushed* to *${short_refname}* in ${repoprefix}"
144 single_commit_suffix="one"
149 # most weird ... this should never happen
150 echo >&2 "*** Unknown type of update to $refname ($rev_type)"
151 echo >&2 "*** - notifications will probably screw up."
154 if $onlylast && [[ "${change_type}" != "delete" ]]; then
155 header="$header, showing last $single_commit_suffix:"
159 if [[ "${change_type}" != "delete" && "${refname_type}" == "branch" ]]; then
160 reporoot=`git config --get hooks.slack.repos-root`
165 if [ -n "$urlformat" ]; then
166 formattedurl="<${urlformat}|%h> "
172 if [[ "${change_type}" == "update" ]]; then
180 # merge `git log` output with $header
187 # Process the log and escape double quotes; assuming for now that committer names don't have five semicolons in them
188 log_out=$( git log --pretty=format:"%cN;;;;;${formattedurl}%s" $countarg ${start}..${end} \
189 | sed -e 's/\\/\\\\/g' \
190 | sed -e 's/"/\\"/g' \
191 | sed -e 's/\(.*\);;;;;\(.*\)/{"title":"\1","value":"\2","short":false},/' )
195 attachments="[{ \"fallback\" : \"${header}\", \"color\" : \"good\", \"fields\" : [${fields}]}]"
198 if [ -n "${attachments}" ] && [[ "${attachments}" != "" ]]; then
199 msg=$(echo -e "\"text\":\"${header}\", \"attachments\" : $attachments")
201 msg=$(echo -e "\"text\":\"${header}\"")
204 # slack API uses \n substitution for newlines
205 # msg=$(echo "${msg}" | perl -p -e 's/\+/+/mg')
207 webhook_url=$(git config --get hooks.slack.webhook-url)
208 channel=$(git config --get hooks.slack.channel)
209 username=$(git config --get hooks.slack.username)
211 if [ -z "$webhook_url" ] || [ -z "$channel" ]; then
212 echo "ERROR: config settings not found"
217 payload="{${msg}, \"channel\": \"#$channel\""
219 if [ -n "$username" ]; then
220 payload="$payload, \"username\": \"$username\""
225 if [ -n "$DEBUG" ]; then
226 echo "POST $webhook_url"
227 echo "payload=$payload"
232 -d "payload=$payload" \
237 webhook_url=$(git config --get hooks.slack.webhook-url)
241 if [ -n "$webhook_url" ]; then