Exemple #1
0
// Munge is the workhorse the will actually make updates to the PR
func (LGTMAfterCommitMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}

	lastModified := obj.LastModifiedTime()
	lgtmTime := obj.LabelTime(lgtmLabel)

	if lastModified == nil || lgtmTime == nil {
		glog.Errorf("PR %d unable to determine lastModified or lgtmTime", *obj.Issue.Number)
		return
	}

	if lastModified.After(*lgtmTime) {
		glog.Infof("PR: %d lgtm:%s  lastModified:%s", *obj.Issue.Number, lgtmTime.String(), lastModified.String())
		body := fmt.Sprintf(lgtmRemovedBody, mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join())
		if err := obj.WriteComment(body); err != nil {
			return
		}
		obj.RemoveLabel(lgtmLabel)
	}
}
Exemple #2
0
// Munge is the workhorse the will actually make updates to the PR
func (r *RebuildMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	comments, err := obj.ListComments()
	if err != nil {
		glog.Errorf("unexpected error getting comments: %v", err)
	}

	for ix := range comments {
		comment := comments[ix]
		// Skip all robot comments
		if r.robots.Has(*comment.User.Login) {
			glog.V(4).Infof("Skipping comment by robot %s: %s", *comment.User.Login, *comment.Body)
			continue
		}
		if isRebuildComment(comment) && rebuildCommentMissingIssueNumber(comment) {
			if err := obj.DeleteComment(comment); err != nil {
				glog.Errorf("Error deleting comment: %v", err)
				continue
			}
			body := fmt.Sprintf(rebuildFormat, *comment.User.Login)
			err := obj.WriteComment(body)
			if err != nil {
				glog.Errorf("unexpected error adding comment: %v", err)
				continue
			}
		}
	}
}
Exemple #3
0
// Munge is the workhorse the will actually make updates to the PR
func (r *ReleaseNoteLabel) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if completedReleaseNoteProcess(obj) {
		r.ensureNoRelNoteNeededLabel(obj)
		return
	}

	if !r.prMustFollowRelNoteProcess(obj) {
		r.ensureNoRelNoteNeededLabel(obj)
		return
	}

	if !obj.HasLabel(releaseNoteLabelNeeded) {
		obj.AddLabel(releaseNoteLabelNeeded)
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}

	obj.WriteComment(releaseNoteBody)
	obj.RemoveLabel(lgtmLabel)
}
Exemple #4
0
// Munge is the workhorse the will actually make updates to the PR
func (b *BlockPath) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(doNotMergeLabel) {
		return
	}

	files, err := obj.ListFiles()
	if err != nil {
		return
	}

	for _, f := range files {
		if matchesAny(*f.Filename, b.blockRegexp) {
			if matchesAny(*f.Filename, b.doNotBlockRegexp) {
				continue
			}
			obj.WriteComment(blockPathBody)
			obj.AddLabels([]string{doNotMergeLabel})
			return
		}
	}
}
Exemple #5
0
func (r *ReleaseNoteLabel) prMustFollowRelNoteProcess(obj *github.MungeObject) bool {
	if obj.IsForBranch("master") {
		return true
	}

	parents := getCherrypickParentPRs(obj, r.config)
	// if it has no parents it needs to follow the release note process
	if len(parents) == 0 {
		return true
	}

	for _, parent := range parents {
		// If the parent didn't set a release note, the CP must
		if !parent.HasLabel(releaseNote) &&
			!parent.HasLabel(releaseNoteActionRequired) {
			if !obj.HasLabel(releaseNoteLabelNeeded) {
				obj.WriteComment(parentReleaseNoteBody)
			}
			return true
		}
	}
	// All of the parents set the releaseNote or releaseNoteActionRequired label,
	// so this cherrypick PR needs to do nothing.
	return false
}
Exemple #6
0
// Munge is the workhorse the will actually make updates to the PR
func (b *BlockPath) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(doNotMergeLabel) {
		return
	}

	commits, err := obj.GetCommits()
	if err != nil {
		return
	}

	for _, c := range commits {
		for _, f := range c.Files {
			if matchesAny(*f.Filename, b.blockRegexp) {
				if matchesAny(*f.Filename, b.doNotBlockRegexp) {
					continue
				}
				body := fmt.Sprintf(`Adding label:%s because PR changes docs prohibited to auto merge
See http://kubernetes.io/editdocs/ for information about editing docs`, doNotMergeLabel)
				obj.WriteComment(body)
				obj.AddLabels([]string{doNotMergeLabel})
				return
			}
		}
	}
}
Exemple #7
0
// Munge is the workhorse the will actually make updates to the PR
func (StaleGreenCI) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}

	if mergeable, err := obj.IsMergeable(); !mergeable || err != nil {
		return
	}

	if !obj.IsStatusSuccess(requiredContexts) {
		return
	}

	for _, context := range requiredContexts {
		statusTime := obj.GetStatusTime(context)
		if statusTime == nil {
			glog.Errorf("%d: unable to determine time %q context was set", *obj.Issue.Number, context)
			return
		}
		if time.Since(*statusTime) > staleGreenCIHours*time.Hour {
			obj.WriteComment(greenMsgBody)
			err := obj.WaitForPending(requiredContexts)
			if err != nil {
				glog.Errorf("Failed waiting for PR to start testing: %v", err)
			}
			return
		}
	}
}
// Munge is the workhorse the will actually make updates to the PR
func (NagFlakeIssues) Munge(obj *mgh.MungeObject) {
	if obj.IsPR() || !obj.HasLabel("kind/flake") {
		return
	}

	comments, err := obj.ListComments()
	if err != nil {
		glog.Error(err)
		return
	}

	// Use the pinger to notify assignees:
	// - Set time period based on configuration (at the top of this file)
	// - Mention list of assignees as an argument
	// - Start the ping timer after the last HumanActor comment

	// How often should we ping
	period := findTimePeriod(obj.Issue.Labels)

	// Who are we pinging
	who := mungerutil.GetIssueUsers(obj.Issue).Assignees.Mention().Join()

	// When does the pinger start
	startDate := c.LastComment(comments, c.HumanActor(), obj.Issue.CreatedAt)

	// Get a notification if it's time to ping.
	notif := pinger.SetTimePeriod(period).PingNotification(
		comments,
		who,
		startDate,
	)
	if notif != nil {
		obj.WriteComment(notif.String())
	}
}
Exemple #9
0
// Munge is the workhorse the will actually make updates to the PR
func (LGTMAfterCommitMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel("lgtm") {
		return
	}

	lastModified := obj.LastModifiedTime()
	lgtmTime := obj.LabelTime("lgtm")

	if lastModified == nil || lgtmTime == nil {
		glog.Errorf("PR %d unable to determine lastModified or lgtmTime", *obj.Issue.Number)
		return
	}

	if lastModified.After(*lgtmTime) {
		glog.Infof("PR: %d lgtm:%s  lastModified:%s", *obj.Issue.Number, lgtmTime.String(), lastModified.String())
		lgtmRemovedBody := "PR changed after LGTM, removing LGTM."
		if err := obj.WriteComment(lgtmRemovedBody); err != nil {
			return
		}
		obj.RemoveLabel("lgtm")
	}
}
Exemple #10
0
// Munge is the workhorse the will actually make updates to the PR
func (PingCIMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel("lgtm") {
		return
	}
	mergeable, err := obj.IsMergeable()
	if err != nil {
		glog.V(2).Infof("Skipping %d - problem determining mergeability", *obj.Issue.Number)
		return
	}
	if !mergeable {
		glog.V(2).Infof("Skipping %d - not mergeable", *obj.Issue.Number)
		return
	}
	if state := obj.GetStatusState([]string{jenkinsCIContext, travisContext}); state != "incomplete" {
		glog.V(2).Info("Have %s status - skipping ping CI", jenkinsCIContext)
		return
	}
	state := obj.GetStatusState([]string{shippableContext, travisContext})
	if state == "incomplete" {
		msg := "Continuous integration appears to have missed, closing and re-opening to trigger it"
		obj.WriteComment(msg)

		obj.ClosePR()
		time.Sleep(5 * time.Second)
		obj.OpenPR(10)
	}
}
Exemple #11
0
// Munge is the workhorse the will actually make updates to the PR
func (StalePendingCI) Munge(obj *github.MungeObject) {
	requiredContexts := []string{jenkinsUnitContext, jenkinsE2EContext}

	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}

	if mergeable, err := obj.IsMergeable(); !mergeable || err != nil {
		return
	}

	status := obj.GetStatusState(requiredContexts)
	if status != "pending" {
		return
	}

	for _, context := range requiredContexts {
		statusTime := obj.GetStatusTime(context)
		if statusTime == nil {
			glog.Errorf("%d: unable to determine time %q context was set", *obj.Issue.Number, context)
			return
		}
		if time.Since(*statusTime) > stalePendingCIHours*time.Hour {
			obj.WriteComment(pendingMsgBody)
			return
		}
	}
}
Exemple #12
0
// Munge is the workhorse the will actually make updates to the PR
func (s *SizeMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	issue := obj.Issue

	s.getGeneratedFiles(obj)
	genFiles := *s.genFiles
	genPrefixes := *s.genPrefixes

	files, err := obj.ListFiles()
	if err != nil {
		return
	}

	adds := 0
	dels := 0
	for _, f := range files {
		skip := false
		for _, p := range genPrefixes {
			if strings.HasPrefix(*f.Filename, p) {
				skip = true
				break
			}
		}
		if skip {
			continue
		}
		if genFiles.Has(*f.Filename) {
			continue
		}
		if f.Additions != nil {
			adds += *f.Additions
		}
		if f.Deletions != nil {
			dels += *f.Deletions
		}
	}

	newSize := calculateSize(adds, dels)
	newLabel := labelSizePrefix + newSize

	existing := github.GetLabelsWithPrefix(issue.Labels, labelSizePrefix)
	needsUpdate := true
	for _, l := range existing {
		if l == newLabel {
			needsUpdate = false
			continue
		}
		obj.RemoveLabel(l)
	}
	if needsUpdate {
		obj.AddLabels([]string{newLabel})

		body := fmt.Sprintf("Labelling this PR as %s", newLabel)
		obj.WriteComment(body)
	}
}
func (sq *SubmitQueue) doGithubE2EAndMerge(obj *github.MungeObject) {
	err := obj.Refresh()
	if err != nil {
		glog.Errorf("%d: unknown err: %v", *obj.Issue.Number, err)
		sq.SetMergeStatus(obj, unknown)
		return
	}

	if !sq.validForMerge(obj) {
		return
	}

	if obj.HasLabel(e2eNotRequiredLabel) {
		obj.MergePR("submit-queue")
		sq.SetMergeStatus(obj, merged)
		return
	}

	if err := obj.WriteComment(verifySafeToMergeBody); err != nil {
		glog.Errorf("%d: unknown err: %v", *obj.Issue.Number, err)
		sq.SetMergeStatus(obj, unknown)
		return
	}

	// Wait for the build to start
	sq.SetMergeStatus(obj, ghE2EWaitingStart)
	err = obj.WaitForPending([]string{sq.E2EStatusContext, sq.UnitStatusContext})
	if err != nil {
		s := fmt.Sprintf("Failed waiting for PR to start testing: %v", err)
		sq.SetMergeStatus(obj, s)
		return
	}

	// Wait for the status to go back to something other than pending
	sq.SetMergeStatus(obj, ghE2ERunning)
	err = obj.WaitForNotPending([]string{sq.E2EStatusContext, sq.UnitStatusContext})
	if err != nil {
		s := fmt.Sprintf("Failed waiting for PR to finish testing: %v", err)
		sq.SetMergeStatus(obj, s)
		return
	}

	// Check if the thing we care about is success
	if ok := obj.IsStatusSuccess([]string{sq.E2EStatusContext, sq.UnitStatusContext}); !ok {
		sq.SetMergeStatus(obj, ghE2EFailed)
		return
	}

	if !sq.e2eStable() {
		sq.SetMergeStatus(obj, e2eFailure)
		return
	}

	obj.MergePR("submit-queue")
	sq.updateMergeRate()
	sq.SetMergeStatus(obj, merged)
	return
}
Exemple #14
0
// Munge is unused by this munger.
func (cla *ClaMunger) Munge(obj *githubhelper.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(claHumanLabel) {
		return
	}

	status := obj.GetStatusState([]string{cla.CLAStatusContext})

	// Check for pending status and exit.
	if status == contextPending {
		// do nothing and wait for state to be updated.
		return
	}

	if status == contextSuccess {
		if obj.HasLabel(cncfClaYesLabel) {
			// status is success and we've already applied 'cncf-cla: yes'.
			return
		}
		if obj.HasLabel(cncfClaNoLabel) {
			obj.RemoveLabel(cncfClaNoLabel)
		}
		obj.AddLabel(cncfClaYesLabel)
		return
	}

	// If we are here, that means that the context is failure/error.
	comments, err := obj.ListComments()
	if err != nil {
		glog.Error(err)
		return
	}
	who := mungerutil.GetIssueUsers(obj.Issue).Author.Mention().Join()

	// Get a notification if it's time to ping.
	notif := cla.pinger.PingNotification(
		comments,
		who,
		nil,
	)
	if notif != nil {
		obj.WriteComment(notif.String())
	}

	if obj.HasLabel(cncfClaNoLabel) {
		// status reported error/failure and we've already applied 'cncf-cla: no' label.
		return
	}

	if obj.HasLabel(cncfClaYesLabel) {
		obj.RemoveLabel(cncfClaYesLabel)
	}
	obj.AddLabel(cncfClaNoLabel)
}
Exemple #15
0
func closePullRequest(obj *github.MungeObject, inactiveFor time.Duration) {
	comment := findLatestWarningComment(obj)
	if comment != nil {
		obj.DeleteComment(comment)
	}

	obj.WriteComment(fmt.Sprintf(closingComment, durationToDays(inactiveFor)))
	obj.ClosePR()
}
func handleFound(obj *github.MungeObject, gitMsg []byte, branch string) error {
	msg := string(gitMsg)
	o := strings.SplitN(msg, "\n", 2)
	sha := o[0]
	msg = fmt.Sprintf("Commit %s found in the %q branch appears to be this PR. Removing the %q label. If this s an error find help to get your PR picked.", sha, branch, cpCandidateLabel)
	obj.WriteComment(msg)
	obj.RemoveLabel(cpCandidateLabel)
	return nil
}
Exemple #17
0
// Munge is the workhorse the will actually make updates to the PR
func (OkToTestMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}
	state := obj.GetStatusState(requiredContexts)
	if state == "incomplete" {
		glog.V(2).Infof("status is incomplete, adding ok to test")
		obj.WriteComment(okToTestBody)
	}
}
func closePullRequest(obj *github.MungeObject, inactiveFor time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	comment := findLatestWarningComment(obj)
	if comment != nil {
		obj.DeleteComment(comment)
	}

	obj.WriteComment(fmt.Sprintf(closingComment, durationToDays(inactiveFor), mention))
	obj.ClosePR()
}
Exemple #19
0
func postWarningComment(obj *github.MungeObject, inactiveFor time.Duration, closeIn time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	closeDate := time.Now().Add(closeIn).Format("Jan 2, 2006")

	obj.WriteComment(fmt.Sprintf(
		warningComment,
		durationToDays(inactiveFor),
		durationToDays(closeIn),
		closeDate,
		mention,
	))
}
// Munge is the workhorse the will actually make updates to the PR
func (PickMustHaveMilestone) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}
	if !obj.HasLabel(cpCandidateLabel) {
		return
	}

	releaseMilestone := obj.ReleaseMilestone()
	hasLabel := obj.HasLabel(cpCandidateLabel)

	if hasLabel && releaseMilestone == "" {
		obj.WriteComment(pickMustHaveMilestoneBody)
		obj.RemoveLabel(cpCandidateLabel)
	}
}
Exemple #21
0
// Munge is the workhorse the will actually make updates to the PR
func (OkToTestMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if !obj.HasLabel("lgtm") {
		return
	}
	state := obj.GetStatusState([]string{"Jenkins GCE e2e"})
	if state == "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.`
		obj.WriteComment(msg)
	}
}
// Munge is the workhorse the will actually make updates to the PR
func (PickMustHaveMilestone) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}
	if !obj.HasLabel(cpCandidateLabel) {
		return
	}

	releaseMilestone := obj.ReleaseMilestone()
	hasLabel := obj.HasLabel(cpCandidateLabel)

	if hasLabel && releaseMilestone == "" {
		msg := fmt.Sprintf("Removing label `%s` because no release milestone was set. This is an invalid state and thus this PR is not being considered for cherry-pick to any release branch. Please add an appropriate release milestone and then re-add the label.", cpCandidateLabel)
		obj.WriteComment(msg)
		obj.RemoveLabel(cpCandidateLabel)
	}
}
Exemple #23
0
// Munge is unused by this munger.
func (c *ClaMunger) Munge(obj *githubhelper.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(claHumanLabel) {
		return
	}

	status := obj.GetStatusState([]string{c.CLAStatusContext})

	// Check for pending status and exit.
	if status == contextPending {
		// do nothing and wait for state to be updated.
		return
	}

	if status == contextSuccess {
		if obj.HasLabel(cncfClaYesLabel) {
			// status is success and we've already applied 'cncf-cla: yes'.
			return
		}
		if obj.HasLabel(cncfClaNoLabel) {
			obj.RemoveLabel(cncfClaNoLabel)
		}
		obj.AddLabel(cncfClaYesLabel)
		return
	}

	if obj.HasLabel(cncfClaNoLabel) {
		// status reported error/failure and we've already applied 'cncf-cla: no' label.
		return
	}

	// Write comment and then modify the labels.
	err := obj.WriteComment(fmt.Sprint(cncfclaNotFoundMessage, mungerutil.GetIssueUsers(obj.Issue).Author.Mention().Join()))
	if err != nil {
		return
	}

	if obj.HasLabel(cncfClaYesLabel) {
		obj.RemoveLabel(cncfClaYesLabel)
	}
	obj.AddLabel(cncfClaNoLabel)
}
// Munge is the workhorse the will actually make updates to the PR
func (LabelUnapprovedPicks) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.IsForBranch("master") {
		return
	}

	if obj.HasLabel(cpApprovedLabel) {
		return
	}

	obj.AddLabel(doNotMergeLabel)

	msg := fmt.Sprintf("This PR is not for the master branch but does not have the `%s` label. Adding the `%s` label.", cpApprovedLabel, doNotMergeLabel)
	obj.WriteComment(msg)
}
Exemple #25
0
// updateIssue adds a comment about the item to the github object.
func (s *IssueSyncer) updateIssue(obj *github.MungeObject, source IssueSource) error {
	body := source.Body(false)
	id := source.ID()
	if !strings.Contains(body, source.ID()) {
		// prevent making tons of duplicate comments
		panic(fmt.Errorf("Programmer error: %v does not contain %v!", body, id))
	}
	glog.Infof("Updating issue %v with item %v", *obj.Issue.Number, source.ID())
	if err := obj.WriteComment(body); err != nil {
		return err
	}
	p, err := source.Priority(obj)
	if err != nil {
		return err
	}
	return s.syncPriority(obj, p)

}
// Munge is the workhorse the will actually make updates to the PR
func (LabelUnapprovedPicks) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.IsForBranch("master") {
		return
	}

	if obj.HasLabel(cpApprovedLabel) {
		return
	}

	if obj.HasLabel(doNotMergeLabel) {
		return
	}

	obj.AddLabel(doNotMergeLabel)

	obj.WriteComment(labelUnapprovedBody)
}
Exemple #27
0
// Munge is the workhorse the will actually make updates to the PR
func (r *ReleaseNoteLabel) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if releaseNoteAlreadyAdded(obj) {
		r.ensureNoRelNoteNeededLabel(obj)
		return
	}

	if !r.prMustFollowRelNoteProcess(obj) {
		r.ensureNoRelNoteNeededLabel(obj)
		return
	}

	labelToAdd := determineReleaseNoteLabel(obj)
	if labelToAdd != releaseNoteLabelNeeded {
		//going to apply some other release-note-label
		if obj.HasLabel(releaseNoteLabelNeeded) {
			obj.RemoveLabel(releaseNoteLabelNeeded)
		}
		obj.AddLabel(labelToAdd)
		return
	}

	if !obj.HasLabel(releaseNoteLabelNeeded) {
		obj.AddLabel(releaseNoteLabelNeeded)
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}

	if obj.HasLabel(doNotMergeLabel) {
		return
	}

	obj.WriteComment(releaseNoteBody)
	obj.AddLabel(doNotMergeLabel)
}
// Munge is the workhorse the will actually make updates to the PR
func (NeedsRebaseMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	mergeable, err := obj.IsMergeable()
	if err != nil {
		glog.V(2).Infof("Skipping %d - problem determining mergeable", *obj.Issue.Number)
		return
	}
	if mergeable && obj.HasLabel(needsRebase) {
		obj.RemoveLabel(needsRebase)
	}
	if !mergeable && !obj.HasLabel(needsRebase) {
		obj.AddLabels([]string{needsRebase})

		body := "PR needs rebase"
		if err := obj.WriteComment(body); err != nil {
			return
		}
	}
}
Exemple #29
0
// Munge is the workhorse the will actually make updates to the PR
func (PingCIMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	// This munger only runs on certain branches, since travis/CI only listens
	// on certain branches
	validBranch := false
	for _, b := range validBranches {
		if obj.IsForBranch(b) {
			validBranch = true
			break
		}
	}
	if !validBranch {
		return
	}

	if !obj.HasLabel(lgtmLabel) {
		return
	}
	mergeable, err := obj.IsMergeable()
	if err != nil {
		glog.V(2).Infof("ping CI skipping %d - problem determining mergeability", *obj.Issue.Number)
		return
	}
	if !mergeable {
		glog.V(2).Infof("ping CI skipping %d - not mergeable", *obj.Issue.Number)
		return
	}
	if state := obj.GetStatusState([]string{travisContext}); state == "incomplete" {
		msg := "Travis continuous integration appears to have missed, closing and re-opening to trigger it"
		obj.WriteComment(msg)

		obj.ClosePR()
		time.Sleep(5 * time.Second)
		obj.OpenPR(10)
	}
}
Exemple #30
0
// Munge is the workhorse the will actually make updates to the PR
func (RebuildMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	comments, err := obj.ListComments(*obj.Issue.Number)
	if err != nil {
		glog.Errorf("unexpected error getting comments: %v", err)
	}

	for ix := range comments {
		comment := &comments[ix]
		// Skip all robot comments
		for _, robot := range []string{"k8s-bot", "k8s-merge-robot", "googlebot"} {
			if *comment.User.Login == robot {
				glog.V(4).Infof("Skipping comment by robot %s: %s", robot, *comment.Body)
				continue
			}
		}
		if isRebuildComment(comment) && rebuildCommentMissingIssueNumber(comment) {
			if err := obj.DeleteComment(comment); err != nil {
				glog.Errorf("Error deleting comment: %v", err)
				continue
			}
			body := fmt.Sprintf(`@%s an issue is required for any manual rebuild.  Expecting comment of the form 'github issue: #<number>'
[Open test flakes](https://github.com/kubernetes/kubernetes/issues?q=is%3Aissue%20label%3Akind%2Fflake)`, *comment.User.Login)
			err := obj.WriteComment(body)
			if err != nil {
				glog.Errorf("unexpected error adding comment: %v", err)
				continue
			}
			if obj.HasLabel("lgtm") {
				if err := obj.RemoveLabel("lgtm"); err != nil {
					glog.Errorf("unexpected error removing lgtm label: %v", err)
				}
			}
		}
	}
}