-
-
Save grappler/214afd6f861ece80af88 to your computer and use it in GitHub Desktop.
post-receive for Sitegound. The file encoding should UTF without BOM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Update the working tree after changes have been pushed here | |
cd .. | |
env -i git checkout composer -f | |
env -i git reset --hard | |
# Check if a composer.lock file is present | |
if [ -f composer.lock ]; then | |
# Install or update packages specified in the lock file | |
/usr/local/php56/bin/php-cli ~/composer.phar install --no-dev --prefer-dist --optimize-autoloader | |
fi | |
cd .git | |
# Slack (slack.com) notification post-receive hook. | |
# | |
# Based on: https://github.com/joemiller/git-hooks Campfire notification post-receive hook. Author: Joe Miller | |
# (http://joemiller.me) | |
# | |
# Based on post-receive.irc by Mikael Fridh <[email protected]> https://gist.github.com/1821358 | |
# | |
# Settings needed: | |
# git config hooks.slack.webhook-url "https://hooks.slack.com/services/..." | |
# git config hooks.slack.channel "general" | |
# | |
# - The Slack webhook URL can be found in: | |
# https://my.slack.com/services/new/incoming-webhook | |
# | |
function help() { | |
echo "Required config settings:" | |
echo " git config hooks.slack.webhook-url 'https://hooks.slack.com/services/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'" | |
echo " git config hooks.slack.channel 'general'" | |
echo " git config hooks.slack.show-only-last-commit true #optional" | |
echo " git config hooks.slack.show-full-commit true #optional" | |
echo " git config hooks.slack.username 'prod-server' #optional" | |
echo " git config hooks.slack.icon-url 'http://imgur/icon.png' #optional" | |
echo " git config hooks.slack.icon-emoji ':twisted_rightwards_arrows:' #optional" | |
echo " git config hooks.slack.repo-nice-name 'Production Server' #optional" | |
echo " git config hooks.slack.repos-root '/path/to/repos' #optional" | |
echo " git config hooks.slack.changeset-url-pattern 'http://yourserver/%repo_path%/changeset/%rev_hash%' #optional" | |
echo " git config hooks.slack.compare-url-pattern 'http://yourserver/%repo_path%/changeset/%old_rev_hash%..%new_rev_hash%' #optional" | |
echo " git config hooks.slack.branch-regexp 'regexp' #optional" | |
} | |
function replace_variables() { | |
sed "s|%repo_path%|$repopath|g;s|%old_rev_hash%|$oldrev|g;s|%new_rev_hash%|$newrev|g;s|%rev_hash%|$newrev|g;s|%repo_prefix%|$repoprefix|g" | |
} | |
function notify() { | |
oldrev=$(git rev-parse $1) | |
newrev=$(git rev-parse $2) | |
refname="$3" | |
# --- Interpret | |
# 0000->1234 (create) | |
# 1234->2345 (update) | |
# 2345->0000 (delete) | |
change_type="update" | |
# --- Get the revision types | |
newrev_type=$(git cat-file -t $newrev 2> /dev/null) | |
oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null) | |
case "$change_type" in | |
create|update) | |
rev="$newrev" | |
rev_type="$newrev_type" | |
;; | |
delete) | |
rev="$oldrev" | |
rev_type="$oldrev_type" | |
;; | |
esac | |
# The revision type tells us what type the commit is, combined with | |
# the location of the ref we can decide between | |
# - working branch | |
# - tracking branch | |
# - unannoted tag | |
# - annotated tag | |
case "$refname","$rev_type" in | |
refs/tags/*,commit) | |
# un-annotated tag | |
refname_type="tag" | |
short_refname=${refname##refs/tags/} | |
;; | |
refs/tags/*,tag) | |
# annotated tag | |
refname_type="annotated tag" | |
short_refname=${refname##refs/tags/} | |
# change recipients | |
if [ -n "$announcerecipients" ]; then | |
recipients="$announcerecipients" | |
fi | |
;; | |
refs/heads/*,commit) | |
# branch | |
refname_type="branch" | |
short_refname=${refname##refs/heads/} | |
;; | |
refs/remotes/*,commit) | |
# tracking branch | |
refname_type="tracking branch" | |
short_refname=${refname##refs/remotes/} | |
echo >&2 "*** Push-update of tracking branch, $refname" | |
echo >&2 "*** - no notification generated." | |
return 0 | |
;; | |
*) | |
# Anything else (is there anything else?) | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - no notification generated" | |
return 0 | |
;; | |
esac | |
branchregexp=$(git config --get hooks.slack.branch-regexp) | |
if [ -n "$branchregexp" ]; then | |
if [[ ! $short_refname =~ $branchregexp ]]; then | |
exit 0; | |
fi | |
fi | |
#channels=$(git config hooks.irc.channel) | |
# plural suffix, default "", changed to "s" if commits > 1 | |
s="" | |
# Repo name, either Gitolite or normal repo. | |
if [ -n "$GL_REPO" ]; then | |
# it's a gitolite repo | |
repodir=$(basename $(pwd)) | |
repo=$GL_REPO | |
else | |
repodir=$(basename $(pwd)) | |
if [ "$repodir" == ".git" ]; then | |
repodir=$(dirname $PWD) | |
repodir=$(basename $repodir) | |
fi | |
repo=${repodir%.git} | |
fi | |
repoprefix=$(git config hooks.slack.repo-nice-name || git config hooks.irc.prefix || git config hooks.emailprefix || echo "$repo") | |
onlylast=$(git config --get hooks.slack.show-only-last-commit) | |
onlylast=$onlylast && [ -n "$onlylast" ] | |
fullcommit=$(git config --get hooks.slack.show-full-commit) | |
# Get the user information | |
# If $GL_USER is set we're running under gitolite. | |
if [ -n "$GL_USER" ]; then | |
user=$GL_USER | |
else | |
user=$USER | |
fi | |
case ${change_type} in | |
"create") | |
header="New ${refname_type} *${short_refname}* has been created in ${repoprefix}" | |
single_commit_suffix="commit" | |
;; | |
"delete") | |
header="$(tr '[:lower:]' '[:upper:]' <<< ${refname_type:0:1})${refname_type:1} *$short_refname* has been deleted from ${repoprefix}" | |
single_commit_suffix="commit" | |
;; | |
"update") | |
num=$(git log --pretty=oneline ${1}..${2}|wc -l|tr -d ' ') | |
branch=${3/refs\/heads\//} | |
if [ ${num} -gt 1 ]; then | |
header="${num} new commits *pushed* to *${short_refname}* in ${repoprefix}" | |
single_commit_suffix="one" | |
s="s" | |
else | |
header="A new commit has been *pushed* to *${short_refname}* in ${repoprefix}" | |
single_commit_suffix="one" | |
fi | |
;; | |
*) | |
# most weird ... this should never happen | |
echo >&2 "*** Unknown type of update to $refname ($rev_type)" | |
echo >&2 "*** - notifications will probably screw up." | |
;; | |
esac | |
if $onlylast && [[ "${change_type}" != "delete" ]]; then | |
header="$header, showing last $single_commit_suffix:" | |
fi | |
if [[ "${change_type}" != "delete" && "${refname_type}" == "branch" ]]; then | |
changeseturlpattern=$(git config --get hooks.slack.changeset-url-pattern) | |
compareurlpattern=$(git config --get hooks.slack.compare-url-pattern) | |
reporoot=$(git config --get hooks.slack.repos-root) | |
urlformat= | |
if [ -n "$changeseturlpattern" -a -n "$reporoot" ]; then | |
if [[ $PWD == ${reporoot}* ]]; then | |
repopath=$PWD | |
base=$(basename $PWD) | |
if [ "$base" == ".git" ]; then | |
repopath=$(dirname $repopath) | |
fi | |
idx=$(echo $reporoot | wc -c | tr -d ' ') | |
repopath=$(echo $repopath | cut -c$idx-) | |
urlformat=$(echo $changeseturlpattern | replace_variables) | |
if [ -n "$compareurlpattern" ]; then | |
comparelink=$(echo $compareurlpattern | replace_variables) | |
header=$(echo $header | sed -e "s|\([a-zA-Z0-9]\{1,\} new commit[s]\{0,1\}\)|\<$comparelink\|\\1\>|") | |
fi | |
else | |
echo >&2 "$PWD is not in $reporoot. Not creating hyperlinks." | |
fi | |
fi | |
formattedurl="" | |
if [ -n "$urlformat" ]; then | |
formattedurl="<${urlformat}|%h> " | |
fi | |
nl="\\\\n" | |
if [[ "${change_type}" == "update" ]]; then | |
start="${1}" | |
else | |
start="HEAD" | |
fi | |
end="${2}" | |
# merge `git log` output with $header | |
if $onlylast; then | |
countarg="-n 1" | |
else | |
countarg="" | |
fi | |
# show the full commit message | |
if [ "$fullcommit" == "true" ]; then | |
commitformat="%s%n%n%b" | |
else | |
commitformat="%s" | |
fi | |
# Process the log and escape double quotes; assuming for now that committer names don't have five semicolons in them | |
log_out=$( git log --pretty=format:"${formattedurl}${commitformat} - %cN" $countarg ${start}..${end} \ | |
| sed ':a;N;$!ba;s/\n/\n/g' \ | |
| sed -e 's/\\/\\\\/g' \ | |
| sed -e 's/"/\\"/g' \ | |
| sed -e 's/\(.*\)\(.*\)/{"title":"","value":"\1","short":false},/' ) | |
fields=${log_out%?} | |
attachments="[{ \"fallback\" : \"${header}\", \"color\" : \"good\", \"fields\" : [${fields}]}]" | |
fi | |
if [ -n "${attachments}" ] && [[ "${attachments}" != "" ]]; then | |
msg=$(echo -e "\"text\":\"${header}\", \"attachments\" : $attachments") | |
else | |
msg=$(echo -e "\"text\":\"${header}\"") | |
fi | |
# slack API uses \n substitution for newlines | |
# msg=$(echo "${msg}" | perl -p -e 's/\+/+/mg') | |
webhook_url=$(git config --get hooks.slack.webhook-url) | |
channel=$(git config --get hooks.slack.channel) | |
username=$(git config --get hooks.slack.username) | |
iconurl=$(git config --get hooks.slack.icon-url) | |
iconemoji=$(git config --get hooks.slack.icon-emoji) | |
if [ -z "$webhook_url" ]; then | |
echo "ERROR: config settings not found" | |
help | |
exit 1 | |
fi | |
payload="{${msg}" | |
if [ -n "$channel" ]; then | |
payload="$payload, \"channel\": \"$channel\"" | |
fi | |
if [ -n "$username" ]; then | |
payload="$payload, \"username\": \"$username\"" | |
fi | |
if [ -n "$iconurl" ]; then | |
payload="$payload, \"icon_url\": \"$iconurl\"" | |
elif [ -n "$iconemoji" ]; then | |
payload="$payload, \"icon_emoji\": \"$iconemoji\"" | |
fi | |
payload="$payload}" | |
if [ -n "$DEBUG" ]; then | |
echo "POST $webhook_url" | |
echo "payload=$payload" | |
return | |
fi | |
curl -s \ | |
-d "payload=$payload" \ | |
"$webhook_url" \ | |
>/dev/null | |
} | |
# MAIN PROGRAM | |
# Read all refs from stdin, notify slack for each | |
while read line; do | |
set -- $line | |
notify $* | |
RET=$? | |
done | |
exit $RET |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment