Created
August 2, 2019 15:02
-
-
Save CGA1123/41a8901b82a14c9f2a77d8f9663d7d19 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env bash | |
set -eu | |
# Finds the heroku slug id from the compile apps latests releases | |
# via the commit SHA | |
function heroku_slug () { | |
heroku releases --app ${1} --json | \ | |
jq -rc --arg commit "${2}" \ | |
'.[] | |
| select(.description | test("Deploy .*")) | |
| (.description | gsub("Deploy "; "")) as $commit_hash | |
| select($commit_hash | test($commit)) | |
| .slug.id' | |
} | |
# Copies a slug to an application | |
function promote_slug () { | |
local app=${1} | |
local slug=${2} | |
local commit=${3} | |
heroku api POST "/apps/${app}/releases" --body '{"slug": "'"${slug}"'", "description": "Deploy '"${commit}"'"}' | tee release.json | |
local version=$(jq '.version' release.json) | |
sleep 5 | |
heroku releases:output ${version} -a ${app} | |
sleep 5 | |
heroku releases:info ${version} --app $app --json | |
heroku releases:info ${version} --app $app --json | grep status | grep -q succeeded | |
} | |
FIVE_MINUTES=$((60 * 5)) | |
COMPILE_APP=${1} | |
APP=${2} | |
CURRENT_COMMIT=${CIRCLE_SHA1} | |
HEAD_COMMIT=$(git rev-parse origin/master) | |
COMMIT_BEFORE_HEAD=$(git rev-parse origin/master~1) | |
CURRENT_TIME=$(date +%s) | |
COMMIT_TIME=$(git show --format='%ct' origin/master | head -n1) | |
SECONDS_SINCE_COMMIT=$(expr $CURRENT_TIME - $COMMIT_TIME) | |
CURRENT_COMMIT_SHORT=${CURRENT_COMMIT:0:8} | |
echo "-----> Trying to find precompile slug for ${CURRENT_COMMIT} on ${COMPILE_APP}" | |
SLUG=$(heroku_slug ${COMPILE_APP} ${CURRENT_COMMIT_SHORT}) | |
# If we found a slug id try and promote it to production, fallback to | |
# old-school deploys if we can't find one | |
if [ ! -z "${SLUG}" ] ; then | |
echo "-----> Trying to promote ${SLUG} to ${APP}..." | |
if [ "${HEAD_COMMIT}" == "${CURRENT_COMMIT}" ] ; then | |
echo " origin/master is at ${CURRENT_COMMIT}." | |
echo " Promoting slug..." | |
promote_slug ${APP} ${SLUG} ${CURRENT_COMMIT_SHORT} | |
elif [ "${COMMIT_BEFORE_HEAD}" == "${CURRENT_COMMIT}" ] && [ "${SECONDS_SINCE_COMMIT}" -lt "$FIVE_MINUTES" ] ; then | |
echo " Next commit on master (${HEAD_COMMIT}) merged less than 5 minutes ago - safe to deploy." | |
echo " Promoting slug..." | |
promote_slug ${APP} ${SLUG} ${CURRENT_COMMIT_SHORT} | |
else | |
echo " Either the next commit on master (${HEAD_COMMIT}) merged more than 5 minutes ago" | |
echo " or there are multiple commits on master ahead." | |
echo " This commit will deploy with the next run." | |
fi | |
else | |
echo "-----> Couldn't find precompiled slug - falling back" | |
echo " Could not find a precompiled slug on ${APP}" | |
echo " Looked for ${CURRENT_COMMIT}" | |
echo " Falling back to regular deploys..." | |
deploy ${APP} | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment