func newInterruptedObject(obj *github.MungeObject) *submitQueueInterruptedObject { if headSHA, baseRef, gotHeadSHA := obj.GetHeadAndBase(); !gotHeadSHA { return nil } else if baseSHA, gotBaseSHA := obj.GetSHAFromRef(baseRef); !gotBaseSHA { return nil } else { return &submitQueueInterruptedObject{obj, headSHA, baseSHA} } }
// Returns true if we can discard the PR from the queue, false if we must keep it for later. func (sq *SubmitQueue) doGithubE2EAndMerge(obj *github.MungeObject) bool { interruptedObj := sq.interruptedObj sq.interruptedObj = nil err := obj.Refresh() if err != nil { glog.Errorf("%d: unknown err: %v", *obj.Issue.Number, err) sq.SetMergeStatus(obj, unknown) return true } if !sq.validForMerge(obj) { return true } if obj.HasLabel(retestNotRequiredLabel) || obj.HasLabel(retestNotRequiredDocsOnlyLabel) { atomic.AddInt32(&sq.instantMerges, 1) sq.mergePullRequest(obj) return true } sha, _, ok := obj.GetHeadAndBase() if !ok { glog.Errorf("%d: Unable to get SHA", *obj.Issue.Number) sq.SetMergeStatus(obj, unknown) return true } if interruptedObj != nil { if interruptedObj.hasSHAChanged() { // This PR will have to be rested. // Make sure we don't have higher priority first. return false } glog.Infof("Skipping retest since head and base sha match previous attempt!") atomic.AddInt32(&sq.retestsAvoided, 1) } else { if sq.retestPR(obj) { return true } err := obj.Refresh() if err != nil { glog.Errorf("%d: unknown err: %v", *obj.Issue.Number, err) sq.SetMergeStatus(obj, unknown) return true } } // We shouldn't merge if it's not valid anymore if !sq.validForMerge(obj) { glog.Errorf("%d: Not mergeable anymore. Do not merge.", *obj.Issue.Number) return true } if newSha, _, ok := obj.GetHeadAndBase(); !ok { glog.Errorf("%d: Unable to get SHA", *obj.Issue.Number) sq.SetMergeStatus(obj, unknown) return true } else if newSha != sha { glog.Errorf("%d: Changed while running the test. Do not merge.", *obj.Issue.Number) sq.SetMergeStatus(obj, headCommitChanged) return false } if !sq.e2eStable(true) { if sq.validForMerge(obj) { sq.interruptedObj = newInterruptedObject(obj) } sq.SetMergeStatus(obj, e2eFailure) return true } sq.mergePullRequest(obj) return true }
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 } // See if we can skip the retest. headSHA, baseRef, gotHeadSHA := obj.GetHeadAndBase() baseSHA := "" gotBaseSHA := false if gotHeadSHA { baseSHA, gotBaseSHA = obj.GetSHAFromRef(baseRef) } maySkipTest := gotHeadSHA && gotBaseSHA && sq.interruptedMergeBaseSHA == baseSHA && sq.interruptedMergeHeadSHA == headSHA if maySkipTest { glog.Infof("Skipping retest since head and base sha match previous attempt!") atomic.AddInt32(&sq.retestsAvoided, 1) } else { 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 } // re-get the base SHA in case something merged between us checking and // starting the tests. if gotHeadSHA { baseSHA, gotBaseSHA = obj.GetSHAFromRef(baseRef) } // 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(true) { if gotHeadSHA && gotBaseSHA { sq.interruptedMergeBaseSHA = baseSHA sq.interruptedMergeHeadSHA = headSHA } sq.SetMergeStatus(obj, e2eFailure) return } obj.MergePR("submit-queue") sq.updateMergeRate() sq.SetMergeStatus(obj, merged) return }