Skip to content

Commit

Permalink
[github-integration] Add /werft run annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
csweichel committed Jun 23, 2021
1 parent f1b514a commit a1372f1
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 29 deletions.
1 change: 1 addition & 0 deletions plugins/github-integration/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ replace github.com/csweichel/werft => ../..
require (
github.com/bradleyfalzon/ghinstallation v1.1.1
github.com/csweichel/werft v0.0.0-00010101000000-000000000000
github.com/google/go-cmp v0.5.2 // indirect
github.com/google/go-github/v35 v35.2.0
github.com/sirupsen/logrus v1.8.1
)
Expand Down
101 changes: 72 additions & 29 deletions plugins/github-integration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,11 +370,6 @@ func (p *githubTriggerPlugin) processIssueCommentEvent(ctx context.Context, even
feedback.Message = "cannot find corresponding PR"
return
}
segs = strings.Split(pr.GetHead().GetRepo().GetFullName(), "/")
var (
prSrcOwner = segs[0]
prSrcRepo = segs[1]
)

var (
sender = event.GetSender().GetLogin()
Expand Down Expand Up @@ -409,27 +404,67 @@ func (p *githubTriggerPlugin) processIssueCommentEvent(ctx context.Context, even
return
}

var run bool
lines := strings.Split(event.GetComment().GetBody(), "\n")
for _, l := range lines {
l = strings.TrimSpace(l)
if !strings.HasPrefix(l, "/werft") {
cmd, args, err := parseCommand(l)
if err != nil {
feedback.Success = false
feedback.Message = fmt.Sprintf("cannot parse %s: %v", l, err)
continue
}
if cmd == "" {
continue
}
l = strings.TrimPrefix(l, "/werft")
l = strings.TrimSpace(l)

fmt.Println(l)
if l == "run" {
run = true
break
} else {
var resp string
switch cmd {
case "run":
resp, err = p.handleCommandRun(ctx, event, pr, args)
default:
err = fmt.Errorf("unknown command: %s", cmd)
}
if err != nil {
log.WithError(err).Warn("GitHub webhook error")
feedback.Success = false
feedback.Message = fmt.Sprintf("unknown command `%s` - only `run` is supported", l)
feedback.Message = err.Error()
return
}

feedback.Success = true
feedback.Message = resp
}
if !run {
return
}

func (p *githubTriggerPlugin) handleCommandRun(ctx context.Context, event *github.IssueCommentEvent, pr *github.PullRequest, args []string) (msg string, err error) {
segs := strings.Split(pr.GetHead().GetRepo().GetFullName(), "/")
var (
prSrcOwner = segs[0]
prSrcRepo = segs[1]
)
segs = strings.Split(event.GetRepo().GetFullName(), "/")
var (
prDstOwner = segs[0]
prDstRepo = segs[1]
)

argm := make(map[string]string)
for _, arg := range args {
var key, value string
if segs := strings.Split(arg, "="); len(segs) == 1 {
key = arg
} else {
key, value = segs[0], strings.Join(segs[1:], "=")
}
argm[key] = value
}
argm[annotationStatusUpdate] = prDstOwner + "/" + prDstRepo

annotations := make([]*v1.Annotation, 0, len(argm))
for k, v := range argm {
annotations = append(annotations, &v1.Annotation{
Key: k,
Value: v,
})
}

ref := pr.GetHead().GetRef()
Expand All @@ -446,13 +481,8 @@ func (p *githubTriggerPlugin) processIssueCommentEvent(ctx context.Context, even
Ref: ref,
Revision: pr.GetHead().GetSHA(),
},
Trigger: v1.JobTrigger_TRIGGER_MANUAL,
Annotations: []*v1.Annotation{
{
Key: annotationStatusUpdate,
Value: prDstOwner + "/" + prDstRepo,
},
},
Trigger: v1.JobTrigger_TRIGGER_MANUAL,
Annotations: annotations,
}
var nameSuffix string
if prDstOwner != prSrcOwner {
Expand All @@ -464,11 +494,24 @@ func (p *githubTriggerPlugin) processIssueCommentEvent(ctx context.Context, even
})
if err != nil {
log.WithError(err).Warn("GitHub webhook error")
feedback.Success = false
feedback.Message = "cannot start job - please talk to whoever's in charge of your Werft installation"
return "", fmt.Errorf("cannot start job - please talk to whoever's in charge of your Werft installation")
}

return fmt.Sprintf("started the job as [%s](%s/job/%s)", resp.Status.Name, p.Config.BaseURL, resp.Status.Name), nil
}

func parseCommand(l string) (cmd string, args []string, err error) {
l = strings.TrimSpace(l)
if !strings.HasPrefix(l, "/werft") {
return
}
l = strings.TrimPrefix(l, "/werft")
l = strings.TrimSpace(l)

segs := strings.Fields(l)
if len(segs) < 1 {
return "", nil, fmt.Errorf("missing command")
}

feedback.Success = true
feedback.Message = fmt.Sprintf("started the job as [%s](%s/job/%s)", resp.Status.Name, p.Config.BaseURL, resp.Status.Name)
return segs[0], segs[1:], nil
}
43 changes: 43 additions & 0 deletions plugins/github-integration/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"testing"

"github.com/google/go-cmp/cmp"
)

func TestParseCommand(t *testing.T) {
type Expectation struct {
Cmd string
Args []string
Err string
}
tests := []struct {
Name string
Input string
Expectation Expectation
}{
{Name: "empty line", Input: ""},
{Name: "ignore line", Input: "something\nsomethingelse"},
{Name: "no command", Input: "/werft", Expectation: Expectation{Err: "missing command"}},
{Name: "no arg", Input: "/werft foo", Expectation: Expectation{Cmd: "foo", Args: []string{}}},
{Name: "one arg", Input: "/werft foo bar", Expectation: Expectation{Cmd: "foo", Args: []string{"bar"}}},
{Name: "two args", Input: "/werft foo bar=baz something", Expectation: Expectation{Cmd: "foo", Args: []string{"bar=baz", "something"}}},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
var (
act Expectation
err error
)
act.Cmd, act.Args, err = parseCommand(test.Input)
if err != nil {
act.Err = err.Error()
}

if diff := cmp.Diff(test.Expectation, act); diff != "" {
t.Errorf("MakeGatewayInfo() mismatch (-want +got):\n%s", diff)
}
})
}
}

0 comments on commit a1372f1

Please sign in to comment.