// 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.
// It is a work in progress; right now it only handles beta and minor (point) releases,
// but eventually we want it to handle major releases too.
//
// Release process
//
//
package main

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

	"github.com/google/go-github/github"
	"golang.org/x/build/gerrit"
)

var releaseTargets = []string{
	"src",
	"linux-386",
	"linux-armv6l",
	"linux-amd64",
	"linux-arm64",
	"freebsd-386",
	"freebsd-amd64",
	"windows-386",
	"windows-amd64",
	"darwin-amd64",
	"linux-s390x",
	"linux-ppc64le",
}

var githubCherryPickApprovers = map[string]bool{
	"aclements":      true,
	"andybons":       true,
	"bradfitz":       true,
	"broady":         true,
	"ianlancetaylor": true,
	"rsc":            true,
}

var releaseModes = map[string]bool{
	"beta":              true,
	"release-candidate": true,
	"final":             true,
	"close-milestone":   true,
}

func usage() {
	fmt.Fprintln(os.Stderr, "usage: releasebot -mode [release mode] go1.8.5 go1.9.2 go1.10")
	fmt.Fprintln(os.Stderr, "Release modes:")
	fmt.Fprintln(os.Stderr)
	for m := range releaseModes {
		fmt.Fprintln(os.Stderr, m)
	}
	os.Exit(2)
}

func main() {
	modeFlag := flag.String("mode", "", "release mode (beta, release-candidate, final, close-milestone)")
	flag.Usage = usage
	flag.Parse()
	if *modeFlag == "" || !releaseModes[*modeFlag] || flag.NArg() == 0 {
		usage()
	}

	http.DefaultTransport = newLogger(http.DefaultTransport)

	checkForGitCodereview()
	loadGithubAuth()
	loadGerritAuth()
	loadGCSAuth()

	miles, err := loadMilestones()
	if err != nil {
		log.Fatal(err)
	}

	var wg sync.WaitGroup
Args:
	for _, release := range flag.Args() {
		for _, m := range miles {
			if strings.ToLower(m.GetTitle()) == release {
				w := &Work{Milestone: m}
				w.BetaRelease = *modeFlag == "beta"
				w.FinalRelease = *modeFlag == "final"
				w.CloseMilestone = *modeFlag == "close-milestone"
				w.setVersion(release)
				wg.Add(1)
				go func() {
					defer wg.Done()
					w.doRelease()
				}()
				continue Args
			}
		}
		log.Printf("cannot find release %s", release)
	}
	wg.Wait()
}

// 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 get golang.org/x/review/git-codereview\n"+
			"to use this program.")
	}
}

// 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
	runDir   string
	extraEnv []string

	BetaRelease    bool // this is the beta release; always cut from master
	FinalRelease   bool // this is the actual release
	CloseMilestone bool // release is done; close the issues and milestone

	Milestone     *github.Milestone // Github milestone
	ReleaseIssue  *github.Issue     // Release status issue
	ReleaseBranch string
	Picks         []*github.Issue // Issues marked cherry-pick-approved
	OtherIssues   []*github.Issue // Other issues
	Dir           string          // work directory
	CLs           []*CL
	Errors        []*Error
	ReleaseBinary string
	Version       string
	VersionCommit string
	VersionChange *gerrit.ChangeInfo

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

// 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
}

// A CL holds the state for a single CL that is to be copied into the release.
type CL struct {
	Num                 int
	Approver            string
	Gerrit              *gerrit.ChangeInfo
	Error               string
	Ref                 string
	Commit              string
	Title               string
	Order               int
	Issues              []int
	Prereq              []int
	ReleaseBranchCL     int
	ReleaseBranchGerrit *gerrit.ChangeInfo
	Errors              []*Error
}

// An Error is a problem to highlight on the status page.
type Error struct {
	CL  *CL
	Msg 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(cl *CL, msg string) {
	e := &Error{cl, msg}
	w.Errors = append(w.Errors, e)
	if cl != nil {
		cl.Errors = append(cl.Errors, e)
	}
}

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

// 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 (w *Work) run(args ...string) {
	out, err := w.runErr(args...)
	if err != nil {
		w.log.Printf("command failed: %s\n%s", err, out)
		panic("cmd")
	}
}

// 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 (w *Work) runOut(args ...string) []byte {
	cmd := exec.Command(args[0], args[1:]...)
	// Make Git editor a no-op so that git codereview submit -i does not pop up
	// an editor.
	cmd.Env = []string{"EDITOR=true"}
	cmd.Dir = w.runDir
	out, err := cmd.CombinedOutput()
	if err != nil {
		w.log.Printf("$ %s\n", strings.Join(args, " "))
		w.log.Printf("command failed: %s\n%s", err, out)
		panic("cmd")
	}
	return out
}

// runErr runs the given command and returns the output and status (error).
// It logs the command line.
// It retries certain known-flaky commands automatically.
func (w *Work) runErr(args ...string) ([]byte, error) {
	maxTry := 1
	try := 0
	// Gerrit sometimes returns 502 errors from git fetch
	if len(args) >= 2 && args[0] == "git" && args[1] == "fetch" {
		maxTry = 3
	}
Again:
	try++
	w.log.Printf("$ %s\n", strings.Join(args, " "))
	cmd := exec.Command(args[0], args[1:]...)
	// Make Git editor a no-op so that git codereview submit -i does not pop up
	// an editor.
	cmd.Env = append(os.Environ(), "EDITOR=true")
	cmd.Dir = w.runDir
	if len(w.extraEnv) > 0 {
		cmd.Env = append(cmd.Env, w.extraEnv...)
	}
	out, err := cmd.CombinedOutput()
	if err != nil && try < maxTry {
		goto Again
	}
	return out, err
}

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

	if w.Milestone.GetClosedIssues() > 0 {
		w.logError(nil, fmt.Sprintf("%s milestone has closed issues", w.Milestone.GetTitle()))
	}

	w.log.Printf("starting")

	w.gitCheckout()
	if w.BetaRelease {
		w.buildReleases()
		return
	}

	w.findIssues()
	w.findCLs()
	w.queryGerritCLs()

	if w.CloseMilestone {
		_, err := w.runErr("git", "rev-parse", w.Version)
		if err != nil {
			w.logError(nil, fmt.Sprintf("cannot close milestone: did not find %s tag in Git repo", w.Version))
			return
		}
		w.closeIssues()
		w.closeMilestone()
		w.updateSummary()
		return
	}

	w.gitFetchCLs()
	w.orderCLs()
	w.updateSummary()
	w.cherryPickCLs()
	w.checkDocs()
	w.updateSummary()
	if w.FinalRelease && len(w.Errors)+len(w.OtherIssues) > 0 {
		w.logError(nil, "**Found errors during final release. Stopping!**")
		return
	}
	w.writeVersion()
	if w.FinalRelease && len(w.Errors)+len(w.OtherIssues) > 0 {
		w.logError(nil, "**Found errors during final release. Stopping!**")
		return
	}
	w.updateSummary()
	w.buildReleases()
	w.updateSummary()
}

func (w *Work) updateSummary() {
	if w.BetaRelease {
		return
	}

	w.summary.Lock()
	defer w.summary.Unlock()

	// TODO: Show relevant issue labels.
	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, "  - ")
			if e.CL != nil {
				fmt.Fprintf(&md, "%s: ", mdChangeLink(e.CL.Num))
			}
			fmt.Fprintf(&md, "%s\n", strings.Replace(strings.TrimRight(e.Msg, "\n"), "\n", "\n    ", -1))
		}
	}

	if len(w.OtherIssues) > 0 {
		fmt.Fprintf(&md, "## ISSUES MISSING FIXES\n\n")
		for _, issue := range w.OtherIssues {
			fmt.Fprintf(&md, "  - #%d %s\n", issue.GetNumber(), mdEscape(issue.GetTitle()))
		}
	}

	fmt.Fprintf(&md, "\n## Issues with fixes\n\n")
	for _, issue := range w.Picks {
		fmt.Fprintf(&md, "  - #%d %s\n", issue.GetNumber(), mdEscape(issue.GetTitle()))
		for _, cl := range w.CLs {
			for _, n := range cl.Issues {
				if n == issue.GetNumber() {
					fmt.Fprintf(&md, "    - %s per %s; %s\n", mdChangeLink(cl.Num), cl.Approver, mdEscape(cl.Title))
				}
			}
		}
	}

	fmt.Fprintf(&md, "\n## Changes on release branch\n\n")
	for _, cl := range w.CLs {
		desc := ""
		if rcl := cl.ReleaseBranchCL; rcl == cl.Num {
			desc = mdChangeLink(rcl) + " (new for release-branch)"
		} else if rcl != 0 {
			desc = mdChangeLink(rcl) + " (cherry-pick of " + mdChangeLink(cl.Num) + ")"
		} else {
			desc = "**CL missing** for cherry-pick of " + mdChangeLink(cl.Num)
		}
		fmt.Fprintf(&md, "  - %s (for", desc)
		for _, n := range cl.Issues {
			fmt.Fprintf(&md, " #%d", n)
		}
		fmt.Fprintf(&md, ")\n")
		if cl.Title != "" {
			fmt.Fprintf(&md, "    - %s\n", mdEscape(cl.Title))
		}
		for _, e := range cl.Errors {
			fmt.Fprintf(&md, "    - **ERROR**: %s\n", strings.Replace(strings.TrimRight(e.Msg, "\n"), "\n", "\n      ", -1))
		}
	}

	if w.Version != "" && w.VersionChange != nil {
		fmt.Fprintf(&md, "\n## Latest build: %s\n", mdEscape(w.Version))
		fmt.Fprintf(&md, "\n    git fetch origin %s &&\n    git checkout %s\n\n", w.VersionChange.Revisions[w.VersionChange.CurrentRevision].Ref, w.VersionCommit)
		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")

	body := wrapStatus(w.Milestone, md.String())
	_, _, err := githubClient.Issues.Edit(context.TODO(), projectOwner, projectRepo, w.ReleaseIssue.GetNumber(), &github.IssueRequest{
		Body: &body,
	})
	if err != nil {
		fmt.Printf("updating issue: %v\n", err)
	}
}

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

func wrapStatus(m *github.Milestone, md string) string {
	return fmt.Sprintf("# %s release status\n\n%s\n%s", strings.Replace(m.GetTitle(), "Go", "Go ", -1), strings.TrimSpace(md), signature())
}

func signature() string {
	return fmt.Sprintf("\n— golang.org/x/build/cmd/releasebot, %v UTC\n", time.Now().UTC().Format(time.Stamp))
}

