blob: 4578c26b19cffb92cf0bbee6e26344843f1c0e85 [file] [log] [blame] [edit]
#!/bin/bash
# Copyright 2021 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# This script is meant to be run from Cloud Build as a substitute
# for "gcloud app deploy", as in:
#
# go-app-deploy.sh [--project=name] app.yaml
#
# It should not be run by hand and is therefore not marked executable.
#
# It customizes the usual "gcloud app deploy" in two ways.
#
# First, it deploys with --no-promote and only promotes after
# the deployed app has passed an in-prod readiness test.
#
# Second, it chooses an app version like 2021-06-02-204309-2c120970
# giving the date, time, and commit hash of the commit being deployed.
# This handles the case where multiple commits are being run through
# Cloud Build at once and would otherwise end up with timestamps in
# arbitrary order depending on the order in which Cloud Build happened
# to reach each's gcloud app deploy command. With our choice, the
# versions are ordered in git time order.
set -e
project=golang-org
case "$1" in
--project=*)
project=$(echo $1 | sed 's/--project=//')
shift
esac
yaml=app.yaml
case "$1" in
*.yaml)
yaml=$1
shift
esac
if [ $# != 0 ]; then
echo 'usage: go-app-deploy.sh [--project=name] path/to/app.yaml' >&2
exit 2
fi
version=$(git log -n1 --date='format:%Y-%m-%d-%H%M%S' --pretty='format:%cd-%h')
service=$(awk '$1=="service:" {print $2}' $yaml)
servicedot="-$service-dot"
if [ "$service" = default ]; then
servicedot=""
fi
host="$version-dot$servicedot-$project.appspot.com"
echo "### deploying to https://$host"
gcloud -q --project=$project app deploy -v $version --no-promote $yaml
curl --version
for i in 1 2 3 4 5; do
if curl -s --fail --show-error "https://$host/_readycheck"; then
echo '### site is up!'
# We used to have to worry about go-app-deploy.sh running for
# other commits simultaneously, so we checked that we weren't
# going to stomp a newer version of the web site.
# The use of locktrigger in cloudbuild.yaml should make this impossible,
# but keep checking anyway.
serving=$(gcloud app services describe --project=$project $service | grep ': 1.0')
if [ "$serving" '>' "$version" ]; then
echo "### serving version $serving is newer than our $version; not promoting"
exit 1
fi
echo '### promoting'
gcloud -q --project=$project app services set-traffic $service --splits=$version=1
exit 0
fi
echo '### not healthy'
curl "https://$host/_readycheck" # show response body
done
echo "### failed to become healthy; giving up"
exit 1