зеркало из https://github.com/golang/build.git
cmd/releasebot: check that the security branch is merged into the release branch
The existing release process doesn't have any automated checks that ensure that the changes contained in the security release branch are in the newly created release branch. This change ensures that non-security releases contain the HEAD commit from the security release branch if such a branch exists. Fixes golang/go#34505 Change-Id: I03d000177ece16548d54b6d6ad7fb0969df3946e Reviewed-on: https://go-review.googlesource.com/c/build/+/206437 Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
Родитель
77c133b63e
Коммит
ef1c74c627
|
@ -11,6 +11,13 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// publicGoRepoURL contains the Gerrit repository URL.
|
||||
publicGoRepoURL = "https://go.googlesource.com/go"
|
||||
// privateGoRepoURL contains the internal repository URL.
|
||||
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).
|
||||
|
@ -25,9 +32,9 @@ func (w *Work) gitCheckout() {
|
|||
w.log.Panic(err)
|
||||
}
|
||||
|
||||
origin := "https://go.googlesource.com/go"
|
||||
origin := publicGoRepoURL
|
||||
if w.Security {
|
||||
origin = "sso://team/golang/go-private"
|
||||
origin = privateGoRepoURL
|
||||
}
|
||||
|
||||
// Check out a local mirror to work-mirror, to speed future checkouts for this point release.
|
||||
|
@ -47,12 +54,13 @@ func (w *Work) gitCheckout() {
|
|||
w.log.Panic(err)
|
||||
}
|
||||
w.runner(w.Dir).run("git", "clone", "--reference", mirror, "-b", w.ReleaseBranch, origin, gitDir)
|
||||
|
||||
r = w.runner(gitDir)
|
||||
r.run("git", "codereview", "change", "relwork")
|
||||
r.run("git", "config", "gc.auto", "0") // don't throw away refs we fetch
|
||||
}
|
||||
|
||||
// gitTagExists returns whether git git tag is already present in the repository.
|
||||
// gitTagExists returns whether a git tag is already present in the repository.
|
||||
func (w *Work) gitTagExists() bool {
|
||||
_, err := w.runner(filepath.Join(w.Dir, "gitwork")).runErr("git", "rev-parse", w.Version)
|
||||
return err == nil
|
||||
|
@ -97,3 +105,21 @@ func (w *Work) gitHeadCommit() string {
|
|||
out := r.runOut("git", "rev-parse", "HEAD")
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
// gitRemoteBranchCommit returns the hash of the HEAD commit on the branch located
|
||||
// on a remote repository. It will return false when the branch does not exist or there
|
||||
// is a problem communicating with the remote repository.
|
||||
func (w *Work) gitRemoteBranchCommit(repositoryURL, branch string) (string, bool) {
|
||||
out := w.runner(w.Dir).runOut("git", "ls-remote", "--heads", repositoryURL, "refs/heads/"+branch)
|
||||
if len(out) == 0 {
|
||||
return "", false
|
||||
}
|
||||
sha := strings.SplitN(string(out), "\t", 2)[0]
|
||||
return sha, true
|
||||
}
|
||||
|
||||
// gitCommitExistsInBranch reports whether the commit hash exists in the current branch.
|
||||
func (w *Work) gitCommitExistsInBranch(commitSHA string) bool {
|
||||
_, err := w.runner(filepath.Join(w.Dir, "gitwork")).runErr("git", "merge-base", "--is-ancestor", commitSHA, "HEAD")
|
||||
return err == nil
|
||||
}
|
||||
|
|
|
@ -79,7 +79,10 @@ func main() {
|
|||
|
||||
release := flag.Arg(0)
|
||||
|
||||
if strings.Contains(release, "beta") || strings.Contains(release, "rc") {
|
||||
isBeta := strings.Contains(release, "beta")
|
||||
isRC := strings.Contains(release, "rc")
|
||||
|
||||
if isBeta || isRC {
|
||||
if *security {
|
||||
log.Printf("error: only minor releases are supported in security mode")
|
||||
usage()
|
||||
|
@ -87,8 +90,8 @@ func main() {
|
|||
w := &Work{
|
||||
Prepare: *modeFlag == "prepare",
|
||||
Version: release,
|
||||
BetaRelease: strings.Contains(release, "beta"),
|
||||
RCRelease: strings.Contains(release, "rc"),
|
||||
BetaRelease: isBeta,
|
||||
RCRelease: isRC,
|
||||
}
|
||||
w.doRelease()
|
||||
return
|
||||
|
@ -299,9 +302,11 @@ func (w *Work) doRelease() {
|
|||
|
||||
if w.BetaRelease {
|
||||
w.ReleaseBranch = "master"
|
||||
|
||||
} else if w.RCRelease {
|
||||
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 {
|
||||
|
@ -327,6 +332,11 @@ func (w *Work) doRelease() {
|
|||
|
||||
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() {
|
||||
|
@ -819,3 +829,24 @@ func (w *Work) uploadStagingRelease(target string, out *ReleaseOutput) error {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче