Last active
March 4, 2020 22:20
-
-
Save ninapavlich/adbf95b2ea2437e82670cd0e8e8d083d to your computer and use it in GitHub Desktop.
Bash script that will check a directory for a new commit in a remote repository, and deploy if detects an update
This file contains 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 | |
# This script will watch a given directory with a .git checkout and execute a deployment if it detects an update. | |
# You can set this up with CRON so that deployments happen automatically. | |
# | |
# Example CRON usage: | |
# crontab -e | |
# */5 * * * * bash /path/to/scripts/deploy.sh | |
# | |
# Example manual usage: | |
# bash /path/to/scripts/deploy.sh force | |
# | |
# ----------------------------------- | |
# PARSE ARGUMENTS | |
# ----------------------------------- | |
GIT_DIR="/srv/project-name/src/" | |
SLACK_WEBHOOK='https://hooks.slack.com/services/XXXXXXX/XXXXXXX/XXXXXXXXXXXXXX' | |
REPO_URL_ROOT='https://bitbucket.org/XXXXXXX/XXXXXXXXXXXXXX/commits/' | |
TEST_URL='https://XXXXXXXXXXXXXX/api/' | |
TEST_STATUS_CODE=200 | |
FORCE_RAW=$1 | |
FORCE=false | |
if [ "$FORCE_RAW" = "force" ]; then | |
FORCE=true | |
fi | |
SECONDS=0 | |
# ----------------------------------- | |
# Check Current Git Status | |
# ----------------------------------- | |
echo "Fetching... (Force Update? $FORCE)" | |
GIT_FETCH_OUTPUT=$( (git --git-dir=$GIT_DIR.git --work-tree=$GIT_DIR fetch) 2>&1) | |
echo "$GIT_FETCH_OUTPUT" | |
GIT_LOCAL_OUTPUT=$( (git --git-dir=$GIT_DIR.git --work-tree=$GIT_DIR rev-parse @{u}) 2>&1) | |
GIT_REMOTE_OUTPUT=$( (git --git-dir=$GIT_DIR.git --work-tree=$GIT_DIR rev-parse HEAD) 2>&1) | |
echo "Local is at $GIT_LOCAL_OUTPUT ... Remote is at $GIT_REMOTE_OUTPUT" | |
if [ $GIT_LOCAL_OUTPUT = $GIT_REMOTE_OUTPUT ] && [ $FORCE = false ]; then | |
echo "Up-to-date" | |
else | |
# ----------------------------------- | |
# Notify that deployment has started | |
# ----------------------------------- | |
SECONDS=0 | |
/usr/bin/curl \ | |
-X PUT \ | |
-s \ | |
--data-urlencode "payload={ \ | |
\"pretext\": \"New deployment started for $GIT_DIR\", \ | |
\"text\": \"Local is at $GIT_LOCAL_OUTPUT ... Remote is at $GIT_REMOTE_OUTPUT\" \ | |
}" \ | |
$SLACK_WEBHOOK | |
# ----------------------------------- | |
# Execute deployment | |
# ----------------------------------- | |
GIT_CHECKOUT_OUTPUT=$( (git --git-dir=$GIT_DIR.git --work-tree=$GIT_DIR checkout master) 2>&1) | |
GIT_RESET_OUTPUT=$( (git --git-dir=$GIT_DIR.git --work-tree=$GIT_DIR reset --hard origin/master) 2>&1) | |
echo "$GIT_CHECKOUT_OUTPUT" | |
echo "$GIT_RESET_OUTPUT" | |
# - Manage virtual environment | |
VIRTUALENV_OUTPUT=$( ($GIT_DIR/venv/bin/pip install -r $GIT_DIR/requirements.txt) 2>&1) | |
echo "$VIRTUALENV_OUTPUT" | |
# - Update database | |
MIGRATED_OUTPUT=$( ($GIT_DIR/venv/bin/python $GIT_DIR/manage.py migrate) 2>&1) | |
echo "$MIGRATED_OUTPUT" | |
# - Collect static | |
STATIC_COLLECTED_OUTPUT=$( ($GIT_DIR/venv/bin/python $GIT_DIR/manage.py collectstatic --noinput) 2>&1) | |
echo "$STATIC_COLLECTED_OUTPUT" | |
# - Restart UWSGI app | |
RESTARTED_UWSGI_OUTPUT=$( (systemctl restart emperor.uwsgi) 2>&1) | |
echo "$RESTARTED_UWSGI_OUTPUT" | |
# - Restart NGINX | |
RESTARTED_NGINX_OUTPUT=$( (systemctl restart nginx) 2>&1) | |
echo "$RESTARTED_NGINX_OUTPUT" | |
# ----------------------------------- | |
# Verify Success by hitting testing endpoint | |
# ----------------------------------- | |
TEST_STATUS_CODE_OUTPUT=$(curl -s -o /dev/null -w '%{http_code}' $TEST_URL) | |
echo "GET $TEST_URL : $TEST_STATUS_CODE_OUTPUT" | |
if [ $TEST_STATUS_CODE_OUTPUT -eq $TEST_STATUS_CODE ]; then | |
MESSAGE_COLOR="good" | |
else | |
MESSAGE_COLOR="danger" | |
fi | |
# ----------------------------------- | |
# Send completion message | |
# ----------------------------------- | |
duration=$SECONDS | |
VIEW_COMMIT_URL="$REPO_URL_ROOT$GIT_REMOTE_OUTPUT" | |
/usr/bin/curl \ | |
-X PUT \ | |
-s \ | |
--data-urlencode "payload={ \ | |
\"attachments\": [ \ | |
{ \ | |
\"fallback\": \"Deployment complete for $GIT_DIR to $GIT_REMOTE_OUTPUT after $duration seconds.\", \ | |
\"color\": \"$MESSAGE_COLOR\",\ | |
\"title\": \"Deployment complete for $GIT_DIR\", \ | |
\"text\": \"Deployment updated to $GIT_REMOTE_OUTPUT after $duration seconds.\", \ | |
\"fields\": [ \ | |
{ \ | |
\"title\": \"Git Update\", \ | |
\"value\": \"${GIT_FETCH_OUTPUT//\"/\\\"}\n\n${GIT_CHECKOUT_OUTPUT//\"/\\\"}\n\n${GIT_RESET_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Managed Virtual Environment\", \ | |
\"value\": \"${VIRTUALENV_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Migrated Databases\", \ | |
\"value\": \"${MIGRATED_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Collected Static Files\", \ | |
\"value\": \"${STATIC_COLLECTED_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Restarted UWSGI\", \ | |
\"value\": \"${RESTARTED_UWSGI_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Restarted NGINX\", \ | |
\"value\": \"${RESTARTED_NGINX_OUTPUT//\"/\\\"}\" | |
}, \ | |
{ \ | |
\"title\": \"Test Deployment\", \ | |
\"value\": \"$TEST_URL returned $TEST_STATUS_CODE_OUTPUT\" | |
} \ | |
], \ | |
\"actions\": [\ | |
{\ | |
\"type\": \"button\",\ | |
\"text\": \"View Commit\",\ | |
\"url\": \"$VIEW_COMMIT_URL\"\ | |
},\ | |
{\ | |
\"type\": \"button\",\ | |
\"text\": \"View Site\",\ | |
\"url\": \"$TEST_URL\"\ | |
}\ | |
]\ | |
} \ | |
]\ | |
}" \ | |
$SLACK_WEBHOOK | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment