// Copyright 2017 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.

// Releasebot manages the process of defining,
// packaging, and publishing Go releases.
package main

import (
	"bytes"
	"context"
	"crypto/sha1"
	"crypto/sha256"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime/debug"
	"strconv"
	"strings"
	"sync"
	"time"

	"golang.org/x/build/buildenv"
	"golang.org/x/build/internal/task"
	"golang.org/x/build/maintner"
)

// A Target is a release target.
type Target struct {
	// GoQuery is a Go version query specifying the Go versions the
	// release target applies to. Empty string means all Go versions.
	GoQuery string

	Name     string // Target name as accepted by cmd/release. For example, "linux-amd64".
	TestOnly bool   // Run tests only; don't produce a release artifact.
}

var releaseTargets = []Target{
	// Source-only target.
	{Name: "src"},

	// Binary targets.
	{Name: "linux-386"},
	{Name: "linux-armv6l"},
	{Name: "linux-amd64"},
	{Name: "linux-arm64"},
	{Name: "freebsd-386"},
	{Name: "freebsd-amd64"},
	{Name: "windows-386"},
	{Name: "windows-amd64"},
	{Name: "windows-arm64", GoQuery: ">= go1.17beta1"},
	{Name: "darwin-amd64"},
	{Name: "darwin-arm64", GoQuery: ">= go1.16beta1"},
	{Name: "linux-s390x"},
	{Name: "linux-ppc64le"},

	// Test-only targets.
	{Name: "linux-386-longtest", TestOnly: true},
	{Name: "linux-amd64-longtest", TestOnly: true},
	{Name: "windows-amd64-longtest", TestOnly: true},
}

var releaseModes = map[string]bool{
	"prepare":    true,
	"release":    true,
	"mail-dl-cl": true,
}

func usage() {
	fmt.Fprintln(os.Stderr, "usage: releasebot -mode {prepare|release|mail-dl-cl} [-security] [-dry-run] {go1.8.5|go1.10beta2|go1.11rc1}")
	flag.PrintDefaults()
	os.Exit(2)
}

var (
	skipTestFlag = flag.String("skip-test", "", "space-separated list of test-only targets to skip (only use if sufficient testing was done elsewhere)")
)

var (
	dryRun   bool                    // only perform pre-flight checks, only log to terminal
	skipTest = make(map[string]bool) // test-only targets that should be skipped
)

func main() {
	modeFlag := flag.String("mode", "", "release mode (prepare, release)")
	flag.BoolVar(&dryRun, "dry-run", false, "only perform pre-flight checks, only log to terminal")
	security := flag.Bool("security", false, "cut a security release from the internal Gerrit")
	flag.Usage = usage
	flag.Parse()
	if !releaseModes[*modeFlag] {
		fmt.Fprintln(os.Stderr, "need to provide a valid mode")
		usage()
	} else if *modeFlag == "mail-dl-cl" {
		mailDLCL()
		return
	} else if flag.NArg() != 1 {
		fmt.Fprintln(os.Stderr, "need to provide a release name")
		usage()
	}
	releaseVersion := flag.Arg(0)
	for _, target := range strings.Fields(*skipTestFlag) {
		if t, ok := releaseTarget(target, releaseVersion); !ok {
			fmt.Fprintf(os.Stderr, "target %q in -skip-test=%q is not a known target\n", target, *skipTestFlag)
			usage()
		} else if !t.TestOnly {
			fmt.Fprintf(os.Stderr, "%s is not a test-only target\n", target)
			usage()
		}
		skipTest[target] = true
	}

	http.DefaultTransport = newLogger(http.DefaultTransport)

	buildenv.CheckUserCredentials()
	checkForGitCodereview()
	loadMaintner()
	loadGomoteUser()
	loadGithubAuth()
	loadGCSAuth()

	w := &Work{
		Prepare:     *modeFlag == "prepare",
		Version:     releaseVersion,
		BetaRelease: strings.Contains(releaseVersion, "beta"),
		RCRelease:   strings.Contains(releaseVersion, "rc"),
		Security:    *security,
	}

	// Validate release version types.
	if w.BetaRelease {
		if w.Security {
			log.Fatalf("%s is a beta version, it cannot be a security release", w.Version)
		}
		w.ReleaseBranch = "master"
	} else if w.RCRelease {
		if w.Security {
			log.Fatalf("%s is a release candidate version, it cannot be a security release", w.Version)
		}
		shortRel := strings.Split(w.Version, "rc")[0]
		w.ReleaseBranch = "release-branch." + shortRel
	} else if strings.Count(w.Version, ".") == 1 {
		// Major release like "go1.X".
		if w.Security {
			log.Fatalf("%s is a major version, it cannot be a security release", w.Version)
		}
		w.ReleaseBranch = "release-branch." + w.Version
	} else if strings.Count(w.Version, ".") == 2 {
		// Minor release or security release like "go1.X.Y".
		shortRel := w.Version[:strings.LastIndex(w.Version, ".")]
		w.ReleaseBranch = "release-branch." + shortRel
		if w.Security {
			w.ReleaseBranch += "-security"
		}
	} else {
		log.Fatalf("cannot understand version %q", w.Version)
	}

	// Select release targets for this Go version.
	w.ReleaseTargets = matchTargets(w.Version)

	// Find milestones.
	var err error
	w.Milestone, err = getMilestone(w.Version)
	if err != nil {
		log.Fatalf("cannot find the GitHub milestone for release %s: %v", w.Version, err)
	}
	if !w.BetaRelease && !w.RCRelease {
		nextV, err := nextVersion(w.Version)
		if err != nil {
			log.Fatalln("nextVersion:", err)
		}
		w.NextMilestone, err = getMilestone(nextV)
		if err != nil {
			log.Fatalf("cannot find %s, the next GitHub milestone after release %s: %v", nextV, w.Version, err)
		}
	}
	// For major releases (go1.X), also check the "create first minor release milestone"
	// step in the release process wasn't accidentally missed. See issue 44404.
	if !w.BetaRelease && !w.RCRelease && strings.Count(w.Version, ".") == 1 {
		firstMinor := w.Version + ".1"
		if _, err := getMilestone(firstMinor); err != nil {
			log.Fatalf("cannot find %s, the first minor release GitHub milestone after major release %s: %v", firstMinor, w.Version, err)
		}
	}

	w.doRelease()
}

// mailDLCL parses command-line arguments for the mail-dl-cl mode,
// and runs it.
func mailDLCL() {
	if flag.NArg() != 1 && flag.NArg() != 2 {
		fmt.Fprintln(os.Stderr, "need to provide 1 or 2 versions")
		usage()
	}
	versions := flag.Args()

	fmt.Printf("About to create a golang.org/dl CL for the following Go versions:\n\n\t• %s\n\nOk? (Y/n) ", strings.Join(versions, "\n\t• "))
	if dryRun {
		fmt.Println("dry-run")
		return
	}
	var response string
	_, err := fmt.Scanln(&response)
	if err != nil {
		log.Fatalln(err)
	}
	if response != "Y" && response != "y" {
		log.Fatalln("stopped as requested")
	}
	changeURL, err := task.MailDLCL(context.Background(), versions)
	if err != nil {
		log.Fatalf(`task.MailDLCL(ctx, %#v) failed: %v

If it's neccessary to perform it manually as a workaround,
consider the following steps:

	git clone https://go.googlesource.com/dl && cd dl
	go run ./internal/genv goX.Y.Z goX.A.B
	git add .
	git commit -m "dl: add goX.Y.Z and goX.A.B"
	git codereview mail -trybot -trust

Discuss with the secondary release coordinator as needed.`, versions, err)
	}
	fmt.Printf("\nPlease review and submit %s\nand then refer to the playbook for the next steps.\n\n", changeURL)
}

// checkForGitCodereview exits the program if git-codereview is not installed
// in the user's path.
func checkForGitCodereview() {
	cmd := exec.Command("which", "git-codereview")
	if err := cmd.Run(); err != nil {
		log.Fatal("could not find git-codereivew: ", cmd.Args, ": ", err, "\n\n"+
			"Please install it via go install golang.org/x/review/git-codereview@latest\n"+
			"to use this program.")
	}
}

var gomoteUser string

func loadGomoteUser() {
	tokenPath := filepath.Join(os.Getenv("HOME"), ".config/gomote")
	files, _ := ioutil.ReadDir(tokenPath)
	for _, file := range files {
		if file.IsDir() {
			continue
		}
		name := file.Name()
		if strings.HasSuffix(name, ".token") && strings.HasPrefix(name, "user-") {
			gomoteUser = strings.TrimPrefix(strings.TrimSuffix(name, ".token"), "user-")
			return
		}
	}
	log.Fatal("missing gomote token - cannot build releases.\n**FIX**: Download https://build-dot-golang-org.appspot.com/key?builder=user-YOURNAME\nand store in ~/.config/gomote/user-YOURNAME.token")
}

// getMilestone returns the GitHub milestone corresponding to the specified version,
// or an error if it cannot be found.
func getMilestone(version string) (*maintner.GitHubMilestone, error) {
	// Pre-release versions of Go share the same milestone as the
	// release version, so trim the pre-release suffix, if any.
	if i := strings.Index(version, "beta"); i != -1 {
		version = version[:i]
	} else if i := strings.Index(version, "rc"); i != -1 {
		version = version[:i]
	}

	var found *maintner.GitHubMilestone
	goRepo.ForeachMilestone(func(m *maintner.GitHubMilestone) error {
		if strings.ToLower(m.Title) != version {
			return nil
		}
		found = m
		return errors.New("stop iteration")
	})
	if found == nil {
		return nil, fmt.Errorf("no milestone found for version %q", version)
	}
	return found, nil
}

func nextVersion(version string) (string, error) {
	parts := strings.Split(version, ".")
	n, err := strconv.Atoi(parts[len(parts)-1])
	if err != nil {
		return "", err
	}
	parts[len(parts)-1] = strconv.Itoa(n + 1)
	return strings.Join(parts, "."), nil
}

// Work collects all the work state for managing a particular release.
// The intent is that the code could be used in a setting where one program
// is managing multiple releases, although the current releasebot command line
// only accepts a single release.
type Work struct {
	logBuf *bytes.Buffer
	log    *log.Logger

	Prepare     bool // create the release commit and submit it for review
	BetaRelease bool
	RCRelease   bool
	Security    bool // cut a security release from the internal Gerrit

	ReleaseIssue   int    // Release status issue number
	ReleaseBranch  string // "master" for beta releases
	Dir            string // work directory ($HOME/go-releasebot-work/<release>)
	StagingDir     string // staging directory (a temporary directory inside <work>/release-staging)
	Errors         []string
	ReleaseBinary  string
	ReleaseTargets []Target // Selected release targets for this release.
	Version        string
	VersionCommit  string

	releaseMu   sync.Mutex
	ReleaseInfo map[string]*ReleaseInfo // map and info protected by releaseMu

	Milestone *maintner.GitHubMilestone // Milestone for the current release.
	// NextMilestone is the milestone of the next release of the same kind.
	// For major releases, it's the milestone of the next major release (e.g., 1.14 → 1.15).
	// For minor releases, it's the milestone of the next minor release (e.g., 1.14.1 → 1.14.2).
	// For other release types, it's unset.
	NextMilestone *maintner.GitHubMilestone
}

// ReleaseInfo describes a release build for a specific target.
type ReleaseInfo struct {
	Outputs []*ReleaseOutput
	Msg     string
}

// ReleaseOutput describes a single release file.
type ReleaseOutput struct {
	File   string
	Suffix string
	Link   string
	Error  string
}

// logError records an error.
// The error is always shown in the "PROBLEMS WITH RELEASE"
// section at the top of the status page.
// If cl is not nil, the error is also shown in that CL's summary.
func (w *Work) logError(msg string, a ...interface{}) {
	w.Errors = append(w.Errors, fmt.Sprintf(msg, a...))
}

// finally should be deferred at the top of each goroutine using a Work
// (as in "defer w.finally()"). It catches and logs panics and posts
// the log.
func (w *Work) finally() {
	if err := recover(); err != nil {
		w.log.Printf("\n\nPANIC: %v\n\n%s", err, debug.Stack())
	}
	w.postSummary()
}

type runner struct {
	w        *Work
	dir      string
	extraEnv []string
}

func (w *Work) runner(dir string, env ...string) *runner {
	return &runner{
		w:        w,
		dir:      dir,
		extraEnv: env,
	}
}

// run runs the command and requires that it succeeds.
// If not, it logs the failure and aborts the work.
// It logs the command line.
func (r *runner) run(args ...string) {
	out, err := r.runErr(args...)
	if err != nil {
		r.w.log.Printf("command failed: %s\n%s", err, out)
		panic("command failed")
	}
}

// runOut runs the command, requires that it succeeds,
// and returns the command's output.
// It does not log the command line except in case of failure.
// Not logging these commands avoids filling the log with
// runs of side-effect-free commands like "git cat-file commit HEAD".
func (r *runner) runOut(args ...string) []byte {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = r.dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		r.w.log.Printf("$ %s\n", strings.Join(args, " "))
		r.w.log.Printf("command failed: %s\n%s", err, out)
		panic("command failed")
	}
	return out
}

// runErr runs the given command and returns the output and status (error).
// It logs the command line.
func (r *runner) runErr(args ...string) ([]byte, error) {
	r.w.log.Printf("$ %s\n", strings.Join(args, " "))
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = r.dir
	if len(r.extraEnv) > 0 {
		cmd.Env = append(os.Environ(), r.extraEnv...)
	}
	return cmd.CombinedOutput()
}

func (w *Work) doRelease() {
	w.logBuf = new(bytes.Buffer)
	w.log = log.New(io.MultiWriter(os.Stdout, w.logBuf), "", log.LstdFlags)
	defer w.finally()

	w.log.Printf("starting")

	w.checkSpelling()
	w.gitCheckout()

	if !w.Security {
		w.mustIncludeSecurityBranch()
	}

	// In release mode we carry on even if the tag exists, in case we
	// need to resume a failed build.
	if w.Prepare && w.gitTagExists() {
		w.logError("%s tag already exists in Go repository!", w.Version)
		w.logError("**Found errors during release. Stopping!**")
		return
	}
	if w.BetaRelease || w.RCRelease {
		// TODO: go tool api -allow_new=false
		if strings.HasSuffix(w.Version, "beta1") {
			w.checkBeta1ReleaseBlockers()
		}
	} else {
		if !w.Security {
			w.checkReleaseBlockers()
		}
	}
	w.findOrCreateReleaseIssue()
	if len(w.Errors) > 0 && !dryRun {
		w.logError("**Found errors during release. Stopping!**")
		return
	}

	if w.Prepare {
		var changeID string
		if !w.BetaRelease {
			changeID = w.writeVersion()
		}

		// Create release archives and run all.bash tests on the builders.
		w.VersionCommit = w.gitHeadCommit()
		w.buildReleases()
		if len(w.Errors) > 0 {
			w.logError("**Found errors during release. Stopping!**")
			return
		}

		if w.BetaRelease {
			w.nextStepsBeta()
		} else {
			w.nextStepsPrepare(changeID)
		}
	} else {
		if !w.BetaRelease {
			w.checkVersion()
		}
		if len(w.Errors) > 0 {
			w.logError("**Found errors during release. Stopping!**")
			return
		}

		// Create and push the Git tag for the release, then create or reuse release archives.
		// (Tests are skipped here since they ran during the prepare mode.)
		w.gitTagVersion()
		w.buildReleases()
		if len(w.Errors) > 0 {
			w.logError("**Found errors during release. Stopping!**")
			return
		}

		switch {
		case !w.BetaRelease && !w.RCRelease:
			w.pushIssues()
			w.closeMilestone()
		case w.BetaRelease && strings.HasSuffix(w.Version, "beta1"):
			w.removeOkayAfterBeta1()
		}
		w.nextStepsRelease()
	}
}

func (w *Work) checkSpelling() {
	if w.Version != strings.ToLower(w.Version) {
		w.logError("release name should be lowercase: %q", w.Version)
	}
	if strings.Contains(w.Version, " ") {
		w.logError("release name should not contain any spaces: %q", w.Version)
	}
	if !strings.HasPrefix(w.Version, "go") {
		w.logError("release name should have 'go' prefix: %q", w.Version)
	}
}

func (w *Work) checkReleaseBlockers() {
	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
			return nil
		}
		if !gi.Closed && gi.HasLabel("release-blocker") {
			w.logError("open issue #%d is tagged release-blocker", gi.Number)
		}
		return nil
	}); err != nil {
		w.logError("error checking release-blockers: %v", err.Error())
		return
	}
}

func (w *Work) checkBeta1ReleaseBlockers() {
	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
			return nil
		}
		if !gi.Closed && gi.HasLabel("release-blocker") && !gi.HasLabel("okay-after-beta1") {
			w.logError("open issue #%d is tagged release-blocker and not okay after beta1", gi.Number)
		}
		return nil
	}); err != nil {
		w.logError("error checking release-blockers: %v", err.Error())
		return
	}
}

func (w *Work) nextStepsPrepare(changeID string) {
	if w.Security {
		w.log.Printf(`

The prepare stage has completed.

Please review and submit https://team-review.git.corp.google.com/q/%s
and then run the release stage.

`, changeID)
		return
	}

	w.log.Printf(`

The prepare stage has completed.

Please review and submit https://go-review.googlesource.com/q/%s
and then run the release stage.

`, changeID)
}

func (w *Work) nextStepsBeta() {
	w.log.Printf(`

The prepare stage has completed.

Please run the release stage next.

`)
}

func (w *Work) nextStepsRelease() {
	w.log.Printf(`

The release stage has completed. Thanks for riding with releasebot today!

Please refer to the playbook for the next steps.

`)
}

func (w *Work) postSummary() {
	var md bytes.Buffer

	if len(w.Errors) > 0 {
		fmt.Fprintf(&md, "## PROBLEMS WITH RELEASE\n\n")
		for _, e := range w.Errors {
			fmt.Fprintf(&md, "  - ")
			fmt.Fprintf(&md, "%s\n", strings.Replace(strings.TrimRight(e, "\n"), "\n", "\n    ", -1))
		}
	}

	if !w.Prepare {
		fmt.Fprintf(&md, "\n## Latest build: %s\n\n", mdEscape(w.Version))
		w.printReleaseTable(&md)
	}

	fmt.Fprintf(&md, "\n## Log\n\n    ")
	md.WriteString(strings.Replace(w.logBuf.String(), "\n", "\n    ", -1))
	fmt.Fprintf(&md, "\n\n")

	if len(w.Errors) > 0 {
		fmt.Fprintf(&md, "There were problems with the release, see above for details.\n")
	}

	body := md.String()
	fmt.Printf("%s", body)
	// Avoid the risk of leaking sensitive test failures on security releases.
	if dryRun || w.Security {
		return
	}

	// Ensure that the entire body can be posted to the issue by splitting it into multiple
	// GitHub comments if necessary. See golang.org/issue/45998.
	bodyParts := splitLogMessage(body, githubCommentCharacterLimit)
	for _, b := range bodyParts {
		err := postGithubComment(w.ReleaseIssue, b)
		if err != nil {
			fmt.Printf("error posting update comment: %v\n", err)
		}
	}
}

func (w *Work) printReleaseTable(md *bytes.Buffer) {
	// TODO: print sha256
	w.releaseMu.Lock()
	defer w.releaseMu.Unlock()
	for _, target := range w.ReleaseTargets {
		fmt.Fprintf(md, "- %s", mdEscape(target.Name))
		if target.TestOnly {
			fmt.Fprintf(md, " (test only)")
		}
		info := w.ReleaseInfo[target.Name]
		if info == nil {
			fmt.Fprintf(md, " - not started\n")
			continue
		}
		if len(info.Outputs) == 0 {
			fmt.Fprintf(md, " - not built")
		} else if target.TestOnly && len(info.Outputs) == 1 && info.Outputs[0].Suffix == "test-only" {
			fmt.Fprintf(md, " - ok")
		}
		for _, out := range info.Outputs {
			if out.Suffix == "test-only" {
				continue
			} else if out.Link != "" {
				fmt.Fprintf(md, " ([%s](%s))", mdEscape(out.Suffix), out.Link)
			} else {
				fmt.Fprintf(md, " (~~%s~~)", mdEscape(out.Suffix))
			}
		}
		fmt.Fprintf(md, "\n")
		if info.Msg != "" {
			fmt.Fprintf(md, "  - %s\n", strings.Replace(strings.TrimRight(info.Msg, "\n"), "\n", "\n    ", -1))
		}
	}
}

func (w *Work) writeVersion() (changeID string) {
	changeID = fmt.Sprintf("I%x", sha1.Sum([]byte(fmt.Sprintf("cmd/release-version-%s", w.Version))))

	err := ioutil.WriteFile(filepath.Join(w.Dir, "gitwork", "VERSION"), []byte(w.Version), 0666)
	if err != nil {
		w.log.Panic(err)
	}

	desc := w.Version + "\n\n"
	desc += "Change-Id: " + changeID + "\n"

	r := w.runner(filepath.Join(w.Dir, "gitwork"))
	r.run("git", "add", "VERSION")
	r.run("git", "commit", "-m", desc, "VERSION")
	if dryRun {
		fmt.Printf("\n### VERSION commit\n\n%s\n", r.runOut("git", "show", "HEAD"))
	} else if w.Security {
		r.run("git", "codereview", "mail")
	} else {
		r.run("git", "codereview", "mail", "-trybot", "-trust")
	}
	return
}

// checkVersion makes sure that the version commit has been submitted.
func (w *Work) checkVersion() {
	ver, err := ioutil.ReadFile(filepath.Join(w.Dir, "gitwork", "VERSION"))
	if err != nil {
		w.log.Panic(err)
	}
	if string(ver) != w.Version {
		w.logError("VERSION is %q; want %q. Did you run prepare and submit the CL?", string(ver), w.Version)
	}
}

func (w *Work) buildReleaseBinary() {
	gopath := filepath.Join(w.Dir, "gopath")
	r := w.runner(w.Dir, "GOPATH="+gopath, "GOBIN="+filepath.Join(gopath, "bin"))
	r.run("go", "clean", "-modcache")
	if err := os.RemoveAll(gopath); err != nil {
		w.log.Panic(err)
	}
	if err := os.MkdirAll(gopath, 0777); err != nil {
		w.log.Panic(err)
	}
	r.run("go", "install", "golang.org/x/build/cmd/release@latest")
	w.ReleaseBinary = filepath.Join(gopath, "bin/release")
}

func (w *Work) buildReleases() {
	w.buildReleaseBinary()
	if err := os.MkdirAll(filepath.Join(w.Dir, "release", w.VersionCommit), 0777); err != nil {
		w.log.Panic(err)
	}
	if err := os.MkdirAll(filepath.Join(w.Dir, "release-staging"), 0777); err != nil {
		w.log.Panic(err)
	}
	stagingDir, err := ioutil.TempDir(filepath.Join(w.Dir, "release-staging"), w.VersionCommit+"_")
	if err != nil {
		w.log.Panic(err)
	}
	w.StagingDir = stagingDir
	w.ReleaseInfo = make(map[string]*ReleaseInfo)

	if w.Security {
		fmt.Printf(`

Please download

	https://team.git.corp.google.com/golang/go-private/+archive/%s.tar.gz

to %s and press enter.
`, w.VersionCommit, filepath.Join(w.Dir, w.VersionCommit+".tar.gz"))

		_, err := fmt.Scanln()
		if err != nil {
			w.log.Panic(err)
		}
	}

	var wg sync.WaitGroup
	for _, target := range w.ReleaseTargets {
		w.releaseMu.Lock()
		w.ReleaseInfo[target.Name] = new(ReleaseInfo)
		w.releaseMu.Unlock()

		if target.TestOnly && skipTest[target.Name] {
			w.log.Printf("skipping test-only target %s because of -skip-test=%q flag", target.Name, *skipTestFlag)
			w.releaseMu.Lock()
			w.ReleaseInfo[target.Name].Msg = fmt.Sprintf("skipped because of -skip-test=%q flag", *skipTestFlag)
			w.releaseMu.Unlock()
			continue
		}

		wg.Add(1)
		target := target
		go func() {
			defer wg.Done()
			defer func() {
				if err := recover(); err != nil {
					stk := strings.TrimSpace(string(debug.Stack()))
					msg := fmt.Sprintf("PANIC: %v\n\n    %s\n", mdEscape(fmt.Sprint(err)), strings.Replace(stk, "\n", "\n    ", -1))
					w.logError(msg)
					w.log.Printf("\n\nBuilding %s: PANIC: %v\n\n%s", target.Name, err, debug.Stack())
					w.releaseMu.Lock()
					w.ReleaseInfo[target.Name].Msg = msg
					w.releaseMu.Unlock()
				}
			}()
			w.buildRelease(target)
		}()
	}
	wg.Wait()

	// Check for release errors and stop if any.
	w.releaseMu.Lock()
	for _, target := range w.ReleaseTargets {
		for _, out := range w.ReleaseInfo[target.Name].Outputs {
			if out.Error != "" || len(w.Errors) > 0 {
				w.logError("RELEASE BUILD FAILED\n")
				w.releaseMu.Unlock()
				return
			}
		}
	}
	w.releaseMu.Unlock()
}

// buildRelease builds the release packaging for a given target. Because the
// "release" program can be flaky, it tries multiple times before stopping.
// The release files are first written to a staging directory specified in w.StagingDir
// (a temporary directory inside $HOME/go-releasebot-work/go1.2.3/release-staging),
// then after the all.bash tests complete successfully (or get skipped),
// they get moved to the final release directory
// ($HOME/go-releasebot-work/go1.2.3/release/COMMIT_HASH).
//
// If files for the current version commit are already present in the release directory,
// they are reused instead of being rebuilt. In release mode, buildRelease then uploads
// the release packaging to the gs://golang-release-staging bucket, along with files
// containing the SHA256 hash of the releases, for eventual use by the download page.
func (w *Work) buildRelease(target Target) {
	log.Printf("BUILDRELEASE %s %s\n", w.Version, target.Name)
	defer log.Printf("DONE BUILDRELEASE %s %s\n", w.Version, target.Name)
	releaseDir := filepath.Join(w.Dir, "release", w.VersionCommit)
	prefix := fmt.Sprintf("%s.%s.", w.Version, target.Name)
	var files []string
	switch {
	case target.TestOnly:
		files = []string{prefix + "test-only"}
	case strings.HasPrefix(target.Name, "windows-"):
		files = []string{prefix + "zip", prefix + "msi"}
	default:
		files = []string{prefix + "tar.gz"}
	}
	var outs []*ReleaseOutput
	haveFiles := true
	for _, file := range files {
		out := &ReleaseOutput{
			File:   file,
			Suffix: strings.TrimPrefix(file, prefix),
		}
		outs = append(outs, out)
		_, err := os.Stat(filepath.Join(releaseDir, file))
		if err != nil {
			haveFiles = false
		}
	}
	w.releaseMu.Lock()
	w.ReleaseInfo[target.Name].Outputs = outs
	w.releaseMu.Unlock()

	if haveFiles {
		w.log.Printf("release -target=%q: already have %v; not rebuilding files", target.Name, files)
	} else {
		failures := 0
		for {
			args := []string{w.ReleaseBinary, "-target", target.Name, "-user", gomoteUser,
				"-version", w.Version, "-staging_dir", w.StagingDir}
			if w.Security {
				args = append(args, "-tarball", filepath.Join(w.Dir, w.VersionCommit+".tar.gz"))
			} else {
				args = append(args, "-rev", w.VersionCommit)
			}
			// 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.
			if !w.Prepare {
				args = append(args, "-skip_tests")
			}
			releaseOutput, releaseError := w.runner(releaseDir, "GOPATH="+filepath.Join(w.Dir, "gopath")).runErr(args...)
			// Exit code from release binary is apparently unreliable.
			// Look to see if the files we expected were created instead.
			failed := false
			w.releaseMu.Lock()
			for _, out := range outs {
				if _, err := os.Stat(filepath.Join(releaseDir, out.File)); err != nil {
					failed = true
				}
			}
			w.releaseMu.Unlock()
			if !failed {
				w.log.Printf("release -target=%q: build succeeded (after %d retries)\n", target.Name, failures)
				break
			}
			w.log.Printf("release -target=%q did not produce expected output files %v:\nerror from cmd/release binary = %v\noutput from cmd/release binary:\n%s", target.Name, files, releaseError, releaseOutput)
			if failures++; failures >= 3 {
				w.log.Printf("release -target=%q: too many failed attempts, stopping\n", target.Name)
				for _, out := range outs {
					w.releaseMu.Lock()
					out.Error = fmt.Sprintf("release -target=%q: build failed", target.Name)
					w.releaseMu.Unlock()
				}
				return
			}
			w.log.Printf("release -target=%q: waiting a bit and trying again\n", target.Name)
			time.Sleep(1 * time.Minute)
		}
	}

	if dryRun || w.Prepare {
		return
	}

	if target.TestOnly {
		// This was a test-only target, nothing to upload.
		return
	}

	for _, out := range outs {
		if err := w.uploadStagingRelease(target, out); err != nil {
			w.log.Printf("error uploading release %s to staging bucket: %s", target.Name, err)
			w.releaseMu.Lock()
			out.Error = err.Error()
			w.releaseMu.Unlock()
		}
	}
}

