cmd/releasebot: use same master commit for beta releases

The prepare mode is responsible for doing testing to ensure
all tests are passing. If a problem is found, it can be fixed
and the prepare mode should be re-done.

The release mode is responsible for taking the well-tested
commit from the prepare mode, and using it to build the release.

For beta releases, the master branch is used, and a commit has a
chance of landing between the time the prepare and release modes
are started.

Instead of fetching the latest master commit in release mode,
start reusing the same master commit that was already tested
in prepare mode.

Fixes golang/go#36182.
For golang/go#36171.

Change-Id: Ibf8052ef385cb0a1ffed372ae3e0ed0a9575882f
Reviewed-on: https://go-review.googlesource.com/c/build/+/235777
Reviewed-by: Alexander Rakoczy <alex@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/cmd/releasebot/git.go b/cmd/releasebot/git.go
index d79a3a3..9fc975b 100644
--- a/cmd/releasebot/git.go
+++ b/cmd/releasebot/git.go
@@ -18,13 +18,20 @@
 	privateGoRepoURL = "sso://team/golang/go-private"
 )
 
-// gitCheckout sets up a fresh git checkout in which to work,
-// in $HOME/go-releasebot-work/<release>/gitwork
-// (where <release> is a string like go1.8.5).
+// gitCheckout sets w.Dir to the work directory
+// at $HOME/go-releasebot-work/<release> (where <release> is a string like go1.8.5),
+// creating it if it doesn't exist,
+// and sets up a fresh git checkout in which to work,
+// in $HOME/go-releasebot-work/<release>/gitwork.
+//
 // The first time it is run for a particular release,
 // gitCheckout also creates a clean checkout in
 // $HOME/go-releasebot-work/<release>/gitmirror,
 // to use as an object cache to speed future checkouts.
+//
+// For beta releases in -mode=release, it sets w.Dir but doesn't
+// fetch the latest master branch. This way the exact commit that
+// was tested in prepare mode is also used in release mode.
 func (w *Work) gitCheckout() {
 	w.Dir = filepath.Join(os.Getenv("HOME"), "go-releasebot-work/"+strings.ToLower(w.Version))
 	w.log.Printf("working in %s\n", w.Dir)
@@ -32,6 +39,13 @@
 		w.log.Panic(err)
 	}
 
+	if w.BetaRelease && !w.Prepare {
+		// We don't want to fetch the latest "master" branch for
+		// a beta release. Instead, reuse the same commit that was
+		// already fetched from origin and tested in prepare mode.
+		return
+	}
+
 	origin := publicGoRepoURL
 	if w.Security {
 		origin = privateGoRepoURL
diff --git a/cmd/releasebot/main.go b/cmd/releasebot/main.go
index 414bc2a..11939b7 100644
--- a/cmd/releasebot/main.go
+++ b/cmd/releasebot/main.go
@@ -734,10 +734,7 @@
 			// The prepare step will run the tests on a commit that has the same
 			// tree (but maybe different message) as the one that the release
 			// step will process, so we can skip tests the second time.
-			// For beta releases, we're releasing from master. Beta releases
-			// should not skip tests, as a new commit may have been pushed after
-			// the prepare step.
-			if !w.Prepare && !w.BetaRelease {
+			if !w.Prepare {
 				args = append(args, "-skip_tests")
 			}
 			out, err := w.runner(releaseDir, "GOPATH="+filepath.Join(w.Dir, "gopath")).runErr(args...)