Skip to content

Instantly share code, notes, and snippets.

@JonRowe
Last active August 29, 2015 13:57
Show Gist options
  • Save JonRowe/9821939 to your computer and use it in GitHub Desktop.
Save JonRowe/9821939 to your computer and use it in GitHub Desktop.
A git pre-receive hook for Ruby deploying.
#!/bin/bash
# Let's deploy...
echo "Deploying..."
echo "Deploying as: `whoami`"
# turn on failing script on any command fail
set -e
set -o pipefail
# The script has been called as a hook; chdir to the working copy
# This fixes bundler from throwing a wobbly about fetching git dependencies
if [ "$GIT_DIR" = "." ]; then
cd ..
unset GIT_DIR
fi
# references passed to hook
# stdin contains `old_rev new_rev ref` on lines for each ref, this ruby code finds the new rev for head or exits
NEW_REV="$(ruby -e 'puts $stdin.read.split("\n").find { |line| line =~ /master$/ }.split(" ")[1] || exit(1)' <&0)"
if [ "$NEW_REV" = "" ]
then
echo "Couldn't find revision to update!"
exit 1
fi
# Set my directories
APP='my_app'
REPO_PATH="/srv/repo/$APP.git"
APP_PATH="/srv/app/$APP"
RELEASE_PATH="$APP_PATH/releases/$(date +%Y_%m_%d_%H%M%S)"
SHARED_PATH="$APP_PATH/shared"
function exit_if_failed {
if [ $? -ne 0 ]
then
rm -rf $RELEASE_PATH
for var in "$@"
do
echo "$var"
done
exit 1
fi
}
echo "Updating code"
mkdir -p $RELEASE_PATH
git --work-tree=$RELEASE_PATH --git-dir=$REPO_PATH checkout -f $NEW_REV > /dev/null
exit_if_failed "Git checkout failed"
mkdir -p $SHARED_PATH/tmp
ln -s $SHARED_PATH/tmp $RELEASE_PATH/tmp
ln -s $SHARED_PATH/.env $RELEASE_PATH/.env
echo "Running setup"
# bundle gems
mkdir -p $SHARED_PATH
mkdir -p $SHARED_PATH/vendor/cache
cd $RELEASE_PATH && bundle install --without development,test --deployment --path $SHARED_PATH/vendor/cache
exit_if_failed "Bundle failed"
# turn on failing script on any command fail
set +e
set +o pipefail
# setup foreman
cd $RELEASE_PATH && sudo /usr/local/bin/bundle exec foreman export upstart /etc/init \
--template $RELEASE_PATH/config/foreman.erb \
--log $SHARED_PATH/log \
--run /srv/sockets \
--app $APP \
--user app \
--env $SHARED_PATH/.env
--procfile $RELEASE_PATH/P
exit_if_failed "Couldn't export foreman upstart scripts" "Have you added a NOPASSWD entry for /usr/local/bin/bundle exec foreman export*"
echo "Restarting"
ln -sf $RELEASE_PATH $APP_PATH/releases/current
sudo /sbin/restart $APP
exit_if_failed "Couldn't restart $APP" "Have you added a NOPASSWD entry for /sbin/restart *?"
# find all releases bar the last 5 (tail -n +6 means start at line 6) and removes them
find $APP_PATH/releases -maxdepth 1 -type d ! -path $APP_PATH/releases | sort -r | tail -n +6 | xargs -n 1 rm -rf
echo "Done!"
echo "Deployed to $RELEASE_PATH"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment