diff --git a/.drone.yml b/.drone.yml index f955e4e..2cfe87e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -20,7 +20,7 @@ pipeline: docker: repo: lgtm/lgtm - tag: [latest, 1.0.0] + tag: [latest, 1.1.0] when: branch: master event: push diff --git a/remote/github/comment_hook.go b/remote/github/comment_hook.go new file mode 100644 index 0000000..cab04af --- /dev/null +++ b/remote/github/comment_hook.go @@ -0,0 +1,55 @@ +package github + +import "github.com/lgtmco/lgtm/model" + +// commentHook represents a subset of the issue_comment payload. +type commentHook struct { + Issue struct { + Link string `json:"html_url"` + Number int `json:"number"` + User struct { + Login string `json:"login"` + } `json:"user"` + + PullRequest struct { + Link string `json:"html_url"` + } `json:"pull_request"` + } `json:"issue"` + + Comment struct { + Body string `json:"body"` + User struct { + Login string `json:"login"` + } `json:"user"` + } `json:"comment"` + + Repository struct { + Name string `json:"name"` + FullName string `json:"full_name"` + Desc string `json:"description"` + Private bool `json:"private"` + Owner struct { + Login string `json:"login"` + Type string `json:"type"` + Avatar string `json:"avatar_url"` + } `json:"owner"` + } `json:"repository"` +} + +func (ch *commentHook) toHook() *model.Hook { + return &model.Hook{ + Issue: &model.Issue{ + Number: ch.Issue.Number, + Author: ch.Issue.User.Login, + }, + Repo: &model.Repo{ + Owner: ch.Repository.Owner.Login, + Name: ch.Repository.Name, + Slug: ch.Repository.FullName, + }, + Comment: &model.Comment{ + Body: ch.Comment.Body, + Author: ch.Comment.User.Login, + }, + } +} diff --git a/remote/github/github.go b/remote/github/github.go index 5dc79e4..d7d9e00 100644 --- a/remote/github/github.go +++ b/remote/github/github.go @@ -301,33 +301,36 @@ func (g *Github) SetStatus(u *model.User, r *model.Repo, num, granted, required } func (g *Github) GetHook(r *http.Request) (*model.Hook, error) { - - // only process comment hooks - if r.Header.Get("X-Github-Event") != "issue_comment" { + eventType := r.Header.Get("X-Github-Event") + if eventType == "issue_comment" { + return getCommentHook(r) + } else if eventType == "pull_request" { + return getPRHook(r) + } else { return nil, nil } +} +func getCommentHook(r *http.Request) (*model.Hook, error) { data := commentHook{} - err := json.NewDecoder(r.Body).Decode(&data) - if err != nil { + defer r.Body.Close() + if err := json.NewDecoder(r.Body).Decode(&data); err != nil { return nil, err } - if len(data.Issue.PullRequest.Link) == 0 { return nil, nil } + return data.toHook(), nil +} - hook := new(model.Hook) - hook.Issue = new(model.Issue) - hook.Issue.Number = data.Issue.Number - hook.Issue.Author = data.Issue.User.Login - hook.Repo = new(model.Repo) - hook.Repo.Owner = data.Repository.Owner.Login - hook.Repo.Name = data.Repository.Name - hook.Repo.Slug = data.Repository.FullName - hook.Comment = new(model.Comment) - hook.Comment.Body = data.Comment.Body - hook.Comment.Author = data.Comment.User.Login - - return hook, nil +func getPRHook(r *http.Request) (*model.Hook, error) { + data := pullRequestHook{} + defer r.Body.Close() + if err := json.NewDecoder(r.Body).Decode(&data); err != nil { + return nil, err + } + if !data.analysable() { + return nil, nil + } + return data.toHook(), nil } diff --git a/remote/github/pull_request_hook.go b/remote/github/pull_request_hook.go new file mode 100644 index 0000000..32c9f04 --- /dev/null +++ b/remote/github/pull_request_hook.go @@ -0,0 +1,42 @@ +package github + +import "github.com/lgtmco/lgtm/model" + +// pullRequestHook represents a subset of the pull_request payload. +type pullRequestHook struct { + Action string `json:"action"` + Number int `json:"number"` + + PullRequest struct { + User struct { + Login string `json:"login"` + } `json:"user"` + } `json:"pull_request"` + + Repository struct { + Name string `json:"name"` + FullName string `json:"full_name"` + Owner struct { + Login string `json:"login"` + } `json:"owner"` + } `json:"repository"` +} + +func (prh *pullRequestHook) toHook() *model.Hook { + return &model.Hook{ + Issue: &model.Issue{ + Number: prh.Number, + Author: prh.PullRequest.User.Login, + }, + Repo: &model.Repo{ + Owner: prh.Repository.Owner.Login, + Name: prh.Repository.Name, + Slug: prh.Repository.FullName, + }, + } +} + +func (prh *pullRequestHook) analysable() bool { + return prh.Action == "opened" || + prh.Action == "synchronize" +} diff --git a/remote/github/types.go b/remote/github/types.go index 4f990e1..7a9b8ef 100644 --- a/remote/github/types.go +++ b/remote/github/types.go @@ -16,37 +16,3 @@ type Branch struct { } `json:"required_status_checks"` } `json:"protection"` } - -// commentHook represents a subset of the issue_comment payload. -type commentHook struct { - Issue struct { - Link string `json:"html_url"` - Number int `json:"number"` - User struct { - Login string `json:"login"` - } `json:"user"` - - PullRequest struct { - Link string `json:"html_url"` - } `json:"pull_request"` - } `json:"issue"` - - Comment struct { - Body string `json:"body"` - User struct { - Login string `json:"login"` - } `json:"user"` - } `json:"comment"` - - Repository struct { - Name string `json:"name"` - FullName string `json:"full_name"` - Desc string `json:"description"` - Private bool `json:"private"` - Owner struct { - Login string `json:"login"` - Type string `json:"type"` - Avatar string `json:"avatar_url"` - } `json:"owner"` - } `json:"repository"` -} diff --git a/remote/github/utils.go b/remote/github/utils.go index d81823c..b0fc749 100644 --- a/remote/github/utils.go +++ b/remote/github/utils.go @@ -64,7 +64,7 @@ func DeleteHook(client *github.Client, owner, name, url string) error { func CreateHook(client *github.Client, owner, name, url string) (*github.Hook, error) { var hook = new(github.Hook) hook.Name = github.String("web") - hook.Events = []string{"issue_comment"} + hook.Events = []string{"issue_comment", "pull_request"} hook.Config = map[string]interface{}{} hook.Config["url"] = url hook.Config["content_type"] = "json"