Skip to content

Instantly share code, notes, and snippets.

@grappler
Last active October 31, 2015 23:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grappler/214afd6f861ece80af88 to your computer and use it in GitHub Desktop.
Save grappler/214afd6f861ece80af88 to your computer and use it in GitHub Desktop.
post-receive for Sitegound. The file encoding should UTF without BOM
#!/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 <frimik@gmail.com> 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/\+/&#43;/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