diff --git a/github/github.go b/github/github.go index 2702d1f..08b066f 100644 --- a/github/github.go +++ b/github/github.go @@ -36,6 +36,8 @@ const ( DeploymentStatusEvent Event = "deployment_status" ForkEvent Event = "fork" GollumEvent Event = "gollum" + InstallationEvent Event = "installation" + IntegrationInstallationEvent Event = "integration_installation" IssueCommentEvent Event = "issue_comment" IssuesEvent Event = "issues" LabelEvent Event = "label" @@ -179,6 +181,10 @@ func (hook Webhook) ParsePayload(w http.ResponseWriter, r *http.Request) { var g GollumPayload json.Unmarshal([]byte(payload), &g) hook.runProcessPayloadFunc(fn, g, hd) + case InstallationEvent, IntegrationInstallationEvent: + var i InstallationPayload + json.Unmarshal([]byte(payload), &i) + hook.runProcessPayloadFunc(fn, i, hd) case IssueCommentEvent: var i IssueCommentPayload json.Unmarshal([]byte(payload), &i) diff --git a/github/github_test.go b/github/github_test.go index 58c74ad..07a0793 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -48,6 +48,8 @@ func TestMain(m *testing.M) { DeploymentStatusEvent, ForkEvent, GollumEvent, + InstallationEvent, + IntegrationInstallationEvent, IssueCommentEvent, IssuesEvent, LabelEvent, @@ -1309,6 +1311,186 @@ func TestGollumEvent(t *testing.T) { Equal(t, resp.StatusCode, http.StatusOK) } +func TestInstallationEvent(t *testing.T) { + + payload := `{ + "action": "created", + "installation": { + "id": 80429, + "account": { + "login": "PombeirP", + "id": 138074, + "avatar_url": "https://avatars1.githubusercontent.com/u/138074?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/PombeirP", + "html_url": "https://github.com/PombeirP", + "followers_url": "https://api.github.com/users/PombeirP/followers", + "following_url": "https://api.github.com/users/PombeirP/following{/other_user}", + "gists_url": "https://api.github.com/users/PombeirP/gists{/gist_id}", + "starred_url": "https://api.github.com/users/PombeirP/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/PombeirP/subscriptions", + "organizations_url": "https://api.github.com/users/PombeirP/orgs", + "repos_url": "https://api.github.com/users/PombeirP/repos", + "events_url": "https://api.github.com/users/PombeirP/events{/privacy}", + "received_events_url": "https://api.github.com/users/PombeirP/received_events", + "type": "User", + "site_admin": false + }, + "repository_selection": "selected", + "access_tokens_url": "https://api.github.com/installations/80429/access_tokens", + "repositories_url": "https://api.github.com/installation/repositories", + "html_url": "https://github.com/settings/installations/80429", + "app_id": 8157, + "target_id": 138074, + "target_type": "User", + "permissions": { + "repository_projects": "write", + "issues": "read", + "metadata": "read", + "pull_requests": "read" + }, + "events": [ + "pull_request" + ], + "created_at": 1516025475, + "updated_at": 1516025475, + "single_file_name": null + }, + "repositories": [ + { + "id": 117381220, + "name": "status-github-bot", + "full_name": "PombeirP/status-github-bot" + } + ], + "sender": { + "login": "PombeirP", + "id": 138074, + "avatar_url": "https://avatars1.githubusercontent.com/u/138074?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/PombeirP", + "html_url": "https://github.com/PombeirP", + "followers_url": "https://api.github.com/users/PombeirP/followers", + "following_url": "https://api.github.com/users/PombeirP/following{/other_user}", + "gists_url": "https://api.github.com/users/PombeirP/gists{/gist_id}", + "starred_url": "https://api.github.com/users/PombeirP/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/PombeirP/subscriptions", + "organizations_url": "https://api.github.com/users/PombeirP/orgs", + "repos_url": "https://api.github.com/users/PombeirP/repos", + "events_url": "https://api.github.com/users/PombeirP/events{/privacy}", + "received_events_url": "https://api.github.com/users/PombeirP/received_events", + "type": "User", + "site_admin": false + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Github-Event", "installation") + req.Header.Set("X-Hub-Signature", "sha1=987338c6e5c21794ab6c258abe51284f9b1df728") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + +func TestIntegrationInstallationEvent(t *testing.T) { + + payload := `{ + "action": "created", + "installation": { + "id": 80429, + "account": { + "login": "PombeirP", + "id": 138074, + "avatar_url": "https://avatars1.githubusercontent.com/u/138074?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/PombeirP", + "html_url": "https://github.com/PombeirP", + "followers_url": "https://api.github.com/users/PombeirP/followers", + "following_url": "https://api.github.com/users/PombeirP/following{/other_user}", + "gists_url": "https://api.github.com/users/PombeirP/gists{/gist_id}", + "starred_url": "https://api.github.com/users/PombeirP/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/PombeirP/subscriptions", + "organizations_url": "https://api.github.com/users/PombeirP/orgs", + "repos_url": "https://api.github.com/users/PombeirP/repos", + "events_url": "https://api.github.com/users/PombeirP/events{/privacy}", + "received_events_url": "https://api.github.com/users/PombeirP/received_events", + "type": "User", + "site_admin": false + }, + "repository_selection": "selected", + "access_tokens_url": "https://api.github.com/installations/80429/access_tokens", + "repositories_url": "https://api.github.com/installation/repositories", + "html_url": "https://github.com/settings/installations/80429", + "app_id": 8157, + "target_id": 138074, + "target_type": "User", + "permissions": { + "repository_projects": "write", + "issues": "read", + "metadata": "read", + "pull_requests": "read" + }, + "events": [ + "pull_request" + ], + "created_at": 1516025475, + "updated_at": 1516025475, + "single_file_name": null + }, + "repositories": [ + { + "id": 117381220, + "name": "status-github-bot", + "full_name": "PombeirP/status-github-bot" + } + ], + "sender": { + "login": "PombeirP", + "id": 138074, + "avatar_url": "https://avatars1.githubusercontent.com/u/138074?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/PombeirP", + "html_url": "https://github.com/PombeirP", + "followers_url": "https://api.github.com/users/PombeirP/followers", + "following_url": "https://api.github.com/users/PombeirP/following{/other_user}", + "gists_url": "https://api.github.com/users/PombeirP/gists{/gist_id}", + "starred_url": "https://api.github.com/users/PombeirP/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/PombeirP/subscriptions", + "organizations_url": "https://api.github.com/users/PombeirP/orgs", + "repos_url": "https://api.github.com/users/PombeirP/repos", + "events_url": "https://api.github.com/users/PombeirP/events{/privacy}", + "received_events_url": "https://api.github.com/users/PombeirP/received_events", + "type": "User", + "site_admin": false + } +} +` + + req, err := http.NewRequest("POST", "http://127.0.0.1:3010/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Github-Event", "integration_installation") + req.Header.Set("X-Hub-Signature", "sha1=987338c6e5c21794ab6c258abe51284f9b1df728") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) +} + func TestIssueCommentEvent(t *testing.T) { payload := `{ diff --git a/github/payload.go b/github/payload.go index 053c6ec..e247c09 100644 --- a/github/payload.go +++ b/github/payload.go @@ -1007,6 +1007,74 @@ type GollumPayload struct { } `json:"sender"` } +// InstallationPayload contains the information for GitHub's installation and integration_installation hook events +type InstallationPayload struct { + Action string `json:"action"` + Installation struct { + ID int64 `json:"id"` + Account struct { + Login string `json:"login"` + ID int64 `json:"id"` + AvatarURL string `json:"avatar_url"` + GravatarID string `json:"gravatar_id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + FollowersURL string `json:"followers_url"` + FollowingURL string `json:"following_url"` + GistsURL string `json:"gists_url"` + StarredURL string `json:"starred_url"` + SubscriptionsURL string `json:"subscriptions_url"` + OrganizationsURL string `json:"organizations_url"` + ReposURL string `json:"repos_url"` + EventsURL string `json:"events_url"` + ReceivedEventsURL string `json:"received_events_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } `json:"account"` + RepositorySelection string `json:"repository_selection"` + AccessTokensURL string `json:"access_tokens_url"` + RepositoriesURL string `json:"repositories_url"` + HTMLURL string `json:"html_url"` + AppID int `json:"app_id"` + TargetID int `json:"target_id"` + TargetType string `json:"target_type"` + Permissions struct { + Issues string `json:"issues"` + Metadata string `json:"metadata"` + PullRequests string `json:"pull_requests"` + RepositoryProjects string `json:"repository_projects"` + } `json:"permissions"` + Events []string `json:"events"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + SingleFileName *string `json:"single_file_name"` + } `json:"installation"` + Repositories []struct { + ID int64 `json:"id"` + Name string `json:"name"` + FullName string `json:"full_name"` + } `json:"repositories"` + Sender struct { + Login string `json:"login"` + ID int64 `json:"id"` + AvatarURL string `json:"avatar_url"` + GravatarID string `json:"gravatar_id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + FollowersURL string `json:"followers_url"` + FollowingURL string `json:"following_url"` + GistsURL string `json:"gists_url"` + StarredURL string `json:"starred_url"` + SubscriptionsURL string `json:"subscriptions_url"` + OrganizationsURL string `json:"organizations_url"` + ReposURL string `json:"repos_url"` + EventsURL string `json:"events_url"` + ReceivedEventsURL string `json:"received_events_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } `json:"sender"` +} + // IssueCommentPayload contains the information for GitHub's issue_comment hook event type IssueCommentPayload struct { Action string `json:"action"`