func (w *Work) checkDocs() {
	// Check that we've documented the release.
	version := strings.ToLower(w.Milestone.GetTitle())
	data, err := ioutil.ReadFile(filepath.Join(w.runDir, "../doc/devel/release.html"))
	if err != nil {
		w.log.Panic(err)
	}
	if !strings.Contains(string(data), "\n<p>\n"+version+" (released ") {
		w.logError(nil, "doc/devel/release.html does not document "+version)
	}
}

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

	version := strings.ToLower(w.Milestone.GetTitle())
	rc := ""

	haveExisting := false
	n := 0
	if change := w.findGerritChangeForReleaseBranch(changeID); change != nil {
		w.runOut("git", "fetch", "origin", change.Revisions[change.CurrentRevision].Ref)
		out, _ := w.runErr("git", "show", change.CurrentRevision+":VERSION")
		v := strings.TrimSpace(string(out))
		i := strings.Index(v, "rc")
		if i < 0 && !w.FinalRelease {
			w.log.Panic("bad existing VERSION " + v)
		}
		var n int
		var err error
		if i >= 0 {
			n, err = strconv.Atoi(v[i+2:])
			if err != nil {
				w.log.Panic("bad existing VERSION " + v)
			}
		}

		_, parent := w.treeAndParentOfCommit(change.CurrentRevision)
		for i := len(w.CLs) - 1; i >= 0; i-- {
			cl := w.CLs[i]
			if cl.ReleaseBranchGerrit != nil {
				if cl.ReleaseBranchGerrit.CurrentRevision == parent {
					haveExisting = true
					if !w.FinalRelease || n == 0 {
						w.log.Printf("reusing %s for VERSION", change.Revisions[change.CurrentRevision].Ref)
						w.run("git", "reset", "--hard", change.CurrentRevision)
						w.Version = v
						w.VersionCommit = change.CurrentRevision
						w.VersionChange = change
						w.CLs = append(w.CLs, &CL{
							Title:           version + rc,
							ReleaseBranchCL: change.ChangeNumber,
						})
						return
					}
				}
				break
			}
		}
	}
	n++
	rc = fmt.Sprintf("rc%d", n)

	if w.FinalRelease {
		if n-1 > 0 && !haveExisting {
			w.logError(nil, fmt.Sprintf("cannot issue final release - code has changed since %src%d", version, n-1))
			return
		}
		rc = ""
	}

	err := ioutil.WriteFile(filepath.Join(w.runDir, "../VERSION"), []byte(version+rc), 0666)
	if err != nil {
		w.log.Panic(err)
	}

	desc := version + "\n\n"
	if rc != "" {
		desc += "TESTING: " + version + rc + "\n\nDO NOT REVIEW\n\n"
	}
	desc += "Change-Id: " + changeID + "\n"

	w.run("git", "commit", "-m", desc, "../VERSION")
	w.run("git", "codereview", "mail", "-trybot", "HEAD")
	change := w.topGerritCL()
	w.CLs = append(w.CLs, &CL{
		Title:           version + rc,
		ReleaseBranchCL: change.ChangeNumber,
	})
	w.Version = version + rc
	w.VersionCommit = change.CurrentRevision
	w.VersionChange = change
}

func (w *Work) buildReleaseBinary() {
	gopath := filepath.Join(w.Dir, "gopath")
	if err := os.RemoveAll(gopath); err != nil {
		w.log.Panic(err)
	}
	if err := os.MkdirAll(gopath, 0777); err != nil {
		w.log.Panic(err)
	}
	w.extraEnv = append(w.extraEnv, "GOPATH="+gopath, "GOBIN="+filepath.Join(gopath, "bin"))
	w.run("go", "get", "golang.org/x/build/cmd/release")
	w.ReleaseBinary = filepath.Join(gopath, "bin/release")
}

func (w *Work) buildReleases() {
	token := filepath.Join(os.Getenv("HOME"), ".config/gomote/user-release.token")
	if _, err := os.Stat(token); err != nil {
		w.logError(nil, fmt.Sprintf("missing %s - cannot build releases.\n**FIX**: Download https://build-dot-golang-org.appspot.com/key?builder=user-release\nand store in %s", mdEscape(token), mdEscape(token)))
		return
	}

	w.buildReleaseBinary()
	if err := os.MkdirAll(filepath.Join(w.Dir, "release"), 0777); err != nil {
		w.log.Panic(err)
	}
	w.runDir = filepath.Join(w.Dir, "release")
	w.ReleaseInfo = make(map[string]*ReleaseInfo)

	var wg sync.WaitGroup
	for _, target := range releaseTargets {
		func() {
			w.releaseMu.Lock()
			defer w.releaseMu.Unlock()
			w.ReleaseInfo[target] = new(ReleaseInfo)
		}()

		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(nil, msg)
					w.log.Printf("\n\nBuilding %s: PANIC: %v\n\n%s", target, err, debug.Stack())
					w.releaseMu.Lock()
					w.ReleaseInfo[target].Msg = msg
					w.releaseMu.Unlock()
					w.updateSummary()
				}
			}()
			w.buildRelease(target)
		}()
	}
	wg.Wait()

	// Check for release errors and stop if any.
	if w.FinalRelease {
		w.releaseMu.Lock()
		for _, target := range releaseTargets {
			for _, out := range w.ReleaseInfo[target].Outputs {
				if out.Error != "" || len(w.Errors)+len(w.OtherIssues) > 0 {
					w.logError(nil, "RELEASE BUILD FAILED; NOT ISSUING RELEASE\n")
					w.releaseMu.Unlock()
					// Delete the release builds, in case we change something
					// before the next attempt. (For non-final releases, a change
					// would bump the release candidate number, but there's no
					// release candidate number here.)
					files, _ := filepath.Glob(filepath.Join(w.runDir, w.Version+".[a-z]*"))
					for _, f := range files {
						os.Remove(f)
					}
					return
				}
			}
		}
		w.releaseMu.Unlock()
		// TODO: Wait for Gerrit CL to have a +2?
		w.gitTagVersion()
		return
	}

	var md bytes.Buffer
	fmt.Fprintf(&md, "## %s pre-release distributions\n\n", w.Version)
	fmt.Fprintf(&md, "%s distributions are now available for testing:\n\n", w.Version)
	w.printReleaseTable(&md)
	md.WriteString(signature())

	if !w.BetaRelease {
		println("POSTING")
		com := findGithubComment(w.ReleaseIssue.GetNumber(), "## "+w.Version+" ")
		if com != nil {
			updateGithubComment(com, md.String())
		} else {
			postGithubComment(w.ReleaseIssue.GetNumber(), md.String())
		}
	}

	println("TAGGING")
	w.gitTagVersion()
}

// buildRelease builds the release packaging for a given target.
// Because the "release" program can be flaky, it tries up to five times.
// The release files are written to the current release directory
// ($HOME/go-releasebot-work/go1.2.3/release).
// If files for the current version are already present in that
// directory, they are reused instead of being rebuilt.
// 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 string) {
	log.Printf("BUILDRELEASE %s %s\n", w.Version, target)
	defer log.Printf("DONE BUILDRELEASE %s\n", target)
	prefix := fmt.Sprintf("%s.%s.", w.Version, target)
	var files []string
	switch {
	case strings.HasPrefix(target, "windows-"):
		files = []string{prefix + "zip", prefix + "msi"}
	case strings.HasPrefix(target, "darwin-"):
		files = []string{prefix + "tar.gz", prefix + "pkg"}
	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(w.runDir, file))
		if err != nil {
			haveFiles = false
		}
	}
	w.releaseMu.Lock()
	w.ReleaseInfo[target].Outputs = outs
	w.releaseMu.Unlock()

	if haveFiles {
		w.log.Printf("release %s: already have %v; not rebuilding files", target, files)
	} else {
		for failures := 0; ; {
			out, err := w.runErr(w.ReleaseBinary, "-target", target, "-user", "release", "-version", w.Version, "-rev", w.VersionCommit, "-tools", w.ReleaseBranch, "-net", w.ReleaseBranch)
			// 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(w.runDir, out.File)); err != nil {
					failed = true
				}
			}
			w.releaseMu.Unlock()
			if !failed {
				break
			}
			w.log.Printf("release %s: %s\n%s", target, err, out)
			if failures++; failures >= 3 {
				w.log.Printf("release %s: too many failures\n", target)
				for _, out := range outs {
					w.releaseMu.Lock()
					out.Error = fmt.Sprintf("release %s: build failed", target)
					w.releaseMu.Unlock()
				}
				return
			}
			w.updateSummary()
			time.Sleep(1 * time.Minute)
		}
	}

	for _, out := range outs {
		if err := w.uploadStagingRelease(target, out); err != nil {
			w.log.Printf("release %s: %s", target, 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 string, out *ReleaseOutput) error {
	src := filepath.Join(w.runDir, 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
}
