blog, go.dev, tour: add cloudbuild deployment configs

These deployment configs are meant to be run from Cloud Build.
They deploy a new version of the site on each commit,
using the commit date and hash to derive the app version.
If a commit is submitted with a Website-Publish+1 vote,
then the new version is promoted to be the live version of the site.
Otherwise the new version is left unpromoted, where it can be
manually inspected and potentially manually promoted,
or simply ignored and eventually automatically deleted.

golang.org will work this way too, after we move it off of Flex.

Change-Id: Iaddb3596276d5cfbf18aa67f210fcd33f323d9d5
Reviewed-on: https://go-review.googlesource.com/c/website/+/324511
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Website-Publish: Russ Cox <rsc@golang.org>
diff --git a/blog/README.md b/blog/README.md
index 2c9e798..bbba25c 100644
--- a/blog/README.md
+++ b/blog/README.md
@@ -43,10 +43,12 @@
 
 ## Deploying
 
-Each time a CL is reviewed and submitted, the blog is automatically redeployed to
-https://blog.golang.org/.
+Each time a CL is reviewed and submitted, the blog is automatically deployed to App Engine.
+If the CL is submitted with a Website-Publish +1 vote,
+the new deployment automatically becomes https://blog.golang.org/.
+Otherwise, the new deployment can be found in the
+[App Engine versions list](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=blog) and verified and manually promoted.
 
-If the automatic redeploy is not working, or to check on the status of a redeploy,
+If the automatic deployment is not working, or to check on the status of a pending deployment,
 see the “website-redeploy-blog” trigger in the
 [Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=golang-org).
-
diff --git a/blog/cloudbuild.yaml b/blog/cloudbuild.yaml
new file mode 100644
index 0000000..3d6559d
--- /dev/null
+++ b/blog/cloudbuild.yaml
@@ -0,0 +1,21 @@
+# This Cloud Build file is run automatically when commits land in the website repo.
+# See https://console.cloud.google.com/cloud-build/triggers?project=golang-org.
+# Do not run directly.
+
+steps:
+  - name: mirror.gcr.io/library/golang
+    args: ["go", "test", "./..."]
+    dir: blog
+  - name: gcr.io/cloud-builders/gcloud
+    entrypoint: bash
+    args: ["../go-app-deploy.sh", "app.yaml"]
+    dir: blog
+  - name: mirror.gcr.io/library/golang
+    args: [
+      "go", "run", "./cmd/versionprune", "--dry_run=false",
+      "--project=$PROJECT_ID", "--service=blog",
+    ]
+    dir: go.dev
+
+options:
+  machineType: E2_HIGHCPU_8
diff --git a/go-app-deploy.sh b/go-app-deploy.sh
new file mode 100644
index 0000000..cc80e36
--- /dev/null
+++ b/go-app-deploy.sh
@@ -0,0 +1,43 @@
+#!/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 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 sets --no-promote or --promote according to whether
+# the commit had a Website-Publish vote.
+#
+# 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 order.
+
+set -e
+
+promote=$(
+	git cat-file -p 'HEAD' |
+	awk '
+		BEGIN { flag = "--no-promote" }
+		/^Reviewed-on:/ { flag = "--no-promote" }
+		/^Website-Publish:/ { flag = "--promote" }
+		END {print flag}
+	'
+)
+
+version=$(
+	git log -n1 --date='format:%Y-%m-%d-%H%M%S' --pretty='format:%cd-%h'
+)
+
+gcloud app deploy $promote -v $version
+
diff --git a/go.dev/README.md b/go.dev/README.md
index c1a8044..5368f41 100644
--- a/go.dev/README.md
+++ b/go.dev/README.md
@@ -13,12 +13,15 @@
 
 ## Deploying
 
