github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/plugins/wip/wip-label.go (about) 1 /* 2 Copyright 2017 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 wip will label a PR a work-in-progress if the author provides 18 // a prefix to their pull request title to the same effect. The submit- 19 // queue will not merge pull requests with the work-in-progress label. 20 // The label will be removed when the title changes to no longer begin 21 // with the prefix. 22 package wip 23 24 import ( 25 "fmt" 26 "regexp" 27 28 "github.com/sirupsen/logrus" 29 30 "k8s.io/test-infra/prow/github" 31 "k8s.io/test-infra/prow/plugins" 32 ) 33 34 const ( 35 label = "do-not-merge/work-in-progress" 36 pluginName = "wip" 37 ) 38 39 var ( 40 titleRegex = regexp.MustCompile(`(?i)^\W?WIP\W`) 41 ) 42 43 type event struct { 44 org string 45 repo string 46 number int 47 hasLabel bool 48 needsLabel bool 49 } 50 51 func init() { 52 plugins.RegisterPullRequestHandler(pluginName, handlePullRequest) 53 } 54 55 // Strict subset of *github.Client methods. 56 type githubClient interface { 57 GetIssueLabels(org, repo string, number int) ([]github.Label, error) 58 AddLabel(owner, repo string, number int, label string) error 59 RemoveLabel(owner, repo string, number int, label string) error 60 CreateComment(org, repo string, number int, comment string) error 61 } 62 63 func handlePullRequest(pc plugins.PluginClient, pe github.PullRequestEvent) error { 64 // These are the only actions indicating the PR title may have changed. 65 if pe.Action != github.PullRequestActionOpened && 66 pe.Action != github.PullRequestActionReopened && 67 pe.Action != github.PullRequestActionEdited { 68 return nil 69 } 70 71 var ( 72 org = pe.PullRequest.Base.Repo.Owner.Login 73 repo = pe.PullRequest.Base.Repo.Name 74 number = pe.PullRequest.Number 75 title = pe.PullRequest.Title 76 ) 77 78 currentLabels, err := pc.GitHubClient.GetIssueLabels(org, repo, number) 79 if err != nil { 80 return fmt.Errorf("could not get labels for PR %s/%s:%d in WIP plugin: %v", org, repo, number, err) 81 } 82 hasLabel := false 83 for _, l := range currentLabels { 84 if l.Name == label { 85 hasLabel = true 86 } 87 } 88 89 needsLabel := titleRegex.MatchString(title) 90 91 e := &event{ 92 org: org, 93 repo: repo, 94 number: number, 95 hasLabel: hasLabel, 96 needsLabel: needsLabel, 97 } 98 return handle(pc.GitHubClient, pc.Logger, e) 99 } 100 101 // handle interacts with GitHub to drive the pull request to the 102 // proper state by adding and removing comments and labels. If a 103 // PR has a WIP prefix, it needs an explanatory comment and label. 104 // Otherwise, neither should be present. 105 func handle(gc githubClient, le *logrus.Entry, e *event) error { 106 if e.needsLabel && !e.hasLabel { 107 if err := gc.AddLabel(e.org, e.repo, e.number, label); err != nil { 108 le.Warnf("error while adding label %q: %v", label, err) 109 return err 110 } 111 } else if !e.needsLabel && e.hasLabel { 112 if err := gc.RemoveLabel(e.org, e.repo, e.number, label); err != nil { 113 le.Warnf("error while removing label %q: %v", label, err) 114 return err 115 } 116 } 117 return nil 118 }