cmd/releasebot: remove okay-after-beta1 label after beta1 is released

The okay-after-beta1 label is used to mark that a given issue with
the release-blocker label for a given major release milestone is
okay to resolve after beta1. When the beta1 is released for that
milestone, by definition, all remaining issues with release-blocker
label must be okay to resolve after beta1 and will have the label
indicating that.

That means the okay-after-beta1 label loses its meaning after beta1
is released. Since it takes up visual space, automatically remove it
from all release-blocker issues in the same milestone, and open up
more room for a potential future "okay-after-rc1" label or so.

Modify pushIssues to match the release status issue by issue
number rather than by title (keeping golang/go#39371 in mind).
Also modify pushIssues and check{,Beta1}ReleaseBlockers to match
milestones by ID rather than by name. This is to be more robust.

Change-Id: If74654375253185cc5e6488d344ec7b2b5195011
Reviewed-on: https://go-review.googlesource.com/c/build/+/236260
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
diff --git a/cmd/releasebot/github.go b/cmd/releasebot/github.go
index 2d53949..50a3ccf 100644
--- a/cmd/releasebot/github.go
+++ b/cmd/releasebot/github.go
@@ -158,11 +158,12 @@
 		// Nothing to do.
 		return
 	}
+
 	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
-		if gi.Milestone == nil || gi.Milestone.Title != w.Milestone.Title {
+		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
 			return nil
 		}
-		if gi.Title == w.releaseStatusTitle() {
+		if gi.Number == int32(w.ReleaseIssue) {
 			return nil
 		}
 		// All issues are unrelated if this is a security release.
@@ -202,6 +203,38 @@
 
 }
 
+func (w *Work) removeOkayAfterBeta1() {
+	if !w.BetaRelease || !strings.HasSuffix(w.Version, "beta1") {
+		// Nothing to do.
+		return
+	}
+
+	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
+		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
+			return nil
+		}
+		if gi.Number == int32(w.ReleaseIssue) {
+			return nil
+		}
+		if gi.Closed || !gi.HasLabel("release-blocker") || !gi.HasLabel("okay-after-beta1") {
+			return nil
+		}
+		w.log.Printf("removing okay-after-beta1 label in issue %d", gi.Number)
+		if dryRun {
+			return nil
+		}
+		_, err := githubClient.Issues.RemoveLabelForIssue(context.Background(),
+			projectOwner, projectRepo, int(gi.Number), "okay-after-beta1")
+		if err != nil {
+			return fmt.Errorf("#%d: %s", gi.Number, err)
+		}
+		return nil
+	}); err != nil {
+		w.logError("error removing okay-after-beta1 label from issues in current milestone: %v", err)
+		return
+	}
+}
+
 func postGithubComment(number int, body string) error {
 	if dryRun {
 		return errors.New("attemted write operation in dry-run mode")
diff --git a/cmd/releasebot/main.go b/cmd/releasebot/main.go
index f9614e1..be6db5f 100644
--- a/cmd/releasebot/main.go
+++ b/cmd/releasebot/main.go
@@ -426,9 +426,12 @@
 			return
 		}
 
-		if !w.BetaRelease && !w.RCRelease {
+		switch {
+		case !w.BetaRelease && !w.RCRelease:
 			w.pushIssues()
 			w.closeMilestone()
+		case w.BetaRelease && strings.HasSuffix(w.Version, "beta1"):
+			w.removeOkayAfterBeta1()
 		}
 		w.nextStepsRelease()
 	}
@@ -448,7 +451,7 @@
 
 func (w *Work) checkReleaseBlockers() {
 	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
-		if gi.Milestone == nil || gi.Milestone.Title != w.Milestone.Title {
+		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
 			return nil
 		}
 		if !gi.Closed && gi.HasLabel("release-blocker") {
@@ -463,7 +466,7 @@
 
 func (w *Work) checkBeta1ReleaseBlockers() {
 	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
-		if gi.Milestone == nil || gi.Milestone.Title != w.Milestone.Title {
+		if gi.Milestone == nil || gi.Milestone.ID != w.Milestone.ID {
 			return nil
 		}
 		if !gi.Closed && gi.HasLabel("release-blocker") && !gi.HasLabel("okay-after-beta1") {