-Each time a CL is reviewed and submitted, the web site is automatically redeployed to
-https://go.dev/.
+Each time a CL is reviewed and submitted, the blog is automatically deployed to App Engine.
+If the CL is submitted with a Website-Publish +1 vote,
+the new deployment automatically becomes https://go.dev/.
+Otherwise, the new deployment can be found in the
+[App Engine versions list](https://console.cloud.google.com/appengine/versions?project=go-discovery&serviceId=go-dev) and verified and manually promoted.
 
-If the automatic redeploy is not working, or to check on the status of a redeploy,
+If the automatic deployment is not working, or to check on the status of a pending deployment,
 see the “website-redeploy-go-dev” trigger in the
-[Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=golang-org).
+[Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=go-discovery).
 
 ## Commands
 
diff --git a/go.dev/cloudbuild.yaml b/go.dev/cloudbuild.yaml
index 50bef8c..7228b53 100644
--- a/go.dev/cloudbuild.yaml
+++ b/go.dev/cloudbuild.yaml
@@ -1,24 +1,25 @@
+# This Cloud Build file is run automatically when commits land in the website repo.
+# See https://console.cloud.google.com/cloud-build/triggers?project=golang-org.
+# Do not run directly.
+
 steps:
   - name: 'mirror.gcr.io/library/golang'
     entrypoint: bash
-    args:
-      - -c
-      - go run ./cmd/events/ > ./_content/events.yaml
+    args: ["-c", "go run ./cmd/events/ > ./_content/events.yaml"]
     dir: go.dev
   - name: 'mirror.gcr.io/library/golang'
-    args:
-      - test
-      - ./...
+    args: ["go", "test", "./..."]
     dir: go.dev
   - name: "gcr.io/cloud-builders/gcloud"
-    args: ["app", "deploy"]
-    dir: go.dev
-  - name: "gcr.io/cloud-builders/gcloud"
-    args: ["app", "deploy", "app.learn.yaml"]
+    entrypoint: bash
+    args: ["../go-app-deploy.sh", "app.yaml"]
     dir: go.dev
   - name: 'mirror.gcr.io/library/golang'
-    args: ["go", "run", "./cmd/versionprune", "--project=$PROJECT_ID", "--service=go-dev", "--dry_run=false"]
+    args: [
+      "go", "run", "./cmd/versionprune", "--dry_run=false",
+      "--project=$PROJECT_ID", "--service=go-dev",
+    ]
     dir: go.dev
-  - name: 'mirror.gcr.io/library/golang'
-    args: ["go", "run", "./cmd/versionprune", "--project=$PROJECT_ID", "--service=learn-go-dev", "--dry_run=false"]
-    dir: go.dev
+
+options:
+  machineType: E2_HIGHCPU_8
diff --git a/tour/README.md b/tour/README.md
index ebc405f..7ddefc5 100644
--- a/tour/README.md
+++ b/tour/README.md
@@ -43,14 +43,16 @@
 
 ## Deploying
 
-Each time a CL is reviewed and submitted, the tour is automatically redeployed to
-https://tour.golang.org/.
+Each time a CL is reviewed and submitted, the tour is automatically deployed to App Engine.
+If the CL is submitted with a Website-Publish +1 vote,
+the new deployment automatically becomes https://tour.golang.org/.
+Otherwise, the new deployment can be found in the
+[App Engine versions list](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=tour) and verified and manually promoted.
 
-If the automatic redeploy is not working, or to check on the status of a redeploy,
+If the automatic deployment is not working, or to check on the status of a pending deployment,
 see the “website-redeploy-tour” trigger in the
 [Cloud Build console](https://console.cloud.google.com/cloud-build/builds?project=golang-org).
 
-
 ## License
 
 Unless otherwise noted, the go-tour source files are distributed
diff --git a/tour/cloudbuild.yaml b/tour/cloudbuild.yaml
new file mode 100644
index 0000000..99fad2a
--- /dev/null
+++ b/tour/cloudbuild.yaml
@@ -0,0 +1,21 @@
+# This Cloud Build file is run automatically when commits land in the website repo.
+# See https://console.cloud.google.com/cloud-build/triggers?project=golang-org.
+# Do not run directly.
+
+steps:
+  - name: 'mirror.gcr.io/library/golang'
+    args: ["go", "test", "./..."]
+    dir: tour
+  - name: gcr.io/cloud-builders/gcloud
+    entrypoint: bash
+    args: ["../go-app-deploy.sh", "app.yaml"]
+    dir: tour
+  - name: 'mirror.gcr.io/library/golang'
+    args: [
+      "go", "run", "./cmd/versionprune", "--dry_run=false",
+      "--project=$PROJECT_ID", "--service=tour",
+    ]
+    dir: go.dev
+
+options:
+  machineType: E2_HIGHCPU_8