Skip to content

Instantly share code, notes, and snippets.

@jankuca
Created April 1, 2013 10:25
Show Gist options
  • Save jankuca/5284174 to your computer and use it in GitHub Desktop.
Save jankuca/5284174 to your computer and use it in GitHub Desktop.
#!/bin/sh
REPO_DIRNAME=$PWD
REPO_BASENAME=$(basename $REPO_DIRNAME)
REPO_BASENAME=${REPO_BASENAME%.git}
if [ $REPO_BASENAME = "gitolite-admin" ]; then
exit 0
fi
read OLD_REV_SHA1 NEW_REV_SHA1 REF
BRANCH=${REF##*/}
NATIVE_NODE_VERSION=$(node -v)
TARGET=/var/apps
PARTIAL_DIR_BASENAME=".$BRANCH.part"
ROLLBACK_DIR_BASENAME=".$BRANCH.rollback"
PID_FILE_BASENAME=".pids"
PORT_FILE_BASENAME=".ports"
unset GIT_DIR
out () {
echo "\033[2K$@"
}
# Enter the target base
cd /var/apps || exit 1
# Get the port number for the current project/branch
if [ ! -f $PORT_FILE_BASENAME ]; then
PORT=2101
echo "$REPO_BASENAME/$BRANCH $PORT" >> $PORT_FILE_BASENAME
else
PORT_LINE=$(grep "$REPO_BASENAME/$BRANCH " "$PORT_FILE_BASENAME")
if [ -z "$PORT_LINE" ]; then
PORT=2100
while read line; do
line_port=$(echo $line | cut -d " " -f 2)
if [ $line_port > $PORT ]; then
PORT=$line_port
fi
done < $PORT_FILE_BASENAME
PORT=$(($PORT + 1))
echo "$REPO_BASENAME/$BRANCH $PORT" >> $PORT_FILE_BASENAME
else
PORT=$(echo $PORT_LINE | cut -d " " -f 2)
fi
fi
# Create a project dir
if [ ! -d $REPO_BASENAME ]; then
mkdir $REPO_BASENAME || exit 1
fi
# Enter the project dir
cd $REPO_BASENAME || exit 1
rm_partial_dir () {
rm -rf "$TARGET/$REPO_BASENAME/$PARTIAL_DIR_BASENAME"
}
fail () {
rm_partial_dir
exit 1
}
success () {
rm_partial_dir
exit 0
}
# Check if the same branch isn't already being deployed
if [ -d $PARTIAL_DIR_BASENAME ]; then
out ""
out "\033[0;31mThe last deployment process for the branch '$BRANCH' hasn't finished yet.\033[0m"
exit 1
fi
# Clone the repo to a temporary deployment target
( git clone $REPO_DIRNAME $PARTIAL_DIR_BASENAME -b $BRANCH ) > /dev/null 2>&1 || fail
# Enter the new temporary deployment target
cd $PARTIAL_DIR_BASENAME
( git checkout $NEW_REV_SHA1 ) > /dev/null 2>&1 || fail
# Check whether there are any git sub-modules
if [ -f .gitmodules ]; then
out ""
out "\033[4;36mDetected git sub-modules:\033[0m"
{ git submodule update --init --recursive | grep "checked out"; } || fail
fi
# Check whether there is a package.json file
if [ ! -f package.json ]; then
out ""
out "\033[4;36mNo package.json file present\033[0m"
out " - Pre-installed node.js version = \033[0;32m$(node -v)\033[0m"
else
out ""
out "\033[4;36mDetected a package.json file:\033[0m"
DEPENDENCY_LINE=$(json_parse < package.json | grep "^\[\"dependencies\"\]")
if [ ! -z "$DEPENDENCY_LINE" ]; then
out " - \033[4;0mInstalling dependencies via NPM"
npm install 2> /dev/null || fail
echo ""
fi
NODE_VERSION=$(json_parse < package.json | grep "^\[\"engine\",\"node\"\]" | cut -d \t -f 2 | cut -d '"' -f 6)
if [ -z "$NODE_VERSION" ] || [ "$NODE_VERSION" = "*" ]; then
out " - No node.js version specified"
out " - Pre-installed node.js version = \033[0;32m$(node -v)\033[0m"
NODE_VERSION=$NATIVE_NODE_VERSION
else
out " - Required node.js version = \033[0;32m$NODE_VERSION\033[0m"
NODE_VERSION="v$NODE_VERSION"
if [ "$NATIVE_NODE_VERSION" != "$NODE_VERSION" ]; then
( nave install $NODE_VERSION ) > /dev/null 2>&1 || fail
fi
fi
fi
# Check whether there is a .bowerrc file
BOWER_FILE="component.json"
if [ -f ".bowerrc" ]; then
BOWER_FILE_PARSED=$(json_parse < .bowerrc | grep "^\[\"json\"\]" | cut -d '"' -f 4)
if [ ! -z "$BOWER_FILE_PARSED" ]; then
BOWER_FILE="$BOWER_FILE_PARSED"
fi
fi
if [ -f $BOWER_FILE ]; then
out ""
out "\033[4;36mDetected a Bower file:\033[0m $BOWER_FILE"
out " - \033[4;0mInstalling dependencies via Bower"
bower install || fail
fi
# Check whether a grunt file is present
if [ -f "grunt.js" ] || [ -f "grunt.coffee" ]; then
out ""
out "\033[4;36mDetected a grunt file\033[0m"
out " - \033[4;0mBuiliding via grunt.js"
grunt || fail
fi
# Replace the previous deployment target
cd ..
# Kill the app process
if [ -f "$PID_FILE_BASENAME" ]; then
killtree() {
local _pid=$1
local _sig=${2-TERM}
for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
killtree ${_child} ${_sig}
done
kill -${_sig} ${_pid}
}
OLD_PID_LINE=$(cat $PID_FILE_BASENAME | grep "^$BRANCH ")
if [ ! -z "$OLD_PID_LINE" ]; then
OLD_PID=$(echo $OLD_PID_LINE | cut -d " " -f 2)
out ""
out "Stopping previous processes: PID=$OLD_PID"
( killtree $OLD_PID ) > /dev/null 2>&1
sed -i "/^$BRANCH /d" $PID_FILE_BASENAME
fi
fi
if [ -d "$BRANCH" ]; then
if [ -d "$ROLLBACK_DIR_BASENAME" ]; then
rm -rf "$ROLLBACK_DIR_BASENAME"
fi
mv "$BRANCH" "$ROLLBACK_DIR_BASENAME"
fi
mv "$PARTIAL_DIR_BASENAME" "$BRANCH"
cd "$BRANCH" || exit 1
# Remove the .git dir
rm -rf .git
# Check whether a Procfile is present
if [ ! -f Procfile ]; then
out ""
out "\033[4;36mNo Procfile present\033[0m"
out ""
out "\033[0;32mSuccessfully deployed, no process launched\033[0m"
out ""
success
fi
out ""
out "\033[4;36mDetected Procfile\033[0m"
command -v foreman > /dev/null || {
out ""
out "\033[0;31mforeman is not installed\033[0m"
out ""
exit 1
}
# Launch the app
out " - Launching processes"
if [ -z $NODE_VERSION ] || [ $NATIVE_NODE_VERSION = $NODE_VERSION ]; then
foreman start -p $PORT > .log 2>&1 &
else
nave use $NODE_VERSION foreman start -p $PORT > .log 2>&1 &
fi
NEW_PID=$!
echo "$BRANCH $NEW_PID" >> ../$PID_FILE_BASENAME
out " PID=$NEW_PID"
out ""
out "\033[0;32mSuccessfully deployed\033[0m"
out ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment