cmd/releasebot, cmd/release: delete code for Go 1.12 and older

Go 1.14 has been released, so there will not be more Go 1.12.x releases
per the release policy¹. Remove various special code paths that applied
only to Go 1.12.x and older releases.

This change should be a no-op for Go 1.13 and newer releases.

¹ https://golang.org/doc/devel/release.html#policy

Change-Id: I94a7666364420ef077d528c351c2cb54e5379b5c
Reviewed-on: https://go-review.googlesource.com/c/build/+/221097
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Alexander Rakoczy <alex@golang.org>
diff --git a/cmd/release/release.go b/cmd/release/release.go
index 881db7a..62b0c7f 100644
--- a/cmd/release/release.go
+++ b/cmd/release/release.go
@@ -42,9 +42,6 @@
 
 	rev       = flag.String("rev", "", "Go revision to build, alternative to -tarball")
 	tarball   = flag.String("tarball", "", "Go tree tarball to build, alternative to -rev")
-	toolsRev  = flag.String("tools", "", "Tools revision to build")
-	tourRev   = flag.String("tour", "master", "Tour revision to include")
-	netRev    = flag.String("net", "master", "Net revision to include")
 	version   = flag.String("version", "", "Version string (go1.5.2)")
 	user      = flag.String("user", username(), "coordinator username, appended to 'user-'")
 	skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash instead of all.bash (only use if you ran trybots first)")
@@ -76,9 +73,6 @@
 	if *version == "" {
 		log.Fatal(`must specify -version flag (such as "go1.12" or "go1.13beta1")`)
 	}
-	if *toolsRev == "" && (versionIncludesGodoc(*version) || versionIncludesTour(*version)) {
-		log.Fatal("must specify -tools flag")
-	}
 
 	coordClient = coordinatorClient()
 	buildEnv = buildenv.Production
@@ -282,29 +276,6 @@
 			return err
 		}
 	}
-	for _, r := range []struct {
-		repo, rev string
-	}{
-		{"tools", *toolsRev},
-		{"tour", *tourRev},
-		{"net", *netRev},
-	} {
-		if b.Source {
-			continue
-		}
-		if r.repo == "tour" && !versionIncludesTour(*version) {
-			continue
-		}
-		if (r.repo == "net" || r.repo == "tools") && !versionIncludesGodoc(*version) {
-			continue
-		}
-		dir := goPath + "/src/golang.org/x/" + r.repo
-		tar := "https://go.googlesource.com/" + r.repo + "/+archive/" + r.rev + ".tar.gz"
-		if err := client.PutTarFromURL(ctx, tar, dir); err != nil {
-			b.logf("failed to put tarball %q into dir %q: %v", tar, dir, err)
-			return err
-		}
-	}
 
 	if u := bc.GoBootstrapURL(buildEnv); u != "" && !b.Source {
 		b.logf("Installing go1.4.")
@@ -427,20 +398,6 @@
 		}
 	}
 
-	var toolPaths []string
-	if versionIncludesGodoc(*version) {
-		toolPaths = append(toolPaths, "golang.org/x/tools/cmd/godoc")
-	}
-	if versionIncludesTour(*version) {
-		toolPaths = append(toolPaths, "golang.org/x/tour")
-	}
-	if len(toolPaths) > 0 {
-		b.logf("Building %v.", strings.Join(toolPaths, ", "))
-		if err := runGo(append([]string{"install"}, toolPaths...)...); err != nil {
-			return err
-		}
-	}
-
 	// postBuildCleanFiles are the list of files to remove in the go/ directory
 	// after things have been built.
 	postBuildCleanFiles := []string{
@@ -928,26 +885,6 @@
 	return append(env, wantKV)
 }
 
-// versionIncludesTour reports whether the provided Go version (of the
-// form "go1.N" or "go1.N.M" includes the Go tour binary.
-func versionIncludesTour(goVer string) bool {
-	// We don't do releases of Go 1.9 and earlier, so this only
-	// needs to recognize the two current past releases. From Go
-	// 1.12 and on, we won't ship the tour binary (see CL 131156).
-	return strings.HasPrefix(goVer, "go1.10.") ||
-		strings.HasPrefix(goVer, "go1.11.")
-}
-
-// versionIncludesGodoc reports whether the provided Go version (of the
-// form "go1.N" or "go1.N.M" includes the godoc binary.
-func versionIncludesGodoc(goVer string) bool {
-	// We don't do releases of Go 1.10 and earlier, so this only
-	// needs to recognize the two current past releases. From Go
-	// 1.13 and on, we won't ship the godoc binary (see Issue 30029).
-	return strings.HasPrefix(goVer, "go1.11.") ||
-		strings.HasPrefix(goVer, "go1.12.")
-}
-
 // minSupportedMacOSVersion provides the minimum supported macOS
 // version (of the form N.M) for each version of Go >= go1.12.
 func minSupportedMacOSVersion(goVer string) string {
diff --git a/cmd/release/releaselet.go b/cmd/release/releaselet.go
index 2ec91bc..945fdac 100644
--- a/cmd/release/releaselet.go
+++ b/cmd/release/releaselet.go
@@ -33,9 +33,6 @@
 		return
 	}
 
-	if err := godoc(); err != nil {
-		log.Fatal(err)
-	}
 	if dir := archDir(); dir != "" {
 		if err := cp("go/bin/go", "go/bin/"+dir+"/go"); err != nil {
 			log.Fatal(err)
@@ -69,38 +66,6 @@
 	return ""
 }
 
-// includesGodoc reports whether we should include the godoc binary in this release.
-// We only include it in go1.12.x and earlier releases; see issue 30029.
-func includesGodoc() bool {
-	_, version, _ := environ()
-	verMajor, verMinor, _ := splitVersion(version)
-	return verMajor == 1 && verMinor < 13
-}
-
-// godoc copies the godoc binary into place for Go 1.12 and earlier.
-//
-// TODO: remove this function once Go 1.14 is released (when Go 1.12
-// is no longer supported).
-func godoc() error {
-	if !includesGodoc() {
-		return nil
-	}
-
-	// Pre Go 1.7, the godoc binary is placed here by cmd/go.
-	// After Go 1.7, we need to copy the binary from GOPATH/bin to GOROOT/bin.
-	// TODO(cbro): Remove after Go 1.6 is no longer supported.
-	dst := filepath.FromSlash("go/bin/godoc" + ext())
-	if _, err := os.Stat(dst); err == nil {
-		return nil
-	}
-
-	// Copy godoc binary to $GOROOT/bin.
-	return cp(
-		dst,
-		filepath.FromSlash("gopath/bin/"+archDir()+"/godoc"+ext()),
-	)
-}
-
 func environ() (cwd, version string, err error) {
 	cwd, err = os.Getwd()
 	if err != nil {
@@ -131,9 +96,6 @@
 	// Write out windows data that is used by the packaging process.
 	win := filepath.Join(cwd, "windows")
 	defer os.RemoveAll(win)
-	if !includesGodoc() {
-		removeGodocShortcut()
-	}
 	if err := writeDataFiles(windowsData, win); err != nil {
 		return err
 	}
@@ -173,7 +135,6 @@
 		"-arch", msArch(),
 		"-dGoVersion="+version,
 		fmt.Sprintf("-dWixGoVersion=%v.%v.%v", verMajor, verMinor, verPatch),
-		fmt.Sprintf("-dIsWinXPSupported=%v", wixIsWinXPSupported(version)),
 		"-dArch="+runtime.GOARCH,
 		"-dSourceDir="+goDir,
 		filepath.Join(win, "installer.wxs"),
@@ -363,20 +324,6 @@
 	return
 }
 
-// wixIsWinXPSupported checks if Windows XP
-// support is expected from the specified version.
-// (WinXP is no longer supported starting Go v1.11)
-func wixIsWinXPSupported(v string) bool {
-	major, minor, _ := splitVersion(v)
-	if major > 1 {
-		return false
-	}
-	if minor >= 11 {
-		return false
-	}
-	return true
-}
-
 const storageBase = "https://storage.googleapis.com/go-builder-data/release/"
 
 // writeDataFiles writes the files in the provided map to the provided base
@@ -405,13 +352,6 @@
 	return nil
 }
 
-// removeGodocShortcut removes the GODOC_SHORTCUT part out of the
-// installer.wxs file contents.
-func removeGodocShortcut() {
-	rx := regexp.MustCompile(`(?s)<!--GODOC_SHORTCUT-->.*<!--END_GODOC_SHORTCUT-->`)
-	windowsData["installer.wxs"] = rx.ReplaceAllString(windowsData["installer.wxs"], "")
-}
-
 var windowsData = map[string]string{
 
 	"installer.wxs": `<?xml version="1.0" encoding="UTF-8"?>
@@ -462,15 +402,9 @@
   <RegistrySearch Id="installed" Type="raw" Root="HKCU" Key="Software\GoProgrammingLanguage" Name="installed" />
 </Property>
 <Media Id='1' Cabinet="go.cab" EmbedCab="yes" CompressionLevel="high" />
-<?if $(var.IsWinXPSupported) = true ?>
-    <Condition Message="Windows XP (with Service Pack 2) or greater required.">
-        (VersionNT >= 501 AND (WindowsBuild > 2600 OR ServicePackLevel >= 2))
-    </Condition>
-<?else?>
-    <Condition Message="Windows 7 (with Service Pack 1) or greater required.">
-        ((VersionNT > 601) OR (VersionNT = 601 AND ServicePackLevel >= 1))
-    </Condition>
-<?endif?>
+<Condition Message="Windows 7 (with Service Pack 1) or greater required.">
+    ((VersionNT > 601) OR (VersionNT = 601 AND ServicePackLevel >= 1))
+</Condition>
 <MajorUpgrade AllowDowngrades="yes" />
 <SetDirectory Id="INSTALLDIRROOT" Value="[%SYSTEMDRIVE]"/>
 
@@ -495,15 +429,6 @@
 <!-- Programs Menu Shortcuts -->
 <DirectoryRef Id="GoProgramShortcutsDir">
   <Component Id="Component_GoProgramShortCuts" Guid="{f5fbfb5e-6c5c-423b-9298-21b0e3c98f4b}">
-    <!--GODOC_SHORTCUT-->
-    <Shortcut
-        Id="GoDocServerStartMenuShortcut"
-        Name="GoDocServer"
-        Description="Starts the Go documentation server (http://localhost:6060)"
-        Show="minimized"
-        Arguments='/c start "Godoc Server http://localhost:6060" "[INSTALLDIR]bin\godoc.exe" -http=localhost:6060 -goroot="[INSTALLDIR]." &amp;&amp; start http://localhost:6060'
-        Icon="gopher.ico"
-        Target="[%ComSpec]" /><!--END_GODOC_SHORTCUT-->
     <Shortcut
         Id="UninstallShortcut"
         Name="Uninstall Go"
@@ -700,26 +625,8 @@
 		}
 	}
 
-	// Test wixIsWinXPSupported
-	for _, tt := range []struct {
-		v    string
-		want bool
-	}{
-		{"go1.9", true},
-		{"go1.10", true},
-		{"go1.11", false},
-		{"go1.12", false},
-	} {
-		got := wixIsWinXPSupported(tt.v)
-		if got != tt.want {
-			log.Fatalf("wixIsWinXPSupported(%q) = %v; want %v", tt.v, got, tt.want)
-		}
-	}
-
-	if !strings.Contains(windowsData["installer.wxs"], "GODOC_SHORTCUT") {
-		log.Fatal("expected GODOC_SHORTCUT to be present")
-	}
-	removeGodocShortcut()
+	// GoDoc binary is no longer bundled with the binary distribution
+	// as of Go 1.13, so there should not be a shortcut to it.
 	if strings.Contains(windowsData["installer.wxs"], "GODOC_SHORTCUT") {
 		log.Fatal("expected GODOC_SHORTCUT to be gone")
 	}
diff --git a/cmd/release/static.go b/cmd/release/static.go
index 9897ea5..300e7c6 100644
--- a/cmd/release/static.go
+++ b/cmd/release/static.go
@@ -6,4 +6,4 @@
 
 package main
 
-const releaselet = "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// +build ignore\n\n// Command releaselet does buildlet-side release construction tasks.\n// It is intended to be executed on the buildlet preparing a release.\npackage main\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\tif v, _ := strconv.ParseBool(os.Getenv(\"RUN_RELEASELET_TESTS\")); v {\n\t\trunSelfTests()\n\t\treturn\n\t}\n\n\tif err := godoc(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif dir := archDir(); dir != \"\" {\n\t\tif err := cp(\"go/bin/go\", \"go/bin/\"+dir+\"/go\"); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif err := cp(\"go/bin/gofmt\", \"go/bin/\"+dir+\"/gofmt\"); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tos.RemoveAll(\"go/bin/\" + dir)\n\t\tos.RemoveAll(\"go/pkg/linux_amd64\")\n\t\tos.RemoveAll(\"go/pkg/tool/linux_amd64\")\n\t}\n\tos.RemoveAll(\"go/pkg/obj\")\n\tif runtime.GOOS == \"windows\" {\n\t\t// Clean up .exe~ files; golang.org/issue/23894\n\t\tfilepath.Walk(\"go\", func(path string, fi os.FileInfo, err error) error {\n\t\t\tif strings.HasSuffix(path, \".exe~\") {\n\t\t\t\tos.Remove(path)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\tif err := windowsMSI(); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc archDir() string {\n\tif os.Getenv(\"GO_BUILDER_NAME\") == \"linux-s390x-crosscompile\" {\n\t\treturn \"linux_s390x\"\n\t}\n\treturn \"\"\n}\n\n// includesGodoc reports whether we should include the godoc binary in this release.\n// We only include it in go1.12.x and earlier releases; see issue 30029.\nfunc includesGodoc() bool {\n\t_, version, _ := environ()\n\tverMajor, verMinor, _ := splitVersion(version)\n\treturn verMajor == 1 && verMinor < 13\n}\n\n// godoc copies the godoc binary into place for Go 1.12 and earlier.\n//\n// TODO: remove this function once Go 1.14 is released (when Go 1.12\n// is no longer supported).\nfunc godoc() error {\n\tif !includesGodoc() {\n\t\treturn nil\n\t}\n\n\t// Pre Go 1.7, the godoc binary is placed here by cmd/go.\n\t// After Go 1.7, we need to copy the binary from GOPATH/bin to GOROOT/bin.\n\t// TODO(cbro): Remove after Go 1.6 is no longer supported.\n\tdst := filepath.FromSlash(\"go/bin/godoc\" + ext())\n\tif _, err := os.Stat(dst); err == nil {\n\t\treturn nil\n\t}\n\n\t// Copy godoc binary to $GOROOT/bin.\n\treturn cp(\n\t\tdst,\n\t\tfilepath.FromSlash(\"gopath/bin/\"+archDir()+\"/godoc\"+ext()),\n\t)\n}\n\nfunc environ() (cwd, version string, err error) {\n\tcwd, err = os.Getwd()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar versionBytes []byte\n\tversionBytes, err = ioutil.ReadFile(\"go/VERSION\")\n\tif err != nil {\n\t\treturn\n\t}\n\tversion = string(bytes.TrimSpace(versionBytes))\n\treturn\n}\n\nfunc windowsMSI() error {\n\tcwd, version, err := environ()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Install Wix tools.\n\twix := filepath.Join(cwd, \"wix\")\n\tdefer os.RemoveAll(wix)\n\tif err := installWix(wix); err != nil {\n\t\treturn err\n\t}\n\n\t// Write out windows data that is used by the packaging process.\n\twin := filepath.Join(cwd, \"windows\")\n\tdefer os.RemoveAll(win)\n\tif !includesGodoc() {\n\t\tremoveGodocShortcut()\n\t}\n\tif err := writeDataFiles(windowsData, win); err != nil {\n\t\treturn err\n\t}\n\n\t// Gather files.\n\tgoDir := filepath.Join(cwd, \"go\")\n\tappfiles := filepath.Join(win, \"AppFiles.wxs\")\n\tif err := runDir(win, filepath.Join(wix, \"heat\"),\n\t\t\"dir\", goDir,\n\t\t\"-nologo\",\n\t\t\"-gg\", \"-g1\", \"-srd\", \"-sfrag\",\n\t\t\"-cg\", \"AppFiles\",\n\t\t\"-template\", \"fragment\",\n\t\t\"-dr\", \"INSTALLDIR\",\n\t\t\"-var\", \"var.SourceDir\",\n\t\t\"-out\", appfiles,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tmsArch := func() string {\n\t\tswitch runtime.GOARCH {\n\t\tdefault:\n\t\t\tpanic(\"unknown arch for windows \" + runtime.GOARCH)\n\t\tcase \"386\":\n\t\t\treturn \"x86\"\n\t\tcase \"amd64\":\n\t\t\treturn \"x64\"\n\t\t}\n\t}\n\n\t// Build package.\n\tverMajor, verMinor, verPatch := splitVersion(version)\n\n\tif err := runDir(win, filepath.Join(wix, \"candle\"),\n\t\t\"-nologo\",\n\t\t\"-arch\", msArch(),\n\t\t\"-dGoVersion=\"+version,\n\t\tfmt.Sprintf(\"-dWixGoVersion=%v.%v.%v\", verMajor, verMinor, verPatch),\n\t\tfmt.Sprintf(\"-dIsWinXPSupported=%v\", wixIsWinXPSupported(version)),\n\t\t\"-dArch=\"+runtime.GOARCH,\n\t\t\"-dSourceDir=\"+goDir,\n\t\tfilepath.Join(win, \"installer.wxs\"),\n\t\tappfiles,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tmsi := filepath.Join(cwd, \"msi\") // known to cmd/release\n\tif err := os.Mkdir(msi, 0755); err != nil {\n\t\treturn err\n\t}\n\treturn runDir(win, filepath.Join(wix, \"light\"),\n\t\t\"-nologo\",\n\t\t\"-dcl:high\",\n\t\t\"-ext\", \"WixUIExtension\",\n\t\t\"-ext\", \"WixUtilExtension\",\n\t\t\"AppFiles.wixobj\",\n\t\t\"installer.wixobj\",\n\t\t\"-o\", filepath.Join(msi, \"go.msi\"), // file name irrelevant\n\t)\n}\n\nconst wixBinaries = \"https://storage.googleapis.com/go-builder-data/wix311-binaries.zip\"\nconst wixSha256 = \"da034c489bd1dd6d8e1623675bf5e899f32d74d6d8312f8dd125a084543193de\"\n\n// installWix fetches and installs the wix toolkit to the specified path.\nfunc installWix(path string) error {\n\t// Fetch wix binary zip file.\n\tbody, err := httpGet(wixBinaries)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Verify sha256\n\tsum := sha256.Sum256(body)\n\tif fmt.Sprintf(\"%x\", sum) != wixSha256 {\n\t\treturn errors.New(\"sha256 mismatch for wix toolkit\")\n\t}\n\n\t// Unzip to path.\n\tzr, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, f := range zr.File {\n\t\tname := filepath.FromSlash(f.Name)\n\t\terr := os.MkdirAll(filepath.Join(path, filepath.Dir(name)), 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trc, err := f.Open()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb, err := ioutil.ReadAll(rc)\n\t\trc.Close()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = ioutil.WriteFile(filepath.Join(path, name), b, 0644)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc httpGet(url string) ([]byte, error) {\n\tr, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbody, err := ioutil.ReadAll(r.Body)\n\tr.Body.Close()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif r.StatusCode != 200 {\n\t\treturn nil, errors.New(r.Status)\n\t}\n\treturn body, nil\n}\n\nfunc run(name string, arg ...string) error {\n\tcmd := exec.Command(name, arg...)\n\tcmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr\n\treturn cmd.Run()\n}\n\nfunc runDir(dir, name string, arg ...string) error {\n\tcmd := exec.Command(name, arg...)\n\tcmd.Dir = dir\n\tcmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr\n\treturn cmd.Run()\n}\n\nfunc cp(dst, src string) error {\n\tsf, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer sf.Close()\n\tfi, err := sf.Stat()\n\tif err != nil {\n\t\treturn err\n\t}\n\ttmpDst := dst + \".tmp\"\n\tdf, err := os.Create(tmpDst)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer df.Close()\n\t// Windows doesn't implement Fchmod.\n\tif runtime.GOOS != \"windows\" {\n\t\tif err := df.Chmod(fi.Mode()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t_, err = io.Copy(df, sf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := df.Close(); err != nil {\n\t\treturn err\n\t}\n\tif err := os.Rename(tmpDst, dst); err != nil {\n\t\treturn err\n\t}\n\t// Ensure the destination has the same mtime as the source.\n\treturn os.Chtimes(dst, fi.ModTime(), fi.ModTime())\n}\n\nfunc cpDir(dst, src string) error {\n\twalk := func(srcPath string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdstPath := filepath.Join(dst, srcPath[len(src):])\n\t\tif info.IsDir() {\n\t\t\treturn os.MkdirAll(dstPath, 0755)\n\t\t}\n\t\treturn cp(dstPath, srcPath)\n\t}\n\treturn filepath.Walk(src, walk)\n}\n\nfunc cpAllDir(dst, basePath string, dirs ...string) error {\n\tfor _, dir := range dirs {\n\t\tif err := cpDir(filepath.Join(dst, dir), filepath.Join(basePath, dir)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ext() string {\n\tif runtime.GOOS == \"windows\" {\n\t\treturn \".exe\"\n\t}\n\treturn \"\"\n}\n\nvar versionRe = regexp.MustCompile(`^go(\\d+(\\.\\d+)*)`)\n\n// splitVersion splits a Go version string such as \"go1.9\" or \"go1.10.2\" (as matched by versionRe)\n// into its three parts: major, minor, and patch\n// It's based on the Git tag.\nfunc splitVersion(v string) (major, minor, patch int) {\n\tm := versionRe.FindStringSubmatch(v)\n\tif m == nil {\n\t\treturn\n\t}\n\tparts := strings.Split(m[1], \".\")\n\tif len(parts) >= 1 {\n\t\tmajor, _ = strconv.Atoi(parts[0])\n\n\t\tif len(parts) >= 2 {\n\t\t\tminor, _ = strconv.Atoi(parts[1])\n\n\t\t\tif len(parts) >= 3 {\n\t\t\t\tpatch, _ = strconv.Atoi(parts[2])\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n// wixIsWinXPSupported checks if Windows XP\n// support is expected from the specified version.\n// (WinXP is no longer supported starting Go v1.11)\nfunc wixIsWinXPSupported(v string) bool {\n\tmajor, minor, _ := splitVersion(v)\n\tif major > 1 {\n\t\treturn false\n\t}\n\tif minor >= 11 {\n\t\treturn false\n\t}\n\treturn true\n}\n\nconst storageBase = \"https://storage.googleapis.com/go-builder-data/release/\"\n\n// writeDataFiles writes the files in the provided map to the provided base\n// directory. If the map value is a URL it fetches the data at that URL and\n// uses it as the file contents.\nfunc writeDataFiles(data map[string]string, base string) error {\n\tfor name, body := range data {\n\t\tdst := filepath.Join(base, name)\n\t\terr := os.MkdirAll(filepath.Dir(dst), 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb := []byte(body)\n\t\tif strings.HasPrefix(body, storageBase) {\n\t\t\tb, err = httpGet(body)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\t// (We really mean 0755 on the next line; some of these files\n\t\t// are executable, and there's no harm in making them all so.)\n\t\tif err := ioutil.WriteFile(dst, b, 0755); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// removeGodocShortcut removes the GODOC_SHORTCUT part out of the\n// installer.wxs file contents.\nfunc removeGodocShortcut() {\n\trx := regexp.MustCompile(`(?s)<!--GODOC_SHORTCUT-->.*<!--END_GODOC_SHORTCUT-->`)\n\twindowsData[\"installer.wxs\"] = rx.ReplaceAllString(windowsData[\"installer.wxs\"], \"\")\n}\n\nvar windowsData = map[string]string{\n\n\t\"installer.wxs\": `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">\n<!--\n# Copyright 2010 The Go Authors.  All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE file.\n-->\n\n<?if $(var.Arch) = 386 ?>\n  <?define ProdId = {FF5B30B2-08C2-11E1-85A2-6ACA4824019B} ?>\n  <?define UpgradeCode = {1C3114EA-08C3-11E1-9095-7FCA4824019B} ?>\n  <?define SysFolder=SystemFolder ?>\n<?else?>\n  <?define ProdId = {716c3eaa-9302-48d2-8e5e-5cfec5da2fab} ?>\n  <?define UpgradeCode = {22ea7650-4ac6-4001-bf29-f4b8775db1c0} ?>\n  <?define SysFolder=System64Folder ?>\n<?endif?>\n\n<Product\n    Id=\"*\"\n    Name=\"Go Programming Language $(var.Arch) $(var.GoVersion)\"\n    Language=\"1033\"\n    Version=\"$(var.WixGoVersion)\"\n    Manufacturer=\"https://golang.org\"\n    UpgradeCode=\"$(var.UpgradeCode)\" >\n\n<Package\n    Id='*'\n    Keywords='Installer'\n    Description=\"The Go Programming Language Installer\"\n    Comments=\"The Go programming language is an open source project to make programmers more productive.\"\n    InstallerVersion=\"300\"\n    Compressed=\"yes\"\n    InstallScope=\"perMachine\"\n    Languages=\"1033\" />\n\n<Property Id=\"ARPCOMMENTS\" Value=\"The Go programming language is a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.\" />\n<Property Id=\"ARPCONTACT\" Value=\"golang-nuts@googlegroups.com\" />\n<Property Id=\"ARPHELPLINK\" Value=\"https://golang.org/help/\" />\n<Property Id=\"ARPREADME\" Value=\"https://golang.org\" />\n<Property Id=\"ARPURLINFOABOUT\" Value=\"https://golang.org\" />\n<Property Id=\"LicenseAccepted\">1</Property>\n<Icon Id=\"gopher.ico\" SourceFile=\"images\\gopher.ico\"/>\n<Property Id=\"ARPPRODUCTICON\" Value=\"gopher.ico\" />\n<Property Id=\"EXISTING_GOLANG_INSTALLED\">\n  <RegistrySearch Id=\"installed\" Type=\"raw\" Root=\"HKCU\" Key=\"Software\\GoProgrammingLanguage\" Name=\"installed\" />\n</Property>\n<Media Id='1' Cabinet=\"go.cab\" EmbedCab=\"yes\" CompressionLevel=\"high\" />\n<?if $(var.IsWinXPSupported) = true ?>\n    <Condition Message=\"Windows XP (with Service Pack 2) or greater required.\">\n        (VersionNT >= 501 AND (WindowsBuild > 2600 OR ServicePackLevel >= 2))\n    </Condition>\n<?else?>\n    <Condition Message=\"Windows 7 (with Service Pack 1) or greater required.\">\n        ((VersionNT > 601) OR (VersionNT = 601 AND ServicePackLevel >= 1))\n    </Condition>\n<?endif?>\n<MajorUpgrade AllowDowngrades=\"yes\" />\n<SetDirectory Id=\"INSTALLDIRROOT\" Value=\"[%SYSTEMDRIVE]\"/>\n\n<CustomAction\n    Id=\"SetApplicationRootDirectory\"\n    Property=\"ARPINSTALLLOCATION\"\n    Value=\"[INSTALLDIR]\" />\n\n<!-- Define the directory structure and environment variables -->\n<Directory Id=\"TARGETDIR\" Name=\"SourceDir\">\n  <Directory Id=\"INSTALLDIRROOT\">\n    <Directory Id=\"INSTALLDIR\" Name=\"Go\"/>\n  </Directory>\n  <Directory Id=\"ProgramMenuFolder\">\n    <Directory Id=\"GoProgramShortcutsDir\" Name=\"Go Programming Language\"/>\n  </Directory>\n  <Directory Id=\"EnvironmentEntries\">\n    <Directory Id=\"GoEnvironmentEntries\" Name=\"Go Programming Language\"/>\n  </Directory>\n</Directory>\n\n<!-- Programs Menu Shortcuts -->\n<DirectoryRef Id=\"GoProgramShortcutsDir\">\n  <Component Id=\"Component_GoProgramShortCuts\" Guid=\"{f5fbfb5e-6c5c-423b-9298-21b0e3c98f4b}\">\n    <!--GODOC_SHORTCUT-->\n    <Shortcut\n        Id=\"GoDocServerStartMenuShortcut\"\n        Name=\"GoDocServer\"\n        Description=\"Starts the Go documentation server (http://localhost:6060)\"\n        Show=\"minimized\"\n        Arguments='/c start \"Godoc Server http://localhost:6060\" \"[INSTALLDIR]bin\\godoc.exe\" -http=localhost:6060 -goroot=\"[INSTALLDIR].\" &amp;&amp; start http://localhost:6060'\n        Icon=\"gopher.ico\"\n        Target=\"[%ComSpec]\" /><!--END_GODOC_SHORTCUT-->\n    <Shortcut\n        Id=\"UninstallShortcut\"\n        Name=\"Uninstall Go\"\n        Description=\"Uninstalls Go and all of its components\"\n        Target=\"[$(var.SysFolder)]msiexec.exe\"\n        Arguments=\"/x [ProductCode]\" />\n    <RemoveFolder\n        Id=\"GoProgramShortcutsDir\"\n        On=\"uninstall\" />\n    <RegistryValue\n        Root=\"HKCU\"\n        Key=\"Software\\GoProgrammingLanguage\"\n        Name=\"ShortCuts\"\n        Type=\"integer\"\n        Value=\"1\"\n        KeyPath=\"yes\" />\n  </Component>\n</DirectoryRef>\n\n<!-- Registry & Environment Settings -->\n<DirectoryRef Id=\"GoEnvironmentEntries\">\n  <Component Id=\"Component_GoEnvironment\" Guid=\"{3ec7a4d5-eb08-4de7-9312-2df392c45993}\">\n    <RegistryKey\n        Root=\"HKCU\"\n        Key=\"Software\\GoProgrammingLanguage\">\n            <RegistryValue\n                Name=\"installed\"\n                Type=\"integer\"\n                Value=\"1\"\n                KeyPath=\"yes\" />\n            <RegistryValue\n                Name=\"installLocation\"\n                Type=\"string\"\n                Value=\"[INSTALLDIR]\" />\n    </RegistryKey>\n    <Environment\n        Id=\"GoPathEntry\"\n        Action=\"set\"\n        Part=\"last\"\n        Name=\"PATH\"\n        Permanent=\"no\"\n        System=\"yes\"\n        Value=\"[INSTALLDIR]bin\" />\n    <Environment\n        Id=\"UserGoPath\"\n        Action=\"create\"\n        Name=\"GOPATH\"\n        Permanent=\"no\"\n        Value=\"%USERPROFILE%\\go\" />\n    <Environment\n        Id=\"UserGoPathEntry\"\n        Action=\"set\"\n        Part=\"last\"\n        Name=\"PATH\"\n        Permanent=\"no\"\n        Value=\"%USERPROFILE%\\go\\bin\" />\n    <RemoveFolder\n        Id=\"GoEnvironmentEntries\"\n        On=\"uninstall\" />\n  </Component>\n</DirectoryRef>\n\n<!-- Install the files -->\n<Feature\n    Id=\"GoTools\"\n    Title=\"Go\"\n    Level=\"1\">\n      <ComponentRef Id=\"Component_GoEnvironment\" />\n      <ComponentGroupRef Id=\"AppFiles\" />\n      <ComponentRef Id=\"Component_GoProgramShortCuts\" />\n</Feature>\n\n<!-- Update the environment -->\n<InstallExecuteSequence>\n    <Custom Action=\"SetApplicationRootDirectory\" Before=\"InstallFinalize\" />\n</InstallExecuteSequence>\n\n<!-- Notify top level applications of the new PATH variable (golang.org/issue/18680)  -->\n<CustomActionRef Id=\"WixBroadcastEnvironmentChange\" />\n\n<!-- Include the user interface -->\n<WixVariable Id=\"WixUILicenseRtf\" Value=\"LICENSE.rtf\" />\n<WixVariable Id=\"WixUIBannerBmp\" Value=\"images\\Banner.jpg\" />\n<WixVariable Id=\"WixUIDialogBmp\" Value=\"images\\Dialog.jpg\" />\n<Property Id=\"WIXUI_INSTALLDIR\" Value=\"INSTALLDIR\" />\n<UIRef Id=\"Golang_InstallDir\" />\n<UIRef Id=\"WixUI_ErrorProgressText\" />\n\n</Product>\n<Fragment>\n  <!--\n    The installer steps are modified so we can get user confirmation to uninstall an existing golang installation.\n\n    WelcomeDlg  [not installed]  =>                  LicenseAgreementDlg => InstallDirDlg  ..\n                [installed]      => OldVersionDlg => LicenseAgreementDlg => InstallDirDlg  ..\n  -->\n  <UI Id=\"Golang_InstallDir\">\n    <!-- style -->\n    <TextStyle Id=\"WixUI_Font_Normal\" FaceName=\"Tahoma\" Size=\"8\" />\n    <TextStyle Id=\"WixUI_Font_Bigger\" FaceName=\"Tahoma\" Size=\"12\" />\n    <TextStyle Id=\"WixUI_Font_Title\" FaceName=\"Tahoma\" Size=\"9\" Bold=\"yes\" />\n\n    <Property Id=\"DefaultUIFont\" Value=\"WixUI_Font_Normal\" />\n    <Property Id=\"WixUI_Mode\" Value=\"InstallDir\" />\n\n    <!-- dialogs -->\n    <DialogRef Id=\"BrowseDlg\" />\n    <DialogRef Id=\"DiskCostDlg\" />\n    <DialogRef Id=\"ErrorDlg\" />\n    <DialogRef Id=\"FatalError\" />\n    <DialogRef Id=\"FilesInUse\" />\n    <DialogRef Id=\"MsiRMFilesInUse\" />\n    <DialogRef Id=\"PrepareDlg\" />\n    <DialogRef Id=\"ProgressDlg\" />\n    <DialogRef Id=\"ResumeDlg\" />\n    <DialogRef Id=\"UserExit\" />\n    <Dialog Id=\"OldVersionDlg\" Width=\"240\" Height=\"95\" Title=\"[ProductName] Setup\" NoMinimize=\"yes\">\n      <Control Id=\"Text\" Type=\"Text\" X=\"28\" Y=\"15\" Width=\"194\" Height=\"50\">\n        <Text>A previous version of Go Programming Language is currently installed. By continuing the installation this version will be uninstalled. Do you want to continue?</Text>\n      </Control>\n      <Control Id=\"Exit\" Type=\"PushButton\" X=\"123\" Y=\"67\" Width=\"62\" Height=\"17\"\n        Default=\"yes\" Cancel=\"yes\" Text=\"No, Exit\">\n        <Publish Event=\"EndDialog\" Value=\"Exit\">1</Publish>\n      </Control>\n      <Control Id=\"Next\" Type=\"PushButton\" X=\"55\" Y=\"67\" Width=\"62\" Height=\"17\" Text=\"Yes, Uninstall\">\n        <Publish Event=\"EndDialog\" Value=\"Return\">1</Publish>\n      </Control>\n    </Dialog>\n\n    <!-- wizard steps -->\n    <Publish Dialog=\"BrowseDlg\" Control=\"OK\" Event=\"DoAction\" Value=\"WixUIValidatePath\" Order=\"3\">1</Publish>\n    <Publish Dialog=\"BrowseDlg\" Control=\"OK\" Event=\"SpawnDialog\" Value=\"InvalidDirDlg\" Order=\"4\"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>\"1\"]]></Publish>\n\n    <Publish Dialog=\"ExitDialog\" Control=\"Finish\" Event=\"EndDialog\" Value=\"Return\" Order=\"999\">1</Publish>\n\n    <Publish Dialog=\"WelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"OldVersionDlg\"><![CDATA[EXISTING_GOLANG_INSTALLED << \"#1\"]]> </Publish>\n    <Publish Dialog=\"WelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\"><![CDATA[NOT (EXISTING_GOLANG_INSTALLED << \"#1\")]]></Publish>\n\n    <Publish Dialog=\"OldVersionDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\">1</Publish>\n\n    <Publish Dialog=\"LicenseAgreementDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"WelcomeDlg\">1</Publish>\n    <Publish Dialog=\"LicenseAgreementDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"InstallDirDlg\">LicenseAccepted = \"1\"</Publish>\n\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"SetTargetPath\" Value=\"[WIXUI_INSTALLDIR]\" Order=\"1\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"DoAction\" Value=\"WixUIValidatePath\" Order=\"2\">NOT WIXUI_DONTVALIDATEPATH</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"SpawnDialog\" Value=\"InvalidDirDlg\" Order=\"3\"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>\"1\"]]></Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\" Order=\"4\">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=\"1\"</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"ChangeFolder\" Property=\"_BrowseProperty\" Value=\"[WIXUI_INSTALLDIR]\" Order=\"1\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"ChangeFolder\" Event=\"SpawnDialog\" Value=\"BrowseDlg\" Order=\"2\">1</Publish>\n\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"InstallDirDlg\" Order=\"1\">NOT Installed</Publish>\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"MaintenanceTypeDlg\" Order=\"2\">Installed AND NOT PATCH</Publish>\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"WelcomeDlg\" Order=\"2\">Installed AND PATCH</Publish>\n\n    <Publish Dialog=\"MaintenanceWelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"MaintenanceTypeDlg\">1</Publish>\n\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"RepairButton\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\">1</Publish>\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"RemoveButton\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\">1</Publish>\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"MaintenanceWelcomeDlg\">1</Publish>\n\n    <Property Id=\"ARPNOMODIFY\" Value=\"1\" />\n  </UI>\n\n  <UIRef Id=\"WixUI_Common\" />\n</Fragment>\n</Wix>\n`,\n\n\t\"LICENSE.rtf\":           storageBase + \"windows/LICENSE.rtf\",\n\t\"images/Banner.jpg\":     storageBase + \"windows/Banner.jpg\",\n\t\"images/Dialog.jpg\":     storageBase + \"windows/Dialog.jpg\",\n\t\"images/DialogLeft.jpg\": storageBase + \"windows/DialogLeft.jpg\",\n\t\"images/gopher.ico\":     storageBase + \"windows/gopher.ico\",\n}\n\n// runSelfTests contains the tests for this file, since this file is\n// +build ignore. This is called by releaselet_test.go with an\n// environment variable set, which func main above recognizes.\nfunc runSelfTests() {\n\t// Test splitVersion.\n\tfor _, tt := range []struct {\n\t\tv                   string\n\t\tmajor, minor, patch int\n\t}{\n\t\t{\"go1\", 1, 0, 0},\n\t\t{\"go1.34\", 1, 34, 0},\n\t\t{\"go1.34.7\", 1, 34, 7},\n\t} {\n\t\tmajor, minor, patch := splitVersion(tt.v)\n\t\tif major != tt.major || minor != tt.minor || patch != tt.patch {\n\t\t\tlog.Fatalf(\"splitVersion(%q) = %v, %v, %v; want %v, %v, %v\",\n\t\t\t\ttt.v, major, minor, patch, tt.major, tt.minor, tt.patch)\n\t\t}\n\t}\n\n\t// Test wixIsWinXPSupported\n\tfor _, tt := range []struct {\n\t\tv    string\n\t\twant bool\n\t}{\n\t\t{\"go1.9\", true},\n\t\t{\"go1.10\", true},\n\t\t{\"go1.11\", false},\n\t\t{\"go1.12\", false},\n\t} {\n\t\tgot := wixIsWinXPSupported(tt.v)\n\t\tif got != tt.want {\n\t\t\tlog.Fatalf(\"wixIsWinXPSupported(%q) = %v; want %v\", tt.v, got, tt.want)\n\t\t}\n\t}\n\n\tif !strings.Contains(windowsData[\"installer.wxs\"], \"GODOC_SHORTCUT\") {\n\t\tlog.Fatal(\"expected GODOC_SHORTCUT to be present\")\n\t}\n\tremoveGodocShortcut()\n\tif strings.Contains(windowsData[\"installer.wxs\"], \"GODOC_SHORTCUT\") {\n\t\tlog.Fatal(\"expected GODOC_SHORTCUT to be gone\")\n\t}\n\n\tfmt.Println(\"ok\")\n}\n"
+const releaselet = "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// +build ignore\n\n// Command releaselet does buildlet-side release construction tasks.\n// It is intended to be executed on the buildlet preparing a release.\npackage main\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\tif v, _ := strconv.ParseBool(os.Getenv(\"RUN_RELEASELET_TESTS\")); v {\n\t\trunSelfTests()\n\t\treturn\n\t}\n\n\tif dir := archDir(); dir != \"\" {\n\t\tif err := cp(\"go/bin/go\", \"go/bin/\"+dir+\"/go\"); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif err := cp(\"go/bin/gofmt\", \"go/bin/\"+dir+\"/gofmt\"); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tos.RemoveAll(\"go/bin/\" + dir)\n\t\tos.RemoveAll(\"go/pkg/linux_amd64\")\n\t\tos.RemoveAll(\"go/pkg/tool/linux_amd64\")\n\t}\n\tos.RemoveAll(\"go/pkg/obj\")\n\tif runtime.GOOS == \"windows\" {\n\t\t// Clean up .exe~ files; golang.org/issue/23894\n\t\tfilepath.Walk(\"go\", func(path string, fi os.FileInfo, err error) error {\n\t\t\tif strings.HasSuffix(path, \".exe~\") {\n\t\t\t\tos.Remove(path)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\tif err := windowsMSI(); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc archDir() string {\n\tif os.Getenv(\"GO_BUILDER_NAME\") == \"linux-s390x-crosscompile\" {\n\t\treturn \"linux_s390x\"\n\t}\n\treturn \"\"\n}\n\nfunc environ() (cwd, version string, err error) {\n\tcwd, err = os.Getwd()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar versionBytes []byte\n\tversionBytes, err = ioutil.ReadFile(\"go/VERSION\")\n\tif err != nil {\n\t\treturn\n\t}\n\tversion = string(bytes.TrimSpace(versionBytes))\n\treturn\n}\n\nfunc windowsMSI() error {\n\tcwd, version, err := environ()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Install Wix tools.\n\twix := filepath.Join(cwd, \"wix\")\n\tdefer os.RemoveAll(wix)\n\tif err := installWix(wix); err != nil {\n\t\treturn err\n\t}\n\n\t// Write out windows data that is used by the packaging process.\n\twin := filepath.Join(cwd, \"windows\")\n\tdefer os.RemoveAll(win)\n\tif err := writeDataFiles(windowsData, win); err != nil {\n\t\treturn err\n\t}\n\n\t// Gather files.\n\tgoDir := filepath.Join(cwd, \"go\")\n\tappfiles := filepath.Join(win, \"AppFiles.wxs\")\n\tif err := runDir(win, filepath.Join(wix, \"heat\"),\n\t\t\"dir\", goDir,\n\t\t\"-nologo\",\n\t\t\"-gg\", \"-g1\", \"-srd\", \"-sfrag\",\n\t\t\"-cg\", \"AppFiles\",\n\t\t\"-template\", \"fragment\",\n\t\t\"-dr\", \"INSTALLDIR\",\n\t\t\"-var\", \"var.SourceDir\",\n\t\t\"-out\", appfiles,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tmsArch := func() string {\n\t\tswitch runtime.GOARCH {\n\t\tdefault:\n\t\t\tpanic(\"unknown arch for windows \" + runtime.GOARCH)\n\t\tcase \"386\":\n\t\t\treturn \"x86\"\n\t\tcase \"amd64\":\n\t\t\treturn \"x64\"\n\t\t}\n\t}\n\n\t// Build package.\n\tverMajor, verMinor, verPatch := splitVersion(version)\n\n\tif err := runDir(win, filepath.Join(wix, \"candle\"),\n\t\t\"-nologo\",\n\t\t\"-arch\", msArch(),\n\t\t\"-dGoVersion=\"+version,\n\t\tfmt.Sprintf(\"-dWixGoVersion=%v.%v.%v\", verMajor, verMinor, verPatch),\n\t\t\"-dArch=\"+runtime.GOARCH,\n\t\t\"-dSourceDir=\"+goDir,\n\t\tfilepath.Join(win, \"installer.wxs\"),\n\t\tappfiles,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tmsi := filepath.Join(cwd, \"msi\") // known to cmd/release\n\tif err := os.Mkdir(msi, 0755); err != nil {\n\t\treturn err\n\t}\n\treturn runDir(win, filepath.Join(wix, \"light\"),\n\t\t\"-nologo\",\n\t\t\"-dcl:high\",\n\t\t\"-ext\", \"WixUIExtension\",\n\t\t\"-ext\", \"WixUtilExtension\",\n\t\t\"AppFiles.wixobj\",\n\t\t\"installer.wixobj\",\n\t\t\"-o\", filepath.Join(msi, \"go.msi\"), // file name irrelevant\n\t)\n}\n\nconst wixBinaries = \"https://storage.googleapis.com/go-builder-data/wix311-binaries.zip\"\nconst wixSha256 = \"da034c489bd1dd6d8e1623675bf5e899f32d74d6d8312f8dd125a084543193de\"\n\n// installWix fetches and installs the wix toolkit to the specified path.\nfunc installWix(path string) error {\n\t// Fetch wix binary zip file.\n\tbody, err := httpGet(wixBinaries)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Verify sha256\n\tsum := sha256.Sum256(body)\n\tif fmt.Sprintf(\"%x\", sum) != wixSha256 {\n\t\treturn errors.New(\"sha256 mismatch for wix toolkit\")\n\t}\n\n\t// Unzip to path.\n\tzr, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, f := range zr.File {\n\t\tname := filepath.FromSlash(f.Name)\n\t\terr := os.MkdirAll(filepath.Join(path, filepath.Dir(name)), 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trc, err := f.Open()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb, err := ioutil.ReadAll(rc)\n\t\trc.Close()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = ioutil.WriteFile(filepath.Join(path, name), b, 0644)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc httpGet(url string) ([]byte, error) {\n\tr, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbody, err := ioutil.ReadAll(r.Body)\n\tr.Body.Close()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif r.StatusCode != 200 {\n\t\treturn nil, errors.New(r.Status)\n\t}\n\treturn body, nil\n}\n\nfunc run(name string, arg ...string) error {\n\tcmd := exec.Command(name, arg...)\n\tcmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr\n\treturn cmd.Run()\n}\n\nfunc runDir(dir, name string, arg ...string) error {\n\tcmd := exec.Command(name, arg...)\n\tcmd.Dir = dir\n\tcmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr\n\treturn cmd.Run()\n}\n\nfunc cp(dst, src string) error {\n\tsf, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer sf.Close()\n\tfi, err := sf.Stat()\n\tif err != nil {\n\t\treturn err\n\t}\n\ttmpDst := dst + \".tmp\"\n\tdf, err := os.Create(tmpDst)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer df.Close()\n\t// Windows doesn't implement Fchmod.\n\tif runtime.GOOS != \"windows\" {\n\t\tif err := df.Chmod(fi.Mode()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t_, err = io.Copy(df, sf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := df.Close(); err != nil {\n\t\treturn err\n\t}\n\tif err := os.Rename(tmpDst, dst); err != nil {\n\t\treturn err\n\t}\n\t// Ensure the destination has the same mtime as the source.\n\treturn os.Chtimes(dst, fi.ModTime(), fi.ModTime())\n}\n\nfunc cpDir(dst, src string) error {\n\twalk := func(srcPath string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdstPath := filepath.Join(dst, srcPath[len(src):])\n\t\tif info.IsDir() {\n\t\t\treturn os.MkdirAll(dstPath, 0755)\n\t\t}\n\t\treturn cp(dstPath, srcPath)\n\t}\n\treturn filepath.Walk(src, walk)\n}\n\nfunc cpAllDir(dst, basePath string, dirs ...string) error {\n\tfor _, dir := range dirs {\n\t\tif err := cpDir(filepath.Join(dst, dir), filepath.Join(basePath, dir)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ext() string {\n\tif runtime.GOOS == \"windows\" {\n\t\treturn \".exe\"\n\t}\n\treturn \"\"\n}\n\nvar versionRe = regexp.MustCompile(`^go(\\d+(\\.\\d+)*)`)\n\n// splitVersion splits a Go version string such as \"go1.9\" or \"go1.10.2\" (as matched by versionRe)\n// into its three parts: major, minor, and patch\n// It's based on the Git tag.\nfunc splitVersion(v string) (major, minor, patch int) {\n\tm := versionRe.FindStringSubmatch(v)\n\tif m == nil {\n\t\treturn\n\t}\n\tparts := strings.Split(m[1], \".\")\n\tif len(parts) >= 1 {\n\t\tmajor, _ = strconv.Atoi(parts[0])\n\n\t\tif len(parts) >= 2 {\n\t\t\tminor, _ = strconv.Atoi(parts[1])\n\n\t\t\tif len(parts) >= 3 {\n\t\t\t\tpatch, _ = strconv.Atoi(parts[2])\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nconst storageBase = \"https://storage.googleapis.com/go-builder-data/release/\"\n\n// writeDataFiles writes the files in the provided map to the provided base\n// directory. If the map value is a URL it fetches the data at that URL and\n// uses it as the file contents.\nfunc writeDataFiles(data map[string]string, base string) error {\n\tfor name, body := range data {\n\t\tdst := filepath.Join(base, name)\n\t\terr := os.MkdirAll(filepath.Dir(dst), 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb := []byte(body)\n\t\tif strings.HasPrefix(body, storageBase) {\n\t\t\tb, err = httpGet(body)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\t// (We really mean 0755 on the next line; some of these files\n\t\t// are executable, and there's no harm in making them all so.)\n\t\tif err := ioutil.WriteFile(dst, b, 0755); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nvar windowsData = map[string]string{\n\n\t\"installer.wxs\": `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">\n<!--\n# Copyright 2010 The Go Authors.  All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE file.\n-->\n\n<?if $(var.Arch) = 386 ?>\n  <?define ProdId = {FF5B30B2-08C2-11E1-85A2-6ACA4824019B} ?>\n  <?define UpgradeCode = {1C3114EA-08C3-11E1-9095-7FCA4824019B} ?>\n  <?define SysFolder=SystemFolder ?>\n<?else?>\n  <?define ProdId = {716c3eaa-9302-48d2-8e5e-5cfec5da2fab} ?>\n  <?define UpgradeCode = {22ea7650-4ac6-4001-bf29-f4b8775db1c0} ?>\n  <?define SysFolder=System64Folder ?>\n<?endif?>\n\n<Product\n    Id=\"*\"\n    Name=\"Go Programming Language $(var.Arch) $(var.GoVersion)\"\n    Language=\"1033\"\n    Version=\"$(var.WixGoVersion)\"\n    Manufacturer=\"https://golang.org\"\n    UpgradeCode=\"$(var.UpgradeCode)\" >\n\n<Package\n    Id='*'\n    Keywords='Installer'\n    Description=\"The Go Programming Language Installer\"\n    Comments=\"The Go programming language is an open source project to make programmers more productive.\"\n    InstallerVersion=\"300\"\n    Compressed=\"yes\"\n    InstallScope=\"perMachine\"\n    Languages=\"1033\" />\n\n<Property Id=\"ARPCOMMENTS\" Value=\"The Go programming language is a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.\" />\n<Property Id=\"ARPCONTACT\" Value=\"golang-nuts@googlegroups.com\" />\n<Property Id=\"ARPHELPLINK\" Value=\"https://golang.org/help/\" />\n<Property Id=\"ARPREADME\" Value=\"https://golang.org\" />\n<Property Id=\"ARPURLINFOABOUT\" Value=\"https://golang.org\" />\n<Property Id=\"LicenseAccepted\">1</Property>\n<Icon Id=\"gopher.ico\" SourceFile=\"images\\gopher.ico\"/>\n<Property Id=\"ARPPRODUCTICON\" Value=\"gopher.ico\" />\n<Property Id=\"EXISTING_GOLANG_INSTALLED\">\n  <RegistrySearch Id=\"installed\" Type=\"raw\" Root=\"HKCU\" Key=\"Software\\GoProgrammingLanguage\" Name=\"installed\" />\n</Property>\n<Media Id='1' Cabinet=\"go.cab\" EmbedCab=\"yes\" CompressionLevel=\"high\" />\n<Condition Message=\"Windows 7 (with Service Pack 1) or greater required.\">\n    ((VersionNT > 601) OR (VersionNT = 601 AND ServicePackLevel >= 1))\n</Condition>\n<MajorUpgrade AllowDowngrades=\"yes\" />\n<SetDirectory Id=\"INSTALLDIRROOT\" Value=\"[%SYSTEMDRIVE]\"/>\n\n<CustomAction\n    Id=\"SetApplicationRootDirectory\"\n    Property=\"ARPINSTALLLOCATION\"\n    Value=\"[INSTALLDIR]\" />\n\n<!-- Define the directory structure and environment variables -->\n<Directory Id=\"TARGETDIR\" Name=\"SourceDir\">\n  <Directory Id=\"INSTALLDIRROOT\">\n    <Directory Id=\"INSTALLDIR\" Name=\"Go\"/>\n  </Directory>\n  <Directory Id=\"ProgramMenuFolder\">\n    <Directory Id=\"GoProgramShortcutsDir\" Name=\"Go Programming Language\"/>\n  </Directory>\n  <Directory Id=\"EnvironmentEntries\">\n    <Directory Id=\"GoEnvironmentEntries\" Name=\"Go Programming Language\"/>\n  </Directory>\n</Directory>\n\n<!-- Programs Menu Shortcuts -->\n<DirectoryRef Id=\"GoProgramShortcutsDir\">\n  <Component Id=\"Component_GoProgramShortCuts\" Guid=\"{f5fbfb5e-6c5c-423b-9298-21b0e3c98f4b}\">\n    <Shortcut\n        Id=\"UninstallShortcut\"\n        Name=\"Uninstall Go\"\n        Description=\"Uninstalls Go and all of its components\"\n        Target=\"[$(var.SysFolder)]msiexec.exe\"\n        Arguments=\"/x [ProductCode]\" />\n    <RemoveFolder\n        Id=\"GoProgramShortcutsDir\"\n        On=\"uninstall\" />\n    <RegistryValue\n        Root=\"HKCU\"\n        Key=\"Software\\GoProgrammingLanguage\"\n        Name=\"ShortCuts\"\n        Type=\"integer\"\n        Value=\"1\"\n        KeyPath=\"yes\" />\n  </Component>\n</DirectoryRef>\n\n<!-- Registry & Environment Settings -->\n<DirectoryRef Id=\"GoEnvironmentEntries\">\n  <Component Id=\"Component_GoEnvironment\" Guid=\"{3ec7a4d5-eb08-4de7-9312-2df392c45993}\">\n    <RegistryKey\n        Root=\"HKCU\"\n        Key=\"Software\\GoProgrammingLanguage\">\n            <RegistryValue\n                Name=\"installed\"\n                Type=\"integer\"\n                Value=\"1\"\n                KeyPath=\"yes\" />\n            <RegistryValue\n                Name=\"installLocation\"\n                Type=\"string\"\n                Value=\"[INSTALLDIR]\" />\n    </RegistryKey>\n    <Environment\n        Id=\"GoPathEntry\"\n        Action=\"set\"\n        Part=\"last\"\n        Name=\"PATH\"\n        Permanent=\"no\"\n        System=\"yes\"\n        Value=\"[INSTALLDIR]bin\" />\n    <Environment\n        Id=\"UserGoPath\"\n        Action=\"create\"\n        Name=\"GOPATH\"\n        Permanent=\"no\"\n        Value=\"%USERPROFILE%\\go\" />\n    <Environment\n        Id=\"UserGoPathEntry\"\n        Action=\"set\"\n        Part=\"last\"\n        Name=\"PATH\"\n        Permanent=\"no\"\n        Value=\"%USERPROFILE%\\go\\bin\" />\n    <RemoveFolder\n        Id=\"GoEnvironmentEntries\"\n        On=\"uninstall\" />\n  </Component>\n</DirectoryRef>\n\n<!-- Install the files -->\n<Feature\n    Id=\"GoTools\"\n    Title=\"Go\"\n    Level=\"1\">\n      <ComponentRef Id=\"Component_GoEnvironment\" />\n      <ComponentGroupRef Id=\"AppFiles\" />\n      <ComponentRef Id=\"Component_GoProgramShortCuts\" />\n</Feature>\n\n<!-- Update the environment -->\n<InstallExecuteSequence>\n    <Custom Action=\"SetApplicationRootDirectory\" Before=\"InstallFinalize\" />\n</InstallExecuteSequence>\n\n<!-- Notify top level applications of the new PATH variable (golang.org/issue/18680)  -->\n<CustomActionRef Id=\"WixBroadcastEnvironmentChange\" />\n\n<!-- Include the user interface -->\n<WixVariable Id=\"WixUILicenseRtf\" Value=\"LICENSE.rtf\" />\n<WixVariable Id=\"WixUIBannerBmp\" Value=\"images\\Banner.jpg\" />\n<WixVariable Id=\"WixUIDialogBmp\" Value=\"images\\Dialog.jpg\" />\n<Property Id=\"WIXUI_INSTALLDIR\" Value=\"INSTALLDIR\" />\n<UIRef Id=\"Golang_InstallDir\" />\n<UIRef Id=\"WixUI_ErrorProgressText\" />\n\n</Product>\n<Fragment>\n  <!--\n    The installer steps are modified so we can get user confirmation to uninstall an existing golang installation.\n\n    WelcomeDlg  [not installed]  =>                  LicenseAgreementDlg => InstallDirDlg  ..\n                [installed]      => OldVersionDlg => LicenseAgreementDlg => InstallDirDlg  ..\n  -->\n  <UI Id=\"Golang_InstallDir\">\n    <!-- style -->\n    <TextStyle Id=\"WixUI_Font_Normal\" FaceName=\"Tahoma\" Size=\"8\" />\n    <TextStyle Id=\"WixUI_Font_Bigger\" FaceName=\"Tahoma\" Size=\"12\" />\n    <TextStyle Id=\"WixUI_Font_Title\" FaceName=\"Tahoma\" Size=\"9\" Bold=\"yes\" />\n\n    <Property Id=\"DefaultUIFont\" Value=\"WixUI_Font_Normal\" />\n    <Property Id=\"WixUI_Mode\" Value=\"InstallDir\" />\n\n    <!-- dialogs -->\n    <DialogRef Id=\"BrowseDlg\" />\n    <DialogRef Id=\"DiskCostDlg\" />\n    <DialogRef Id=\"ErrorDlg\" />\n    <DialogRef Id=\"FatalError\" />\n    <DialogRef Id=\"FilesInUse\" />\n    <DialogRef Id=\"MsiRMFilesInUse\" />\n    <DialogRef Id=\"PrepareDlg\" />\n    <DialogRef Id=\"ProgressDlg\" />\n    <DialogRef Id=\"ResumeDlg\" />\n    <DialogRef Id=\"UserExit\" />\n    <Dialog Id=\"OldVersionDlg\" Width=\"240\" Height=\"95\" Title=\"[ProductName] Setup\" NoMinimize=\"yes\">\n      <Control Id=\"Text\" Type=\"Text\" X=\"28\" Y=\"15\" Width=\"194\" Height=\"50\">\n        <Text>A previous version of Go Programming Language is currently installed. By continuing the installation this version will be uninstalled. Do you want to continue?</Text>\n      </Control>\n      <Control Id=\"Exit\" Type=\"PushButton\" X=\"123\" Y=\"67\" Width=\"62\" Height=\"17\"\n        Default=\"yes\" Cancel=\"yes\" Text=\"No, Exit\">\n        <Publish Event=\"EndDialog\" Value=\"Exit\">1</Publish>\n      </Control>\n      <Control Id=\"Next\" Type=\"PushButton\" X=\"55\" Y=\"67\" Width=\"62\" Height=\"17\" Text=\"Yes, Uninstall\">\n        <Publish Event=\"EndDialog\" Value=\"Return\">1</Publish>\n      </Control>\n    </Dialog>\n\n    <!-- wizard steps -->\n    <Publish Dialog=\"BrowseDlg\" Control=\"OK\" Event=\"DoAction\" Value=\"WixUIValidatePath\" Order=\"3\">1</Publish>\n    <Publish Dialog=\"BrowseDlg\" Control=\"OK\" Event=\"SpawnDialog\" Value=\"InvalidDirDlg\" Order=\"4\"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>\"1\"]]></Publish>\n\n    <Publish Dialog=\"ExitDialog\" Control=\"Finish\" Event=\"EndDialog\" Value=\"Return\" Order=\"999\">1</Publish>\n\n    <Publish Dialog=\"WelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"OldVersionDlg\"><![CDATA[EXISTING_GOLANG_INSTALLED << \"#1\"]]> </Publish>\n    <Publish Dialog=\"WelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\"><![CDATA[NOT (EXISTING_GOLANG_INSTALLED << \"#1\")]]></Publish>\n\n    <Publish Dialog=\"OldVersionDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\">1</Publish>\n\n    <Publish Dialog=\"LicenseAgreementDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"WelcomeDlg\">1</Publish>\n    <Publish Dialog=\"LicenseAgreementDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"InstallDirDlg\">LicenseAccepted = \"1\"</Publish>\n\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"LicenseAgreementDlg\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"SetTargetPath\" Value=\"[WIXUI_INSTALLDIR]\" Order=\"1\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"DoAction\" Value=\"WixUIValidatePath\" Order=\"2\">NOT WIXUI_DONTVALIDATEPATH</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"SpawnDialog\" Value=\"InvalidDirDlg\" Order=\"3\"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>\"1\"]]></Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\" Order=\"4\">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=\"1\"</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"ChangeFolder\" Property=\"_BrowseProperty\" Value=\"[WIXUI_INSTALLDIR]\" Order=\"1\">1</Publish>\n    <Publish Dialog=\"InstallDirDlg\" Control=\"ChangeFolder\" Event=\"SpawnDialog\" Value=\"BrowseDlg\" Order=\"2\">1</Publish>\n\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"InstallDirDlg\" Order=\"1\">NOT Installed</Publish>\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"MaintenanceTypeDlg\" Order=\"2\">Installed AND NOT PATCH</Publish>\n    <Publish Dialog=\"VerifyReadyDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"WelcomeDlg\" Order=\"2\">Installed AND PATCH</Publish>\n\n    <Publish Dialog=\"MaintenanceWelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"MaintenanceTypeDlg\">1</Publish>\n\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"RepairButton\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\">1</Publish>\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"RemoveButton\" Event=\"NewDialog\" Value=\"VerifyReadyDlg\">1</Publish>\n    <Publish Dialog=\"MaintenanceTypeDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"MaintenanceWelcomeDlg\">1</Publish>\n\n    <Property Id=\"ARPNOMODIFY\" Value=\"1\" />\n  </UI>\n\n  <UIRef Id=\"WixUI_Common\" />\n</Fragment>\n</Wix>\n`,\n\n\t\"LICENSE.rtf\":           storageBase + \"windows/LICENSE.rtf\",\n\t\"images/Banner.jpg\":     storageBase + \"windows/Banner.jpg\",\n\t\"images/Dialog.jpg\":     storageBase + \"windows/Dialog.jpg\",\n\t\"images/DialogLeft.jpg\": storageBase + \"windows/DialogLeft.jpg\",\n\t\"images/gopher.ico\":     storageBase + \"windows/gopher.ico\",\n}\n\n// runSelfTests contains the tests for this file, since this file is\n// +build ignore. This is called by releaselet_test.go with an\n// environment variable set, which func main above recognizes.\nfunc runSelfTests() {\n\t// Test splitVersion.\n\tfor _, tt := range []struct {\n\t\tv                   string\n\t\tmajor, minor, patch int\n\t}{\n\t\t{\"go1\", 1, 0, 0},\n\t\t{\"go1.34\", 1, 34, 0},\n\t\t{\"go1.34.7\", 1, 34, 7},\n\t} {\n\t\tmajor, minor, patch := splitVersion(tt.v)\n\t\tif major != tt.major || minor != tt.minor || patch != tt.patch {\n\t\t\tlog.Fatalf(\"splitVersion(%q) = %v, %v, %v; want %v, %v, %v\",\n\t\t\t\ttt.v, major, minor, patch, tt.major, tt.minor, tt.patch)\n\t\t}\n\t}\n\n\t// GoDoc binary is no longer bundled with the binary distribution\n\t// as of Go 1.13, so there should not be a shortcut to it.\n\tif strings.Contains(windowsData[\"installer.wxs\"], \"GODOC_SHORTCUT\") {\n\t\tlog.Fatal(\"expected GODOC_SHORTCUT to be gone\")\n\t}\n\n\tfmt.Println(\"ok\")\n}\n"
diff --git a/cmd/releasebot/main.go b/cmd/releasebot/main.go
index 51986c1..414bc2a 100644
--- a/cmd/releasebot/main.go
+++ b/cmd/releasebot/main.go
@@ -545,26 +545,6 @@
 	if !strings.Contains(string(data), major) {
 		w.logError("doc/contrib.html does not list major version %s", major)
 	}
-
-	// TODO: Delete this block after Go 1.14 is released (and Go 1.12 is no longer supported),
-	//       or consider moving it into a third -mode=wrapup. See golang.org/issue/36086.
-	if w.activeReleaseHistory() {
-		// Check that the release is listed on the release history page.
-		data, err := ioutil.ReadFile(filepath.Join(w.Dir, "gitwork", "doc/devel/release.html"))
-		if err != nil {
-			w.log.Panic(err)
-		}
-		if !strings.Contains(string(data), w.Version+" (released ") {
-			w.logError("doc/devel/release.html does not document %s", w.Version)
-		}
-	}
-}
-
-// activeReleaseHistory reports whether this release needs to include
-// an up-to-date release history page. We've stopped doing this for
-// Go 1.13 and newer. See golang.org/issue/36075.
-func (w *Work) activeReleaseHistory() bool {
-	return major(w.Version) == "go1.12"
 }
 
 // major takes a go version like "go1.5", "go1.5.1", "go1.5.2", etc.,
@@ -744,10 +724,8 @@
 	} else {
 		failures := 0
 		for {
-			releaseBranch := strings.TrimSuffix(w.ReleaseBranch, "-security")
 			args := []string{w.ReleaseBinary, "-target", target, "-user", gomoteUser,
-				"-version", w.Version, "-tools", releaseBranch, "-net", releaseBranch,
-				"-staging_dir", w.StagingDir}
+				"-version", w.Version, "-staging_dir", w.StagingDir}
 			if w.Security {
 				args = append(args, "-tarball", filepath.Join(w.Dir, w.VersionCommit+".tar.gz"))
 			} else {