added labels
This commit is contained in:
parent
56cbb383ab
commit
bfb79c3f3c
5 changed files with 243 additions and 29 deletions
221
main.go
221
main.go
|
|
@ -3,7 +3,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
|
@ -11,7 +13,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -25,9 +27,11 @@ import (
|
|||
var debug = false
|
||||
|
||||
const (
|
||||
prAction = "X-Interceptor-Pr-Action"
|
||||
pushAction = "X-Interceptor-Push-Action"
|
||||
commentAction = "X-Interceptor-Comment-Action"
|
||||
prAction = "X-Interceptor-Pr-Action"
|
||||
pushAction = "X-Interceptor-Push-Action"
|
||||
commentAction = "X-Interceptor-Comment-Action"
|
||||
labelHeader = "X-Interceptor-Label"
|
||||
removeLabelsHeader = "X-Interceptor-Remove-Labels"
|
||||
|
||||
contentType = "Content-Type"
|
||||
jsonType = "application/json"
|
||||
|
|
@ -89,15 +93,162 @@ func (h *Handler) getPullRequest(repo Repository, api, id string) (*PullRequest,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, errors.New("error getting pull request")
|
||||
}
|
||||
pr := new(PullRequest)
|
||||
err = json.NewDecoder(resp.Body).Decode(pr)
|
||||
_, err = readBody(resp.Body, pr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
func (h *Handler) addLabel(repo Repository, api, label, color string) (labelID int64, err error) {
|
||||
labelID = -1
|
||||
u, err := url.Parse(repo.CloneURL)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing repo URL: %s", err)
|
||||
return
|
||||
}
|
||||
repoLabels := strings.Join([]string{api, "repos",
|
||||
repo.Owner.Login, repo.Name,
|
||||
"labels"}, "/")
|
||||
u.Path = repoLabels
|
||||
req, err := http.NewRequest("GET", u.String(), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user, pass, err := h.getSecret(u.Host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.SetBasicAuth(user, pass)
|
||||
req.Header.Set(contentType, jsonType)
|
||||
|
||||
resp, err := h.cl.Do(req)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting labels of %s: %s", u, err)
|
||||
return
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("error getting labels of %s", u)
|
||||
return
|
||||
}
|
||||
var labels []Label
|
||||
_, err = readBody(resp.Body, &labels)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, l := range labels {
|
||||
if l.Name == label {
|
||||
labelID = l.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
if labelID >= 0 {
|
||||
return
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
l := &Label{Name: label, Color: color}
|
||||
err = json.NewEncoder(buf).Encode(l)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err = http.NewRequest("POST", u.String(), buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Set(contentType, jsonType)
|
||||
req.SetBasicAuth(user, pass)
|
||||
|
||||
resp, err = h.cl.Do(req)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error creating label %s for %s: %s", label, u, err)
|
||||
return
|
||||
}
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
err = fmt.Errorf("error creating label %s for %s", label, u)
|
||||
}
|
||||
var createdLabel Label
|
||||
_, err = readBody(resp.Body, &createdLabel)
|
||||
labelID = createdLabel.ID
|
||||
return
|
||||
}
|
||||
|
||||
func (h *Handler) setLabel(repo Repository, api, id, label, color string, remove []string) (err error) {
|
||||
labelID, err := h.addLabel(repo, api, label, color)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
u, err := url.Parse(repo.CloneURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
u.Path = strings.Join([]string{api, "repos",
|
||||
repo.Owner.Login, repo.Name,
|
||||
"issues", id, "labels"}, "/")
|
||||
req, err := http.NewRequest("GET", u.String(), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user, pass, err := h.getSecret(u.Host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.SetBasicAuth(user, pass)
|
||||
req.Header.Set(contentType, jsonType)
|
||||
resp, err := h.cl.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting issue labels of %s: %s", u, err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("error getting issue labels of %s", u)
|
||||
}
|
||||
var labels []Label
|
||||
_, err = readBody(resp.Body, &labels)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pl := &PostLabels{[]int64{labelID}}
|
||||
var rm, found bool
|
||||
for _, l := range labels {
|
||||
if contains(remove, l.Name) {
|
||||
rm = true
|
||||
} else {
|
||||
if l.Name == label {
|
||||
found = true
|
||||
}
|
||||
pl.Labels = append(pl.Labels, l.ID)
|
||||
}
|
||||
}
|
||||
if !rm && found {
|
||||
return
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = json.NewEncoder(buf).Encode(pl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err = http.NewRequest("PUT", u.String(), buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.SetBasicAuth(user, pass)
|
||||
req.Header.Set(contentType, jsonType)
|
||||
|
||||
resp, err = h.cl.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error setting issue label %s for %s: %s", label, u, err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("error setting issue label %s for %s", label, u)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
sec typedcorev1.SecretInterface
|
||||
cl *http.Client
|
||||
|
|
@ -121,14 +272,27 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (h *Handler) prHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var prb PullRequestBody
|
||||
body, err := readBody(r, &prb)
|
||||
body, err := readBody(r.Body, &prb)
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if contains(r.Header[prAction], prb.Action) {
|
||||
if l := r.Header.Get(labelHeader); l != "" {
|
||||
label, _ := getLabel(l)
|
||||
var labels []string
|
||||
for _, l := range prb.PullRequest.Labels {
|
||||
labels = append(labels, l.Name)
|
||||
}
|
||||
|
||||
if !contains(labels, label) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
h := w.Header()
|
||||
h.Set(issueHeader, strconv.FormatInt(prb.Number, 10))
|
||||
h.Set(issueHeader, itoa(prb.Number))
|
||||
h.Set(commitHeader, prb.PullRequest.Head.SHA)
|
||||
w.Write(body)
|
||||
return
|
||||
|
|
@ -138,12 +302,14 @@ func (h *Handler) prHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (h *Handler) pushHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var pb PushBody
|
||||
body, err := readBody(r, &pb)
|
||||
body, err := readBody(r.Body, &pb)
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
return
|
||||
}
|
||||
if contains(r.Header[pushAction], pb.Ref) {
|
||||
push := r.Header.Get(pushAction)
|
||||
//if contains(r.Header[pushAction], pb.Ref) {
|
||||
if push != "" && push == pb.Ref {
|
||||
h := w.Header()
|
||||
h.Set(commitHeader, pb.After)
|
||||
w.Write(body)
|
||||
|
|
@ -154,20 +320,45 @@ func (h *Handler) pushHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (h *Handler) commentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var cb CommentBody
|
||||
body, err := readBody(r, &cb)
|
||||
body, err := readBody(r.Body, &cb)
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
return
|
||||
}
|
||||
//if label := r.Header.Get(labelHeader); label != "" {
|
||||
//}
|
||||
if contains(r.Header[commentAction], cb.Comment.Body) {
|
||||
issue := strconv.FormatInt(cb.Issue.Number, 10)
|
||||
|
||||
//if contains(r.Header[commentAction], cb.Comment.Body) {
|
||||
comment := r.Header.Get(commentAction)
|
||||
if comment == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
m, err := regexp.MatchString("(?m)^"+comment+"$", cb.Comment.Body)
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
return
|
||||
}
|
||||
if m {
|
||||
issue := itoa(cb.Issue.Number)
|
||||
api := detectAPI(r)
|
||||
if api == "" {
|
||||
logError(w, "unable to detect git provider API")
|
||||
return
|
||||
}
|
||||
if l := r.Header.Get(labelHeader); l != "" {
|
||||
label, color := getLabel(l)
|
||||
var labels []string
|
||||
for _, l := range cb.Issue.Labels {
|
||||
labels = append(labels, l.Name)
|
||||
}
|
||||
if !contains(labels, label) {
|
||||
err := h.setLabel(cb.Repository, api, issue, label, color, r.Header[removeLabelsHeader])
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pr, err := h.getPullRequest(cb.Repository, api, issue)
|
||||
if err != nil {
|
||||
logError(w, err.Error())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue