// 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/envutil"
	"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:]...)
	envutil.SetDir(cmd, 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:]...)
	envutil.SetDir(cmd, r.dir)
	envutil.SetEnv(cmd, 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
}
