#!/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