tour: add analytics HTML and deploy instructions

When deployed with App Engine on tour.golang.org,
insert analytics HTML at the beginning of <head>.

Add deploy instructions to the README.

Also update to the App Engine Go 1.12 runtime.

Change-Id: Ib3333290783f34eb00843006cf949308302b342d
Reviewed-on: https://go-review.googlesource.com/c/tour/+/198320
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/README.md b/README.md
index 0f980f1..2477e62 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,24 @@
 https://github.com/golang/go/issues. Prefix your issue with "tour:" in the
 subject line, so it is easy to find.
 
+## Deploying
+
+1.	To deploy tour.golang.org, run:
+
+	```
+	GO111MODULE=on gcloud --project=golang-org app deploy --no-promote app.yaml
+	```
+
+	This will create a new version, which can be viewed within the
+	[golang-org GCP project](https://console.cloud.google.com/appengine/versions?project=golang-org&serviceId=tour).
+
+2.	Check that the deployed version looks OK (click the version link in GCP).
+
+3.	If all is well, click "Migrate Traffic" to move 100% of the tour.golang.org
+	traffic to the new version.
+
+4.	You're done.
+
 ## License
 
 Unless otherwise noted, the go-tour source files are distributed
diff --git a/app.yaml b/app.yaml
index fcd8f17..5ba09d0 100644
--- a/app.yaml
+++ b/app.yaml
@@ -1,8 +1,17 @@
 service: tour
-runtime: go111
+runtime: go112
 
 env_variables:
   GOLANGORG_CHECK_COUNTRY: true
+  TOUR_ANALYTICS: |
+    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-11222381-5"></script>
+    <script>
+    window.dataLayer = window.dataLayer || [];
+    function gtag(){dataLayer.push(arguments);}
+    gtag("js", new Date());
+    gtag("config", "UA-11222381-5");
+    gtag("config", "UA-49880327-6");
+    </script>
 
 default_expiration: "7d"
 
diff --git a/appengine.go b/appengine.go
index 9398160..c6201a3 100644
--- a/appengine.go
+++ b/appengine.go
@@ -7,6 +7,7 @@
 import (
 	"bufio"
 	"bytes"
+	"html/template"
 	"io"
 	"log"
 	"net/http"
@@ -18,6 +19,7 @@
 func gaeMain() {
 	prepContent = gaePrepContent
 	socketAddr = gaeSocketAddr
+	analyticsHTML = template.HTML(os.Getenv("TOUR_ANALYTICS"))
 
 	if err := initTour(".", "HTTPTransport"); err != nil {
 		log.Fatal(err)
diff --git a/local.go b/local.go
index 21421af..7702c8f 100644
--- a/local.go
+++ b/local.go
@@ -8,6 +8,7 @@
 	"flag"
 	"fmt"
 	"go/build"
+	"html/template"
 	"io"
 	"log"
 	"net"
@@ -224,3 +225,6 @@
 
 // socketAddr returns the WebSocket handler address.
 var socketAddr = func() string { return "ws://" + httpAddr + socketPath }
+
+// analyticsHTML is optional analytics HTML to insert at the beginning of <head>.
+var analyticsHTML template.HTML
diff --git a/template/index.tmpl b/template/index.tmpl
index 01f94b4..837dc77 100755
--- a/template/index.tmpl
+++ b/template/index.tmpl
@@ -2,7 +2,7 @@
 <html lang="en" ng-app="tour">
 
 <head>
-    <meta charset="utf-8">
+{{.AnalyticsHTML}}    <meta charset="utf-8">
     <title>A Tour of Go</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
     <meta name="apple-mobile-web-app-capable" content="yes">
diff --git a/tour.go b/tour.go
index 1a74285..806b54c 100644
--- a/tour.go
+++ b/tour.go
@@ -57,9 +57,10 @@
 	buf := new(bytes.Buffer)
 
 	data := struct {
-		SocketAddr string
-		Transport  template.JS
-	}{socketAddr(), template.JS(transport)}
+		AnalyticsHTML template.HTML
+		SocketAddr    string
+		Transport     template.JS
+	}{analyticsHTML, socketAddr(), template.JS(transport)}
 
 	if err := ui.Execute(buf, data); err != nil {
 		return fmt.Errorf("render UI: %v", err)