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