github.com/abayer/test-infra@v0.0.5/mungegithub/mungers/lgtm_after_commit.go (about) 1 /* 2 Copyright 2015 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 "regexp" 22 23 "k8s.io/apimachinery/pkg/util/sets" 24 "k8s.io/test-infra/mungegithub/features" 25 "k8s.io/test-infra/mungegithub/github" 26 "k8s.io/test-infra/mungegithub/mungers/mungerutil" 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 lgtmRemovedBody = "/lgtm cancel //PR changed after LGTM, removing LGTM. %s" 35 ) 36 37 var ( 38 lgtmRemovedRegex = regexp.MustCompile("/lgtm cancel //PR changed after LGTM, removing LGTM.") 39 ) 40 41 // LGTMAfterCommitMunger will remove the LGTM flag from an PR which has been 42 // updated since the reviewer added LGTM 43 type LGTMAfterCommitMunger struct{} 44 45 func init() { 46 l := LGTMAfterCommitMunger{} 47 RegisterMungerOrDie(l) 48 RegisterStaleIssueComments(l) 49 } 50 51 // Name is the name usable in --pr-mungers 52 func (LGTMAfterCommitMunger) Name() string { return "lgtm-after-commit" } 53 54 // RequiredFeatures is a slice of 'features' that must be provided 55 func (LGTMAfterCommitMunger) RequiredFeatures() []string { return []string{} } 56 57 // Initialize will initialize the munger 58 func (LGTMAfterCommitMunger) Initialize(config *github.Config, features *features.Features) error { 59 return nil 60 } 61 62 // EachLoop is called at the start of every munge loop 63 func (LGTMAfterCommitMunger) EachLoop() error { return nil } 64 65 // RegisterOptions registers options for this munger; returns any that require a restart when changed. 66 func (LGTMAfterCommitMunger) RegisterOptions(opts *options.Options) sets.String { return nil } 67 68 // Munge is the workhorse the will actually make updates to the PR 69 func (LGTMAfterCommitMunger) Munge(obj *github.MungeObject) { 70 if !obj.IsPR() { 71 return 72 } 73 74 if !obj.HasLabel(lgtmLabel) { 75 return 76 } 77 78 lastModified, ok := obj.LastModifiedTime() 79 lgtmTime, ok2 := obj.LabelTime(lgtmLabel) 80 81 if !ok || !ok2 || lastModified == nil || lgtmTime == nil { 82 glog.Errorf("PR %d unable to determine lastModified or lgtmTime", *obj.Issue.Number) 83 return 84 } 85 86 if lastModified.After(*lgtmTime) { 87 glog.Infof("PR: %d lgtm:%s lastModified:%s", *obj.Issue.Number, lgtmTime.String(), lastModified.String()) 88 body := fmt.Sprintf(lgtmRemovedBody, mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()) 89 if err := obj.WriteComment(body); err != nil { 90 return 91 } 92 obj.RemoveLabel(lgtmLabel) 93 } 94 } 95 96 func (LGTMAfterCommitMunger) isStaleIssueComment(obj *github.MungeObject, comment *githubapi.IssueComment) bool { 97 if !obj.IsRobot(comment.User) { 98 return false 99 } 100 if !lgtmRemovedRegex.MatchString(*comment.Body) { 101 return false 102 } 103 if !obj.HasLabel(lgtmLabel) { 104 return false 105 } 106 lgtmTime, ok := obj.LabelTime(lgtmLabel) 107 if lgtmTime == nil || !ok { 108 return false 109 } 110 stale := lgtmTime.After(*comment.CreatedAt) 111 if stale { 112 glog.V(6).Infof("Found stale LGTMAfterCommitMunger comment") 113 } 114 return stale 115 } 116 117 // StaleIssueComments returns a list of stale issue comments. 118 func (l LGTMAfterCommitMunger) StaleIssueComments(obj *github.MungeObject, comments []*githubapi.IssueComment) []*githubapi.IssueComment { 119 return forEachCommentTest(obj, comments, l.isStaleIssueComment) 120 }