// MungePullRequest is the workhorse the will actually make updates to the PR func (NeedsRebaseMunger) MungePullRequest(config *github_util.Config, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) { mergeable, err := config.IsPRMergeable(pr) if err != nil { glog.V(2).Infof("Skipping %d - problem determining mergeable", *pr.Number) return } if mergeable && github_util.HasLabel(issue.Labels, needsRebase) { config.RemoveLabel(*pr.Number, needsRebase) } if !mergeable && !github_util.HasLabel(issue.Labels, needsRebase) { config.AddLabels(*pr.Number, []string{needsRebase}) } }
// MungePullRequest is the workhorse the will actually make updates to the PR func (OkToTestMunger) MungePullRequest(config *github_util.Config, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) { if !github_util.HasLabel(issue.Labels, "lgtm") { return } status, err := config.GetStatus(pr, []string{"Jenkins GCE e2e"}) if err != nil { glog.Errorf("unexpected error getting status: %v", err) return } if status == "incomplete" { glog.V(2).Infof("status is incomplete, adding ok to test") msg := `@k8s-bot ok to test pr builder appears to be missing, activating due to 'lgtm' label.` config.WriteComment(*pr.Number, msg) } }
// MungePullRequest is the workhorse the will actually make updates to the PR func (p *PathLabelMunger) MungePullRequest(config *github_util.Config, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) { labelMap := *p.labelMap needsLabels := sets.NewString() for _, c := range commits { for _, f := range c.Files { for prefix, label := range labelMap { if strings.HasPrefix(*f.Filename, prefix) && !github_util.HasLabel(issue.Labels, label) { needsLabels.Insert(label) } } } } if needsLabels.Len() != 0 { config.AddLabels(*pr.Number, needsLabels.List()) } }
// MungePullRequest is the workhorse the will actually make updates to the PR func (LGTMAfterCommitMunger) MungePullRequest(config *github_util.Config, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) { if !github_util.HasLabel(issue.Labels, "lgtm") { return } lastModified := github_util.LastModifiedTime(commits) lgtmTime := github_util.LabelTime("lgtm", events) if lastModified == nil || lgtmTime == nil { glog.Errorf("PR %d unable to determine lastModified or lgtmTime", *pr.Number) return } if lastModified.After(*lgtmTime) { lgtmRemovedBody := "PR changed after LGTM, removing LGTM." if err := config.WriteComment(*pr.Number, lgtmRemovedBody); err != nil { return } config.RemoveLabel(*pr.Number, "lgtm") } }
// MungePullRequest is the workhorse the will actually make updates to the PR func (PingCIMunger) MungePullRequest(config *github_util.Config, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) { if !github_util.HasLabel(issue.Labels, "lgtm") { return } if mergeable, err := config.IsPRMergeable(pr); err != nil { glog.V(2).Infof("Skipping %d - problem determining mergeability", *pr.Number) } else if !mergeable { glog.V(2).Infof("Skipping %d - not mergeable", *pr.Number) } status, err := config.GetStatus(pr, []string{"Shippable", "continuous-integration/travis-ci/pr"}) if err != nil { glog.Errorf("unexpected error getting status: %v", err) return } if status == "incomplete" { glog.V(2).Infof("status is incomplete, closing and re-opening") msg := "Continuous integration appears to have missed, closing and re-opening to trigger it" config.WriteComment(*pr.Number, msg) config.ClosePR(pr) time.Sleep(5 * time.Second) config.OpenPR(pr, 10) } }
// MungePullRequest is the workhorse the will actually make updates to the PR func (sq *SubmitQueue) MungePullRequest(config *github_util.Config, pr *github_api.PullRequest, issue *github_api.Issue, commits []github_api.RepositoryCommit, events []github_api.IssueEvent) { e2e := sq.e2e userSet := sq.userWhitelist if !github_util.HasLabels(issue.Labels, []string{"cla: yes"}) { sq.SetPRStatus(pr, noCLA) return } if mergeable, err := config.IsPRMergeable(pr); err != nil { glog.V(2).Infof("Skipping %d - unable to determine mergeability", *pr.Number) sq.SetPRStatus(pr, undeterminedMergability) return } else if !mergeable { glog.V(4).Infof("Skipping %d - not mergable", *pr.Number) sq.SetPRStatus(pr, unmergeable) return } // Validate the status information for this PR contexts := sq.RequiredStatusContexts if len(sq.E2EStatusContext) > 0 && (len(sq.DontRequireE2ELabel) == 0 || !github_util.HasLabel(issue.Labels, sq.DontRequireE2ELabel)) { contexts = append(contexts, sq.E2EStatusContext) } if ok := config.IsStatusSuccess(pr, contexts); !ok { glog.Errorf("PR# %d Github CI status is not success", *pr.Number) sq.SetPRStatus(pr, ciFailure) return } if !github_util.HasLabel(issue.Labels, sq.WhitelistOverride) && !userSet.Has(*pr.User.Login) { glog.V(4).Infof("Dropping %d since %s isn't in whitelist and %s isn't present", *pr.Number, *pr.User.Login, sq.WhitelistOverride) if !github_util.HasLabel(issue.Labels, needsOKToMergeLabel) { config.AddLabels(*pr.Number, []string{needsOKToMergeLabel}) body := "The author of this PR is not in the whitelist for merge, can one of the admins add the 'ok-to-merge' label?" config.WriteComment(*pr.Number, body) } sq.SetPRStatus(pr, needsok) return } // Tidy up the issue list. if github_util.HasLabel(issue.Labels, needsOKToMergeLabel) { config.RemoveLabel(*pr.Number, needsOKToMergeLabel) } if !github_util.HasLabels(issue.Labels, []string{"lgtm"}) { sq.SetPRStatus(pr, noLGTM) return } lastModifiedTime := github_util.LastModifiedTime(commits) lgtmTime := github_util.LabelTime("lgtm", events) if lastModifiedTime == nil || lgtmTime == nil { glog.Errorf("PR %d was unable to determine when LGTM was added or when last modified", *pr.Number) sq.SetPRStatus(pr, unknown) return } if lastModifiedTime.After(*lgtmTime) { glog.V(4).Infof("PR %d changed after LGTM. Will not merge", *pr.Number) sq.SetPRStatus(pr, lgtmEarly) return } if !e2e.Stable() { sq.SetPRStatus(pr, e2eFailure) return } // if there is a 'e2e-not-required' label, just merge it. if len(sq.DontRequireE2ELabel) > 0 && github_util.HasLabel(issue.Labels, sq.DontRequireE2ELabel) { config.MergePR(pr, "submit-queue") sq.SetPRStatus(pr, merged) return } sq.SetPRStatus(pr, githube2e) sq.Lock() sq.githubE2ERequest <- true sq.needsGithubE2E[*pr.Number] = pr sq.Unlock() return }