1 package triageissue
2
3 import (
4 "net/http"
5 "regexp"
6 "strconv"
7 "strings"
8
9 "github.com/google/go-github/v47/github"
10
11 "edge-infra.dev/pkg/f8n/devinfra/jack/constants"
12 guestservices "edge-infra.dev/pkg/f8n/devinfra/jack/guest_services"
13 "edge-infra.dev/pkg/f8n/devinfra/jack/plugin"
14 )
15
16 var (
17
18 labelApplied bool
19 check bool
20 )
21
22 const ghURL = "https://github.com/"
23
24
25
26 func checkForIssueInPR(hp plugin.HandlerParams, event github.PullRequestEvent) error {
27
28 if event.GetSender().GetType() == constants.Bot {
29 return nil
30 }
31
32 body := event.GetPullRequest().GetBody()
33
34 linkNum, _ := guestservices.ParsePRIssueLinkBody(body)
35 labelCheck := labelCheck(body, linkNum)
36
37 switch {
38 case labelCheck:
39 hp.Log.Info("adding needs-issue label")
40 newLabels := []string{constants.TriageIssueLabel}
41 labelApplied = true
42 _, _, err := hp.Client.Issues().AddLabelsToIssue(hp.Ctx, hp.Org, hp.Repo, event.PullRequest.GetNumber(), newLabels)
43 if err != nil {
44 return err
45 }
46 case !labelCheck:
47 _, err := http.Get(ghURL + constants.Address + linkNum)
48 if err != nil {
49 return err
50 }
51 hp.Log.Info("removing needs issue label")
52 labelApplied = false
53 err = removeTriageLabel(hp, event)
54 if err != nil {
55 return err
56 }
57 err = addIssueNumberToTitle(hp, event, linkNum, event.GetPullRequest().GetTitle())
58 if err != nil {
59 return err
60 }
61 }
62 return nil
63 }
64
65
66 func labelCheck(body, linkNum string) bool {
67 _, err := strconv.Atoi(linkNum)
68
69 if body == "" || linkNum == "" || linkNum == "ISSUE_NUMBER_HERE" || linkNum[0:1] == "0" || err != nil {
70 check = true
71 } else {
72 check = false
73 }
74 return check
75 }
76
77
78 func addLabel(hp plugin.HandlerParams, event github.PullRequestEvent) error {
79
80 if event.GetSender().GetType() == constants.Bot {
81 return nil
82 }
83
84 hp.Log.Info("add triage/needs_issue")
85
86 body := event.GetPullRequest().GetBody()
87 linkNum, _ := guestservices.ParsePRIssueLinkBody(body)
88
89 if !labelCheck(body, linkNum) {
90 hp.Log.Info("Link exists. Removing label again.")
91 return removeLabel(hp, event)
92 }
93
94 if labelCheck(body, linkNum) {
95 hp.Log.Info("adding needs-issue label")
96 newLabels := []string{constants.TriageIssueLabel}
97 labelApplied = true
98 _, _, err := hp.Client.Issues().AddLabelsToIssue(hp.Ctx, hp.Org, hp.Repo, event.PullRequest.GetNumber(), newLabels)
99 if err != nil {
100 return err
101 }
102 }
103
104 return nil
105 }
106
107
108 func removeLabel(hp plugin.HandlerParams, event github.PullRequestEvent) error {
109
110 if event.GetSender().GetType() == constants.Bot {
111 return nil
112 }
113 hp.Log.Info("remove triage/needs_issue")
114
115 body := event.GetPullRequest().GetBody()
116 linkNum, _ := guestservices.ParsePRIssueLinkBody(body)
117
118 if labelCheck(body, linkNum) {
119 hp.Log.Info("Link does not exist. Adding label back")
120 return addLabel(hp, event)
121 }
122
123 _, err := http.Get(ghURL + constants.Address + linkNum)
124 if err != nil {
125 return err
126 }
127 hp.Log.Info("removing needs-issue label")
128 labelApplied = false
129 err = removeTriageLabel(hp, event)
130 if err != nil {
131 return err
132 }
133 return nil
134 }
135
136
137
138 func editedPRBody(hp plugin.HandlerParams, event github.PullRequestEvent) error {
139
140 if event.GetSender().GetType() == constants.Bot {
141 return nil
142 }
143
144 body := event.GetPullRequest().GetBody()
145 linkNum, _ := guestservices.ParsePRIssueLinkBody(body)
146 doesNotHaveIssue := labelCheck(body, linkNum)
147
148
149
150 switch {
151 case labelApplied && !doesNotHaveIssue:
152 _, err := http.Get(ghURL + constants.Address + linkNum)
153 if err != nil {
154 return err
155 }
156 labelApplied = false
157 hp.Log.Info("removing needs-issue label")
158 err = removeTriageLabel(hp, event)
159 if err != nil {
160 return err
161 }
162 if !isIssueNumberInTitle(event.GetPullRequest().GetTitle()) {
163 err = addIssueNumberToTitle(hp, event, linkNum, event.GetPullRequest().GetTitle())
164 if err != nil {
165 return err
166 }
167 }
168 case !labelApplied && doesNotHaveIssue:
169 if labelCheck(body, linkNum) {
170 newLabels := []string{constants.TriageIssueLabel}
171 labelApplied = true
172 hp.Log.Info("adding needs-issue label")
173 _, _, err := hp.Client.Issues().AddLabelsToIssue(hp.Ctx, hp.Org, hp.Repo, event.PullRequest.GetNumber(), newLabels)
174 if err != nil {
175 return err
176 }
177 }
178 case !doesNotHaveIssue:
179
180 if compareTitleNumberToBody(event.GetPullRequest().GetTitle(), linkNum) != 0 {
181 err := updateIssueNumberInTitle(hp, event, linkNum, event.GetPullRequest().GetTitle())
182 if err != nil {
183 return err
184 }
185 }
186 }
187 return nil
188 }
189
190
191 func removeTriageLabel(hp plugin.HandlerParams, pre github.PullRequestEvent) error {
192 for _, x := range pre.PullRequest.Labels {
193 if x.GetName() == constants.TriageIssueLabel {
194 _, err := hp.Client.Issues().RemoveLabelForIssue(hp.Ctx, hp.Org, hp.Repo, pre.PullRequest.GetNumber(), constants.TriageIssueLabel)
195 if err != nil {
196 return err
197 }
198 break
199 }
200 }
201
202 return nil
203 }
204
205
206 func addIssueNumberToTitle(hp plugin.HandlerParams, pre github.PullRequestEvent, linkNum string, title string) error {
207 githubIssueBody := &github.IssueRequest{Title: github.String(linkNum + ": " + title)}
208 _, _, err := hp.Client.Issues().Edit(hp.Ctx, hp.Org, hp.Repo, pre.PullRequest.GetNumber(), githubIssueBody)
209 if err != nil {
210 return err
211 }
212 return nil
213 }
214
215
216 func updateIssueNumberInTitle(hp plugin.HandlerParams, pre github.PullRequestEvent, linkNum string, title string) error {
217 r := regexp.MustCompile(`(\d+):\s*(.*)`)
218 matches := r.FindStringSubmatch(title)
219 githubIssueBody := &github.IssueRequest{Title: github.String(linkNum + ": " + matches[2])}
220 _, _, err := hp.Client.Issues().Edit(hp.Ctx, hp.Org, hp.Repo, pre.PullRequest.GetNumber(), githubIssueBody)
221 if err != nil {
222 return err
223 }
224 return nil
225 }
226
227
228 func isIssueNumberInTitle(title string) bool {
229 r := regexp.MustCompile(`[0-9]+:`)
230 return len(r.FindStringSubmatch(title)) > 0
231 }
232
233 func compareTitleNumberToBody(title string, linkNum string) int {
234 r := regexp.MustCompile(`(\d+):\s*(.*)`)
235 matches := r.FindStringSubmatch(title)
236 return strings.Compare(matches[1], linkNum)
237 }
238
View as plain text