github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/plugins/close/close.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 close 18 19 import ( 20 "fmt" 21 "regexp" 22 23 "github.com/sirupsen/logrus" 24 25 "k8s.io/test-infra/prow/github" 26 "k8s.io/test-infra/prow/plugins" 27 ) 28 29 const pluginName = "close" 30 31 var closeRe = regexp.MustCompile(`(?mi)^/close\s*$`) 32 33 func init() { 34 plugins.RegisterGenericCommentHandler(pluginName, handleGenericComment) 35 } 36 37 type githubClient interface { 38 CreateComment(owner, repo string, number int, comment string) error 39 CloseIssue(owner, repo string, number int) error 40 ClosePR(owner, repo string, number int) error 41 IsMember(owner, login string) (bool, error) 42 AssignIssue(owner, repo string, number int, assignees []string) error 43 } 44 45 func handleGenericComment(pc plugins.PluginClient, e github.GenericCommentEvent) error { 46 return handle(pc.GitHubClient, pc.Logger, &e) 47 } 48 49 func handle(gc githubClient, log *logrus.Entry, e *github.GenericCommentEvent) error { 50 // Only consider open issues and new comments. 51 if e.IssueState != "open" || e.Action != github.GenericCommentActionCreated { 52 return nil 53 } 54 55 if !closeRe.MatchString(e.Body) { 56 return nil 57 } 58 59 org := e.Repo.Owner.Login 60 repo := e.Repo.Name 61 number := e.Number 62 commentAuthor := e.User.Login 63 64 // Allow assignees and authors to close issues. 65 isAssignee := false 66 for _, assignee := range e.Assignees { 67 if commentAuthor == assignee.Login { 68 isAssignee = true 69 break 70 } 71 } 72 if e.IssueAuthor.Login != commentAuthor && !isAssignee { 73 log.Infof("Assigning %s/%s#%d to %s", org, repo, number, commentAuthor) 74 if err := gc.AssignIssue(org, repo, number, []string{commentAuthor}); err != nil { 75 msg := "Assigning you to the issue failed." 76 if ok, merr := gc.IsMember(org, commentAuthor); merr == nil && !ok { 77 msg = "Only kubernetes org members may be assigned issues." 78 } else if merr != nil { 79 log.WithError(merr).Errorf("Failed IsMember(%s, %s)", org, commentAuthor) 80 } else { 81 log.WithError(err).Errorf("Failed AssignIssue(%s, %s, %d, %s)", org, repo, number, commentAuthor) 82 } 83 resp := fmt.Sprintf("you can't close an issue unless you authored it or you are assigned to it, %s.", msg) 84 log.Infof("Commenting \"%s\".", resp) 85 return gc.CreateComment(org, repo, number, plugins.FormatResponseRaw(e.Body, e.HTMLURL, commentAuthor, resp)) 86 } 87 } 88 89 if e.IsPR { 90 log.Info("Closing PR.") 91 return gc.ClosePR(org, repo, number) 92 } 93 94 log.Info("Closing issue.") 95 return gc.CloseIssue(org, repo, number) 96 }