github.com/abayer/test-infra@v0.0.5/prow/plugins/trigger/ic.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 trigger 18 19 import ( 20 "fmt" 21 "regexp" 22 23 "k8s.io/test-infra/prow/github" 24 "k8s.io/test-infra/prow/plugins" 25 ) 26 27 var okToTestRe = regexp.MustCompile(`(?m)^/ok-to-test\s*$`) 28 var testAllRe = regexp.MustCompile(`(?m)^/test all\s*$`) 29 var retestRe = regexp.MustCompile(`(?m)^/retest\s*$`) 30 31 func handleIC(c client, trigger *plugins.Trigger, ic github.IssueCommentEvent) error { 32 org := ic.Repo.Owner.Login 33 repo := ic.Repo.Name 34 number := ic.Issue.Number 35 commentAuthor := ic.Comment.User.Login 36 // Only take action when a comment is first created. 37 if ic.Action != github.IssueCommentActionCreated { 38 return nil 39 } 40 // If it's not an open PR, skip it. 41 if !ic.Issue.IsPullRequest() { 42 return nil 43 } 44 if ic.Issue.State != "open" { 45 return nil 46 } 47 // Skip bot comments. 48 botName, err := c.GitHubClient.BotName() 49 if err != nil { 50 return err 51 } 52 if commentAuthor == botName { 53 return nil 54 } 55 56 // Which jobs does the comment want us to run? 57 okToTest := okToTestRe.MatchString(ic.Comment.Body) 58 testAll := okToTest || testAllRe.MatchString(ic.Comment.Body) 59 shouldRetestFailed := retestRe.MatchString(ic.Comment.Body) 60 requestedJobs := c.Config.MatchingPresubmits(ic.Repo.FullName, ic.Comment.Body, testAll) 61 if !shouldRetestFailed && len(requestedJobs) == 0 { 62 // Check for the presence of the needs-ok-to-test label and remove it 63 // if a trusted member has commented "/ok-to-test". 64 if okToTest && ic.Issue.HasLabel(needsOkToTest) { 65 trusted, err := trustedUser(c.GitHubClient, trigger, commentAuthor, org, repo) 66 if err != nil { 67 return err 68 } 69 if trusted { 70 return c.GitHubClient.RemoveLabel(org, repo, number, needsOkToTest) 71 } 72 } 73 return nil 74 } 75 76 pr, err := c.GitHubClient.GetPullRequest(org, repo, number) 77 if err != nil { 78 return err 79 } 80 81 var forceRunContexts map[string]bool 82 if shouldRetestFailed { 83 combinedStatus, err := c.GitHubClient.GetCombinedStatus(org, repo, pr.Head.SHA) 84 if err != nil { 85 return err 86 } 87 skipContexts := make(map[string]bool) // these succeeded or are running 88 forceRunContexts = make(map[string]bool) // these failed and should be re-run 89 for _, status := range combinedStatus.Statuses { 90 state := status.State 91 if state == github.StatusSuccess || state == github.StatusPending { 92 skipContexts[status.Context] = true 93 } else if state == github.StatusError || state == github.StatusFailure { 94 forceRunContexts[status.Context] = true 95 } 96 } 97 retests := c.Config.RetestPresubmits(ic.Repo.FullName, skipContexts, forceRunContexts) 98 requestedJobs = append(requestedJobs, retests...) 99 } 100 101 var comments []github.IssueComment 102 // Skip untrusted users. 103 trusted, err := trustedUser(c.GitHubClient, trigger, commentAuthor, org, repo) 104 if err != nil { 105 return fmt.Errorf("error checking trust of %s: %v", commentAuthor, err) 106 } 107 if !trusted { 108 comments, err = c.GitHubClient.ListIssueComments(org, repo, number) 109 if err != nil { 110 return fmt.Errorf("error listing issue comments: %v", err) 111 } 112 trusted, err := trustedPullRequest(c.GitHubClient, trigger, ic.Issue.User.Login, org, repo, comments) 113 if err != nil { 114 return err 115 } 116 if !trusted { 117 resp := fmt.Sprintf("Cannot trigger testing until a trusted user reviews the PR and leaves an `/ok-to-test` message.") 118 c.Logger.Infof("Commenting \"%s\".", resp) 119 return c.GitHubClient.CreateComment(org, repo, number, plugins.FormatICResponse(ic.Comment, resp)) 120 } 121 } 122 123 if okToTest && ic.Issue.HasLabel(needsOkToTest) { 124 if err := c.GitHubClient.RemoveLabel(ic.Repo.Owner.Login, ic.Repo.Name, ic.Issue.Number, needsOkToTest); err != nil { 125 c.Logger.WithError(err).Errorf("Failed at removing %s label", needsOkToTest) 126 } 127 err = clearStaleComments(c.GitHubClient, *pr, comments) 128 if err != nil { 129 c.Logger.Warnf("Failed to clear stale comments: %v.", err) 130 } 131 } 132 133 return runOrSkipRequested(c, pr, requestedJobs, forceRunContexts, ic.Comment.Body, ic.GUID) 134 }