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