// uploadStagingRelease uploads target to the release staging bucket.
// If successful, it records the corresponding URL in out.Link.
// In addition to uploading target, it creates and uploads a file
// named "<target>.sha256" containing the hex sha256 hash
// of the target file. This is needed for the release signing process
// and also displayed on the eventual download page.
func (w *Work) uploadStagingRelease(target Target, out *ReleaseOutput) error {
	if dryRun {
		return errors.New("attempted write operation in dry-run mode")
	} else if target.TestOnly {
		return errors.New("attempted to upload a test-only target")
	}

	src := filepath.Join(w.Dir, "release", w.VersionCommit, out.File)
	h := sha256.New()
	f, err := os.Open(src)
	if err != nil {
		return err
	}
	_, err = io.Copy(h, f)
	f.Close()
	if err != nil {
		return err
	}
	if err := ioutil.WriteFile(src+".sha256", []byte(fmt.Sprintf("%x", h.Sum(nil))), 0666); err != nil {
		return err
	}

	dst := w.Version + "/" + out.File
	if err := gcsUpload(src, dst); err != nil {
		return err
	}
	if err := gcsUpload(src+".sha256", dst+".sha256"); err != nil {
		return err
	}

	w.releaseMu.Lock()
	out.Link = "https://" + releaseBucket + ".storage.googleapis.com/" + dst
	w.releaseMu.Unlock()
	return nil
}

// mustIncludeSecurityBranch remotely checks if there is an associated release branch
// for the current release. If one exists, it ensures that the HEAD commit in the latest
// security release branch exists within the current release branch. If the latest security
// branch has changes which have not been merged into the proposed release, it will exit
// fatally. If an asssociated security release branch does not exist, the function will
// return without doing the check. It assumes that if the security branch doesn't exist,
// it's because it was already merged everywhere and deleted.
func (w *Work) mustIncludeSecurityBranch() {
	securityReleaseBranch := fmt.Sprintf("%s-security", w.ReleaseBranch)

	sha, ok := w.gitRemoteBranchCommit(privateGoRepoURL, securityReleaseBranch)
	if !ok {
		w.log.Printf("an associated security release branch %q does not exist; assuming it has been merged and deleted, so proceeding as usual", securityReleaseBranch)
		return
	}

	if !w.gitCommitExistsInBranch(sha) {
		log.Fatalf("release branch does not contain security release HEAD commit %q; aborting", sha)
	}
}

// releaseTarget returns a release target with the specified name
// for the specified Go version.
func releaseTarget(name, goVer string) (_ Target, ok bool) {
	for _, t := range releaseTargets {
		if !match(t.GoQuery, goVer) {
			continue
		}
		if t.Name == name {
			return t, true
		}
	}
	return Target{}, false
}

// matchTargets selects release targets that have a matching
// GoQuery value for the specified Go version.
func matchTargets(goVer string) (matched []Target) {
	for _, t := range releaseTargets {
		if !match(t.GoQuery, goVer) {
			continue
		}
		matched = append(matched, t)
	}
	return matched
}

// match reports whether the Go version goVer matches the provided version query.
// The empty query matches all Go versions.
// match panics if given a query that it doesn't support.
func match(query, goVer string) bool {
	// TODO(golang.org/issue/40558): This should help inform the API for a Go version parser.
	switch query {
	case "": // A special case to make the zero Target.GoQuery value useful.
		return true
	case ">= go1.17beta1":
		return !strings.HasPrefix(goVer, "go1.16") && !strings.HasPrefix(goVer, "go1.15")
	case ">= go1.16beta1":
		return !strings.HasPrefix(goVer, "go1.15")
	default:
		panic(fmt.Errorf("match: query %q is not supported", query))
	}
}

// splitLogMessage splits a string into n number of strings of maximum size maxStrLen.
// It naively attempts to split the string along the bounderies of new line characters in order
// to make each individual string as readable as possible.
func splitLogMessage(s string, maxStrLen int) []string {
	sl := []string{}
	for len(s) > maxStrLen {
		end := strings.LastIndex(s[:maxStrLen], "\n")
		if end == -1 {
			end = maxStrLen
		}
		sl = append(sl, s[:end])

		if string(s[end]) == "\n" {
			s = s[end+1:]
		} else {
			s = s[end:]
		}
	}
	sl = append(sl, s)
	return sl
}
