github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/mungegithub/mungers/stale-pending-ci.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mungers 18 19 import ( 20 "fmt" 21 "time" 22 23 "k8s.io/kubernetes/pkg/util/sets" 24 "k8s.io/test-infra/mungegithub/features" 25 "k8s.io/test-infra/mungegithub/github" 26 "k8s.io/test-infra/mungegithub/mungeopts" 27 "k8s.io/test-infra/mungegithub/options" 28 29 "github.com/golang/glog" 30 githubapi "github.com/google/go-github/github" 31 ) 32 33 const ( 34 stalePendingCIHours = 24 35 pendingMsgFormat = `@` + jenkinsBotName + ` test this issue: #IGNORE 36 37 Tests have been pending for %d hours` 38 ) 39 40 var ( 41 pendingMsgBody = fmt.Sprintf(pendingMsgFormat, stalePendingCIHours) 42 ) 43 44 // StalePendingCI will ask the testBot-to test any PR with a LGTM that has 45 // been pending for more than 24 hours. This can happen when the jenkins VM 46 // is restarted. 47 // 48 // The real fix would be for the jenkins VM restart to not move every single 49 // PR to pending without actually testing... 50 // 51 // But this is our world and so we should really do this for all PRs which 52 // aren't likely to get another push (everything that is mergeable). Since that 53 // can be a lot of PRs, I'm just doing it for the LGTM PRs automatically... 54 type StalePendingCI struct{} 55 56 func init() { 57 s := &StalePendingCI{} 58 RegisterMungerOrDie(s) 59 RegisterStaleIssueComments(s) 60 } 61 62 // Name is the name usable in --pr-mungers 63 func (s *StalePendingCI) Name() string { return "stale-pending-ci" } 64 65 // RequiredFeatures is a slice of 'features' that must be provided 66 func (s *StalePendingCI) RequiredFeatures() []string { return []string{} } 67 68 // Initialize will initialize the munger 69 func (s *StalePendingCI) Initialize(config *github.Config, features *features.Features) error { 70 return nil 71 } 72 73 // EachLoop is called at the start of every munge loop 74 func (s *StalePendingCI) EachLoop() error { return nil } 75 76 // RegisterOptions registers options for this munger; returns any that require a restart when changed. 77 func (s *StalePendingCI) RegisterOptions(opts *options.Options) sets.String { return nil } 78 79 // Munge is the workhorse the will actually make updates to the PR 80 func (s *StalePendingCI) Munge(obj *github.MungeObject) { 81 if !obj.IsPR() { 82 return 83 } 84 85 if !obj.HasLabel(lgtmLabel) { 86 return 87 } 88 89 if mergeable, ok := obj.IsMergeable(); !ok || !mergeable { 90 return 91 } 92 93 status, ok := obj.GetStatusState(mungeopts.RequiredContexts.Retest) 94 if !ok || status != "pending" { 95 return 96 } 97 98 for _, context := range mungeopts.RequiredContexts.Retest { 99 statusTime, ok := obj.GetStatusTime(context) 100 if !ok || statusTime == nil { 101 glog.Errorf("%d: unable to determine time %q context was set", *obj.Issue.Number, context) 102 return 103 } 104 if time.Since(*statusTime) > stalePendingCIHours*time.Hour { 105 obj.WriteComment(pendingMsgBody) 106 return 107 } 108 } 109 } 110 111 func isStaleIssueComment(obj *github.MungeObject, comment *githubapi.IssueComment) bool { 112 if !obj.IsRobot(comment.User) { 113 return false 114 } 115 if *comment.Body != pendingMsgBody { 116 return false 117 } 118 stale := commentBeforeLastCI(obj, comment, mungeopts.RequiredContexts.Retest) 119 if stale { 120 glog.V(6).Infof("Found stale StalePendingCI comment") 121 } 122 return stale 123 } 124 125 // StaleIssueComments returns a slice of stale issue comments. 126 func (s *StalePendingCI) StaleIssueComments(obj *github.MungeObject, comments []*githubapi.IssueComment) []*githubapi.IssueComment { 127 if mungeopts.RequiredContexts.Retest == nil { 128 return nil // mungers not initialized, cannot clean stale comments. 129 } 130 return forEachCommentTest(obj, comments, isStaleIssueComment) 131 }