func (config *SubmitQueueConfig) handlePR(e2e *e2eTester, pr *github_api.PullRequest, issue *github_api.Issue) {
	if config.userWhitelist == nil {
		config.RefreshWhitelist()
	}
	userSet := config.userWhitelist

	if !github.HasLabel(issue.Labels, config.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, config.WhitelistOverride)
		if !github.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)
		}
		return
	}

	// Tidy up the issue list.
	if github.HasLabel(issue.Labels, NeedsOKToMergeLabel) {
		config.RemoveLabel(*pr.Number, NeedsOKToMergeLabel)
	}

	lastModifiedTime, err := config.LastModifiedTime(*pr.Number)
	if err != nil {
		glog.Errorf("Failed to get last modified time, skipping PR: %d", *pr.Number)
		return
	}
	if ok, err := config.validateLGTMAfterPush(pr, lastModifiedTime); err != nil {
		glog.Errorf("Error validating LGTM: %v, Skipping: %d", err, *pr.Number)
		return
	} else if !ok {
		glog.Errorf("PR pushed after LGTM, attempting to remove LGTM and skipping")
		staleLGTMBody := "LGTM was before last commit, removing LGTM"
		config.WriteComment(*pr.Number, staleLGTMBody)
		config.RemoveLabel(*pr.Number, "lgtm")
		return
	}

	if mergeable, err := config.IsPRMergeable(pr); err != nil {
		glog.V(2).Infof("Skipping %d - unable to determine mergeability", *pr.Number)
	} else if !mergeable {
		glog.V(2).Infof("Skipping %d - not mergable", *pr.Number)
	}

	// Validate the status information for this PR
	contexts := config.RequiredStatusContexts
	if len(config.DontRequireE2ELabel) == 0 || !github.HasLabel(issue.Labels, config.DontRequireE2ELabel) {
		contexts = append(contexts, config.E2EStatusContext)
	}
	if ok, err := config.ValidateStatus(*pr.Number, contexts, false); !ok || err != nil {
		glog.Errorf("Error validating PR status: %v", err)
		return
	}

	if err := e2e.runE2ETests(pr, issue); err != nil {
		glog.Errorf("Error running e2e test: %v", err)
		return
	}

	return
}
func (NeedsRebaseMunger) MungePullRequest(config *config.MungeConfig, 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})
	}
}
Beispiel #3
0
// This is called on a potentially mergeable PR
func (e *e2eTester) runE2ETests(pr *github_api.PullRequest, issue *github_api.Issue) error {
	e.locked(func() { e.state.CurrentPR = prInfo(pr) })
	defer e.locked(func() { e.state.CurrentPR = nil })
	e.msg("Considering PR %d", *pr.Number)

	e.waitForStableBuilds()

	// if there is a 'e2e-not-required' label, just merge it.
	if len(e.Config.DontRequireE2ELabel) > 0 && github_util.HasLabel(issue.Labels, e.Config.DontRequireE2ELabel) {
		e.msg("Merging %d since %s is set", *pr.Number, e.Config.DontRequireE2ELabel)
		return e.Config.MergePR(*pr.Number, "submit-queue")
	}

	body := "@k8s-bot test this [submit-queue is verifying that this PR is safe to merge]"
	if err := e.Config.WriteComment(*pr.Number, body); err != nil {
		e.error(err)
		return err
	}

	// Wait for the build to start
	err := e.Config.WaitForPending(*pr.Number)

	// Wait for the status to go back to 'success'
	ok, err := e.Config.ValidateStatus(*pr.Number, []string{}, true)
	if err != nil {
		e.error(err)
		return err
	}
	if !ok {
		e.msg("Status after build is not 'success', skipping PR %d", *pr.Number)
		return nil
	}
	return e.Config.MergePR(*pr.Number, "submit-queue")
}
Beispiel #4
0
func (OkToTestMunger) MungePullRequest(config *config.MungeConfig, 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.Number, []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)
	}
}
Beispiel #5
0
// MungePullRequest is the workhorse the will actually make updates to the PR
func (LGTMAfterCommitMunger) MungePullRequest(config *config.MungeConfig, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) {
	lastModified := lastModifiedTime(commits)
	lgtmTime := lgtmTime(events)

	if lastModified == nil || lgtmTime == nil {
		return
	}

	if !github_util.HasLabel(issue.Labels, "lgtm") {
		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")
	}
}
Beispiel #6
0
// MungePullRequest is the workhorse the will actually make updates to the PR
func (p *PathLabelMunger) MungePullRequest(config *config.MungeConfig, pr *github.PullRequest, issue *github.Issue, commits []github.RepositoryCommit, events []github.IssueEvent) {
	if p.labelMap == nil {
		if err := p.loadPathMap(); err != nil {
			return
		}
	}
	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())
	}
}
Beispiel #7
0
func (PingCIMunger) MungePullRequest(config *config.MungeConfig, 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)
	}
}