diff --git a/README.md b/README.md index 588d6ba..5531f94 100644 --- a/README.md +++ b/README.md @@ -124,8 +124,10 @@ Once [installed](#usage), this integration will create a [check](https://developer.github.com/v3/checks/runs/) indicating whether commits in a Pull Request do not contain a valid `Signed-off-by` line. -Comment `@dcoapp recheck` on an open Pull Request to re-run or create the DCO -check, which can recover PRs stuck waiting for status after an outage. +To re-run or create the DCO check on an open Pull Request, submit a Pull +Request review with `@dcoapp recheck` on its own line in the review summary. +You can also add an inline review comment with `@dcoapp recheck` on its own +line. This can recover PRs stuck waiting for status after an outage. ![DCO success](https://user-images.githubusercontent.com/13410355/42352738-35f4e690-8071-11e8-9c8c-260e5868bfc8.png) ![DCO failure](https://user-images.githubusercontent.com/13410355/42352794-85fe1c9c-8071-11e8-834a-05a4aeb8cc90.png) diff --git a/REUSE.toml b/REUSE.toml index f196a72..2dcc9fe 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -9,9 +9,10 @@ path = [ "test/__snapshots__/index.test.js.snap", "test/fixtures/compare-success.json", "test/fixtures/compare.json", - "test/fixtures/issue_comment.created.json", "test/fixtures/pull_request.opened-success.json", "test/fixtures/pull_request.opened.json", + "test/fixtures/pull_request_review.submitted.json", + "test/fixtures/pull_request_review_comment.created.json", "test/fixtures/push.not-signed-off.json", "test/fixtures/push.signed-off.json", ] diff --git a/app.yml b/app.yml index 8a8cc19..a3e9d91 100644 --- a/app.yml +++ b/app.yml @@ -26,7 +26,7 @@ default_events: # - deployment_status # - fork # - gollum - - issue_comment + # - issue_comment # - issues # - label # - milestone @@ -40,8 +40,8 @@ default_events: # - project_column # - public - pull_request - # - pull_request_review - # - pull_request_review_comment + - pull_request_review + - pull_request_review_comment - push # - release # - repository diff --git a/index.js b/index.js index 9087608..f3754a4 100644 --- a/index.js +++ b/index.js @@ -143,17 +143,28 @@ module.exports = (app) => { } } - app.on("issue_comment.created", onRecheckComment); - async function onRecheckComment(context) { - const { comment, issue } = context.payload; - if (!issue.pull_request) return; - if (comment.user.type === "Bot") return; - if (issue.state !== "open") return; - if (comment.body.trim().toLowerCase() !== "@dcoapp recheck") return; + function isRecheckCommand(body) { + if (!body) return false; + return body + .split(/\r?\n/) + .some((line) => line.trim().toLowerCase() === "@dcoapp recheck"); + } - const { data: pr } = await context.octokit.rest.pulls.get( - context.repo({ pull_number: issue.number }) - ); + app.on("pull_request_review.submitted", onRecheckReview); + async function onRecheckReview(context) { + const { review, pull_request: pr } = context.payload; + if (review.user.type === "Bot") return; + if (pr.state !== "open") return; + if (!isRecheckCommand(review.body)) return; + await check(context, pr); + } + + app.on("pull_request_review_comment.created", onRecheckReviewComment); + async function onRecheckReviewComment(context) { + const { comment, pull_request: pr } = context.payload; + if (comment.user.type === "Bot") return; + if (pr.state !== "open") return; + if (!isRecheckCommand(comment.body)) return; await check(context, pr); } diff --git a/test/fixtures/issue_comment.created.json b/test/fixtures/issue_comment.created.json deleted file mode 100644 index e8d891c..0000000 --- a/test/fixtures/issue_comment.created.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "action": "created", - "issue": { - "number": 1, - "state": "open", - "pull_request": { - "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1", - "html_url": "https://github.com/octocat/Hello-World/pull/1", - "diff_url": "https://github.com/octocat/Hello-World/pull/1.diff", - "patch_url": "https://github.com/octocat/Hello-World/pull/1.patch" - } - }, - "comment": { - "id": 123456, - "body": "@dcoapp recheck", - "user": { - "login": "octocat", - "type": "User" - } - }, - "repository": { - "name": "Hello-World", - "full_name": "octocat/Hello-World", - "owner": { - "login": "octocat", - "type": "User" - }, - "default_branch": "master" - }, - "sender": { - "login": "octocat", - "type": "User" - } -} diff --git a/test/fixtures/pull_request_review.submitted.json b/test/fixtures/pull_request_review.submitted.json new file mode 100644 index 0000000..628bd56 --- /dev/null +++ b/test/fixtures/pull_request_review.submitted.json @@ -0,0 +1,459 @@ +{ + "action": "submitted", + "review": { + "id": 80, + "node_id": "MDE3OlB1bGxSZXF1ZXN0UmV2aWV3ODA=", + "user": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "type": "User", + "site_admin": false + }, + "body": "@dcoapp recheck", + "state": "commented", + "html_url": "https://github.com/octocat/Hello-World/pull/1#pullrequestreview-80", + "pull_request_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1", + "submitted_at": "2018-05-30T20:20:00Z", + "commit_id": "34c5c7793cb3b279e22454cb6750c80560547b3a", + "author_association": "CONTRIBUTOR" + }, + "pull_request": { + "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1", + "id": 191568743, + "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz", + "html_url": "https://github.com/octocat/Hello-World/pull/1", + "diff_url": "https://github.com/octocat/Hello-World/pull/1.diff", + "patch_url": "https://github.com/octocat/Hello-World/pull/1.patch", + "issue_url": "https://api.github.com/repos/octocat/Hello-World/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2018-05-30T20:18:30Z", + "updated_at": "2018-05-30T20:18:50Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "414cb0069601a32b00bd122a2380cd283626a8e5", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "commits_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/octocat/Hello-World/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1/comments", + "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a", + "head": { + "label": "octocat:changes", + "ref": "changes", + "sha": "34c5c7793cb3b279e22454cb6750c80560547b3a", + "user": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "octocat/Hello-World", + "owner": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/octocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/octocat/Hello-World", + "forks_url": "https://api.github.com/repos/octocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/octocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/octocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/octocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/octocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/octocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/octocat/Hello-World.git", + "ssh_url": "git@github.com:octocat/Hello-World.git", + "clone_url": "https://github.com/octocat/Hello-World.git", + "svn_url": "https://github.com/octocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "octocat:master", + "ref": "master", + "sha": "a10867b14bb761a232cd80139fbd4c0d33264240", + "user": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "octocat/Hello-World", + "owner": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/octocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/octocat/Hello-World", + "forks_url": "https://api.github.com/repos/octocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/octocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/octocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/octocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/octocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/octocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/octocat/Hello-World.git", + "ssh_url": "git@github.com:octocat/Hello-World.git", + "clone_url": "https://github.com/octocat/Hello-World.git", + "svn_url": "https://github.com/octocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/octocat/Hello-World/pulls/1" + }, + "html": { + "href": "https://github.com/octocat/Hello-World/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/octocat/Hello-World/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/octocat/Hello-World/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/octocat/Hello-World/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/octocat/Hello-World/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/octocat/Hello-World/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/octocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a" + } + }, + "author_association": "OWNER", + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 0, + "review_comments": 1, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "octocat/Hello-World", + "owner": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/octocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/octocat/Hello-World", + "forks_url": "https://api.github.com/repos/octocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/octocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/octocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/octocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/octocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/octocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/octocat/Hello-World.git", + "ssh_url": "git@github.com:octocat/Hello-World.git", + "clone_url": "https://github.com/octocat/Hello-World.git", + "svn_url": "https://github.com/octocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "octocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/test/fixtures/pull_request_review_comment.created.json b/test/fixtures/pull_request_review_comment.created.json new file mode 100644 index 0000000..f1d8c57 --- /dev/null +++ b/test/fixtures/pull_request_review_comment.created.json @@ -0,0 +1,455 @@ +{ + "action": "created", + "comment": { + "id": 123456, + "node_id": "MDEyOklzc3VlQ29tbWVudDEyMzQ1Ng==", + "body": "@dcoapp recheck", + "path": "README.md", + "position": 1, + "commit_id": "e76ed6025cec8879c75454a6efd6081d46de4c94", + "original_commit_id": "e76ed6025cec8879c75454a6efd6081d46de4c94", + "user": { + "login": "bkeepers", + "id": 173, + "type": "User", + "site_admin": true + }, + "created_at": "2017-09-22T23:22:00Z", + "updated_at": "2017-09-22T23:22:00Z", + "html_url": "https://github.com/robotland/test/pull/113#discussion_r123456", + "pull_request_url": "https://api.github.com/repos/robotland/test/pulls/113", + "author_association": "CONTRIBUTOR" + }, + "pull_request": { + "url": "https://api.github.com/repos/robotland/test/pulls/113", + "id": 142686911, + "html_url": "https://github.com/robotland/test/pull/113", + "diff_url": "https://github.com/robotland/test/pull/113.diff", + "patch_url": "https://github.com/robotland/test/pull/113.patch", + "issue_url": "https://api.github.com/repos/robotland/test/issues/113", + "number": 113, + "state": "open", + "locked": false, + "title": "DCO Test", + "user": { + "login": "bkeepers", + "id": 173, + "avatar_url": "https://avatars0.githubusercontent.com/u/173?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bkeepers", + "html_url": "https://github.com/bkeepers", + "followers_url": "https://api.github.com/users/bkeepers/followers", + "following_url": "https://api.github.com/users/bkeepers/following{/other_user}", + "gists_url": "https://api.github.com/users/bkeepers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bkeepers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bkeepers/subscriptions", + "organizations_url": "https://api.github.com/users/bkeepers/orgs", + "repos_url": "https://api.github.com/users/bkeepers/repos", + "events_url": "https://api.github.com/users/bkeepers/events{/privacy}", + "received_events_url": "https://api.github.com/users/bkeepers/received_events", + "type": "User", + "site_admin": true + }, + "body": "", + "created_at": "2017-09-22T23:21:03Z", + "updated_at": "2017-09-22T23:21:03Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": null, + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "milestone": null, + "commits_url": "https://api.github.com/repos/robotland/test/pulls/113/commits", + "review_comments_url": "https://api.github.com/repos/robotland/test/pulls/113/comments", + "review_comment_url": "https://api.github.com/repos/robotland/test/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/robotland/test/issues/113/comments", + "statuses_url": "https://api.github.com/repos/robotland/test/statuses/e76ed6025cec8879c75454a6efd6081d46de4c94", + "head": { + "label": "robotland:dco-test", + "ref": "dco-test", + "sha": "e76ed6025cec8879c75454a6efd6081d46de4c94", + "user": { + "login": "robotland", + "id": 11724939, + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robotland", + "html_url": "https://github.com/robotland", + "followers_url": "https://api.github.com/users/robotland/followers", + "following_url": "https://api.github.com/users/robotland/following{/other_user}", + "gists_url": "https://api.github.com/users/robotland/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robotland/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robotland/subscriptions", + "organizations_url": "https://api.github.com/users/robotland/orgs", + "repos_url": "https://api.github.com/users/robotland/repos", + "events_url": "https://api.github.com/users/robotland/events{/privacy}", + "received_events_url": "https://api.github.com/users/robotland/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 68474533, + "name": "test", + "full_name": "robotland/test", + "owner": { + "login": "robotland", + "id": 11724939, + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robotland", + "html_url": "https://github.com/robotland", + "followers_url": "https://api.github.com/users/robotland/followers", + "following_url": "https://api.github.com/users/robotland/following{/other_user}", + "gists_url": "https://api.github.com/users/robotland/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robotland/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robotland/subscriptions", + "organizations_url": "https://api.github.com/users/robotland/orgs", + "repos_url": "https://api.github.com/users/robotland/repos", + "events_url": "https://api.github.com/users/robotland/events{/privacy}", + "received_events_url": "https://api.github.com/users/robotland/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/robotland/test", + "description": "a trainable robot that responds to activity on GitHub", + "fork": false, + "url": "https://api.github.com/repos/robotland/test", + "forks_url": "https://api.github.com/repos/robotland/test/forks", + "keys_url": "https://api.github.com/repos/robotland/test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/robotland/test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/robotland/test/teams", + "hooks_url": "https://api.github.com/repos/robotland/test/hooks", + "issue_events_url": "https://api.github.com/repos/robotland/test/issues/events{/number}", + "events_url": "https://api.github.com/repos/robotland/test/events", + "assignees_url": "https://api.github.com/repos/robotland/test/assignees{/user}", + "branches_url": "https://api.github.com/repos/robotland/test/branches{/branch}", + "tags_url": "https://api.github.com/repos/robotland/test/tags", + "blobs_url": "https://api.github.com/repos/robotland/test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/robotland/test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/robotland/test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/robotland/test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/robotland/test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/robotland/test/languages", + "stargazers_url": "https://api.github.com/repos/robotland/test/stargazers", + "contributors_url": "https://api.github.com/repos/robotland/test/contributors", + "subscribers_url": "https://api.github.com/repos/robotland/test/subscribers", + "subscription_url": "https://api.github.com/repos/robotland/test/subscription", + "commits_url": "https://api.github.com/repos/robotland/test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/robotland/test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/robotland/test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/robotland/test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/robotland/test/contents/{+path}", + "compare_url": "https://api.github.com/repos/robotland/test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/robotland/test/merges", + "archive_url": "https://api.github.com/repos/robotland/test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/robotland/test/downloads", + "issues_url": "https://api.github.com/repos/robotland/test/issues{/number}", + "pulls_url": "https://api.github.com/repos/robotland/test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/robotland/test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/robotland/test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/robotland/test/labels{/name}", + "releases_url": "https://api.github.com/repos/robotland/test/releases{/id}", + "deployments_url": "https://api.github.com/repos/robotland/test/deployments", + "created_at": "2016-09-17T19:44:06Z", + "updated_at": "2017-09-05T17:14:12Z", + "pushed_at": "2017-09-22T23:20:57Z", + "git_url": "git://github.com/robotland/test.git", + "ssh_url": "git@github.com:robotland/test.git", + "clone_url": "https://github.com/robotland/test.git", + "svn_url": "https://github.com/robotland/test", + "homepage": "https://probot.github.io/", + "size": 39, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "robotland:master", + "ref": "master", + "sha": "607c64cd8e37eb2db939f99a17bee5c7d1a90a31", + "user": { + "login": "robotland", + "id": 11724939, + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robotland", + "html_url": "https://github.com/robotland", + "followers_url": "https://api.github.com/users/robotland/followers", + "following_url": "https://api.github.com/users/robotland/following{/other_user}", + "gists_url": "https://api.github.com/users/robotland/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robotland/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robotland/subscriptions", + "organizations_url": "https://api.github.com/users/robotland/orgs", + "repos_url": "https://api.github.com/users/robotland/repos", + "events_url": "https://api.github.com/users/robotland/events{/privacy}", + "received_events_url": "https://api.github.com/users/robotland/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 68474533, + "name": "test", + "full_name": "robotland/test", + "owner": { + "login": "robotland", + "id": 11724939, + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robotland", + "html_url": "https://github.com/robotland", + "followers_url": "https://api.github.com/users/robotland/followers", + "following_url": "https://api.github.com/users/robotland/following{/other_user}", + "gists_url": "https://api.github.com/users/robotland/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robotland/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robotland/subscriptions", + "organizations_url": "https://api.github.com/users/robotland/orgs", + "repos_url": "https://api.github.com/users/robotland/repos", + "events_url": "https://api.github.com/users/robotland/events{/privacy}", + "received_events_url": "https://api.github.com/users/robotland/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/robotland/test", + "description": "a trainable robot that responds to activity on GitHub", + "fork": false, + "url": "https://api.github.com/repos/robotland/test", + "forks_url": "https://api.github.com/repos/robotland/test/forks", + "keys_url": "https://api.github.com/repos/robotland/test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/robotland/test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/robotland/test/teams", + "hooks_url": "https://api.github.com/repos/robotland/test/hooks", + "issue_events_url": "https://api.github.com/repos/robotland/test/issues/events{/number}", + "events_url": "https://api.github.com/repos/robotland/test/events", + "assignees_url": "https://api.github.com/repos/robotland/test/assignees{/user}", + "branches_url": "https://api.github.com/repos/robotland/test/branches{/branch}", + "tags_url": "https://api.github.com/repos/robotland/test/tags", + "blobs_url": "https://api.github.com/repos/robotland/test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/robotland/test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/robotland/test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/robotland/test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/robotland/test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/robotland/test/languages", + "stargazers_url": "https://api.github.com/repos/robotland/test/stargazers", + "contributors_url": "https://api.github.com/repos/robotland/test/contributors", + "subscribers_url": "https://api.github.com/repos/robotland/test/subscribers", + "subscription_url": "https://api.github.com/repos/robotland/test/subscription", + "commits_url": "https://api.github.com/repos/robotland/test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/robotland/test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/robotland/test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/robotland/test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/robotland/test/contents/{+path}", + "compare_url": "https://api.github.com/repos/robotland/test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/robotland/test/merges", + "archive_url": "https://api.github.com/repos/robotland/test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/robotland/test/downloads", + "issues_url": "https://api.github.com/repos/robotland/test/issues{/number}", + "pulls_url": "https://api.github.com/repos/robotland/test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/robotland/test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/robotland/test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/robotland/test/labels{/name}", + "releases_url": "https://api.github.com/repos/robotland/test/releases{/id}", + "deployments_url": "https://api.github.com/repos/robotland/test/deployments", + "created_at": "2016-09-17T19:44:06Z", + "updated_at": "2017-09-05T17:14:12Z", + "pushed_at": "2017-09-22T23:20:57Z", + "git_url": "git://github.com/robotland/test.git", + "ssh_url": "git@github.com:robotland/test.git", + "clone_url": "https://github.com/robotland/test.git", + "svn_url": "https://github.com/robotland/test", + "homepage": "https://probot.github.io/", + "size": 39, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/robotland/test/pulls/113" + }, + "html": { + "href": "https://github.com/robotland/test/pull/113" + }, + "issue": { + "href": "https://api.github.com/repos/robotland/test/issues/113" + }, + "comments": { + "href": "https://api.github.com/repos/robotland/test/issues/113/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/robotland/test/pulls/113/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/robotland/test/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/robotland/test/pulls/113/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/robotland/test/statuses/e76ed6025cec8879c75454a6efd6081d46de4c94" + } + }, + "author_association": "CONTRIBUTOR", + "merged": false, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 68474533, + "name": "test", + "full_name": "robotland/test", + "owner": { + "login": "robotland", + "id": 11724939, + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/robotland", + "html_url": "https://github.com/robotland", + "followers_url": "https://api.github.com/users/robotland/followers", + "following_url": "https://api.github.com/users/robotland/following{/other_user}", + "gists_url": "https://api.github.com/users/robotland/gists{/gist_id}", + "starred_url": "https://api.github.com/users/robotland/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/robotland/subscriptions", + "organizations_url": "https://api.github.com/users/robotland/orgs", + "repos_url": "https://api.github.com/users/robotland/repos", + "events_url": "https://api.github.com/users/robotland/events{/privacy}", + "received_events_url": "https://api.github.com/users/robotland/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/robotland/test", + "description": "a trainable robot that responds to activity on GitHub", + "fork": false, + "url": "https://api.github.com/repos/robotland/test", + "forks_url": "https://api.github.com/repos/robotland/test/forks", + "keys_url": "https://api.github.com/repos/robotland/test/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/robotland/test/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/robotland/test/teams", + "hooks_url": "https://api.github.com/repos/robotland/test/hooks", + "issue_events_url": "https://api.github.com/repos/robotland/test/issues/events{/number}", + "events_url": "https://api.github.com/repos/robotland/test/events", + "assignees_url": "https://api.github.com/repos/robotland/test/assignees{/user}", + "branches_url": "https://api.github.com/repos/robotland/test/branches{/branch}", + "tags_url": "https://api.github.com/repos/robotland/test/tags", + "blobs_url": "https://api.github.com/repos/robotland/test/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/robotland/test/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/robotland/test/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/robotland/test/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/robotland/test/statuses/{sha}", + "languages_url": "https://api.github.com/repos/robotland/test/languages", + "stargazers_url": "https://api.github.com/repos/robotland/test/stargazers", + "contributors_url": "https://api.github.com/repos/robotland/test/contributors", + "subscribers_url": "https://api.github.com/repos/robotland/test/subscribers", + "subscription_url": "https://api.github.com/repos/robotland/test/subscription", + "commits_url": "https://api.github.com/repos/robotland/test/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/robotland/test/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/robotland/test/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/robotland/test/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/robotland/test/contents/{+path}", + "compare_url": "https://api.github.com/repos/robotland/test/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/robotland/test/merges", + "archive_url": "https://api.github.com/repos/robotland/test/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/robotland/test/downloads", + "issues_url": "https://api.github.com/repos/robotland/test/issues{/number}", + "pulls_url": "https://api.github.com/repos/robotland/test/pulls{/number}", + "milestones_url": "https://api.github.com/repos/robotland/test/milestones{/number}", + "notifications_url": "https://api.github.com/repos/robotland/test/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/robotland/test/labels{/name}", + "releases_url": "https://api.github.com/repos/robotland/test/releases{/id}", + "deployments_url": "https://api.github.com/repos/robotland/test/deployments", + "created_at": "2016-09-17T19:44:06Z", + "updated_at": "2017-09-05T17:14:12Z", + "pushed_at": "2017-09-22T23:20:57Z", + "git_url": "git://github.com/robotland/test.git", + "ssh_url": "git@github.com:robotland/test.git", + "clone_url": "https://github.com/robotland/test.git", + "svn_url": "https://github.com/robotland/test", + "homepage": "https://probot.github.io/", + "size": 39, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "robotland", + "id": 11724939, + "url": "https://api.github.com/orgs/robotland", + "repos_url": "https://api.github.com/orgs/robotland/repos", + "events_url": "https://api.github.com/orgs/robotland/events", + "hooks_url": "https://api.github.com/orgs/robotland/hooks", + "issues_url": "https://api.github.com/orgs/robotland/issues", + "members_url": "https://api.github.com/orgs/robotland/members{/member}", + "public_members_url": "https://api.github.com/orgs/robotland/public_members{/member}", + "avatar_url": "https://avatars2.githubusercontent.com/u/11724939?v=4", + "description": null + }, + "sender": { + "login": "bkeepers", + "id": 173, + "avatar_url": "https://avatars0.githubusercontent.com/u/173?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bkeepers", + "html_url": "https://github.com/bkeepers", + "followers_url": "https://api.github.com/users/bkeepers/followers", + "following_url": "https://api.github.com/users/bkeepers/following{/other_user}", + "gists_url": "https://api.github.com/users/bkeepers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bkeepers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bkeepers/subscriptions", + "organizations_url": "https://api.github.com/users/bkeepers/orgs", + "repos_url": "https://api.github.com/users/bkeepers/repos", + "events_url": "https://api.github.com/users/bkeepers/events{/privacy}", + "received_events_url": "https://api.github.com/users/bkeepers/received_events", + "type": "User", + "site_admin": true + } +} diff --git a/test/index.test.js b/test/index.test.js index a8010b0..8f7bf5f 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -7,7 +7,8 @@ const dco = require(".."); const payload = require("./fixtures/pull_request.opened"); const payloadSuccess = require("./fixtures/pull_request.opened-success"); -const issueCommentPayload = require("./fixtures/issue_comment.created"); +const pullRequestReviewPayload = require("./fixtures/pull_request_review.submitted"); +const pullRequestReviewCommentPayload = require("./fixtures/pull_request_review_comment.created"); const compare = require("./fixtures/compare"); const compareSuccess = require("./fixtures/compare-success"); @@ -545,47 +546,40 @@ allowRemediationCommits: }); }); - describe("issue_comment.created event", () => { - test("ignores comments that are not on a pull request", async () => { - const payload = structuredClone(issueCommentPayload); - delete payload.issue.pull_request; + describe("pull_request_review.submitted event", () => { + test("ignores reviews from bots", async () => { + const payload = structuredClone(pullRequestReviewPayload); + payload.review.user.type = "Bot"; - await probot.receive({ name: "issue_comment", payload }); + await probot.receive({ name: "pull_request_review", payload }); }); - test("ignores comments from bots", async () => { - const payload = structuredClone(issueCommentPayload); - payload.comment.user.type = "Bot"; + test("ignores reviews on closed pull requests", async () => { + const payload = structuredClone(pullRequestReviewPayload); + payload.pull_request.state = "closed"; - await probot.receive({ name: "issue_comment", payload }); + await probot.receive({ name: "pull_request_review", payload }); }); - test("ignores comments on closed pull requests", async () => { - const payload = structuredClone(issueCommentPayload); - payload.issue.state = "closed"; + test("ignores reviews with empty bodies", async () => { + const payload = structuredClone(pullRequestReviewPayload); + payload.review.body = null; - await probot.receive({ name: "issue_comment", payload }); + await probot.receive({ name: "pull_request_review", payload }); }); - test("ignores comments without the exact recheck command", async () => { - const payload = structuredClone(issueCommentPayload); - payload.comment.body = "@dcoapp recheck please"; + test("ignores reviews without the recheck command on its own line", async () => { + const payload = structuredClone(pullRequestReviewPayload); + payload.review.body = "please @dcoapp recheck"; - await probot.receive({ name: "issue_comment", payload }); + await probot.receive({ name: "pull_request_review", payload }); }); - test("creates a passing check for recheck comments", async () => { - const payload = structuredClone(issueCommentPayload); - payload.comment.body = " @DCOApp Recheck "; - const pullRequest = { - ...payloadSuccess.pull_request, - closed_at: null, - state: "open", - }; + test("creates a passing check for recheck reviews", async () => { + const payload = structuredClone(pullRequestReviewPayload); + payload.review.body = "please run\n @DCOApp Recheck \nthanks"; const mock = nock("https://api.github.com") - .get("/repos/octocat/Hello-World/pulls/1") - .reply(200, pullRequest) // no config .get("/repos/octocat/Hello-World/contents/.github%2Fdco.yml") .reply(404) @@ -616,7 +610,120 @@ allowRemediationCommits: }) .reply(200); - await probot.receive({ name: "issue_comment", payload }); + await probot.receive({ name: "pull_request_review", payload }); + + expect(mock.activeMocks()).toStrictEqual([]); + }); + }); + + describe("pull_request_review_comment.created event", () => { + test("ignores review comments from bots", async () => { + const payload = structuredClone(pullRequestReviewCommentPayload); + payload.comment.user.type = "Bot"; + + await probot.receive({ name: "pull_request_review_comment", payload }); + }); + + test("ignores review comments on closed pull requests", async () => { + const payload = structuredClone(pullRequestReviewCommentPayload); + payload.pull_request.state = "closed"; + + await probot.receive({ name: "pull_request_review_comment", payload }); + }); + + test("ignores review comments with empty bodies", async () => { + const payload = structuredClone(pullRequestReviewCommentPayload); + payload.comment.body = null; + + await probot.receive({ name: "pull_request_review_comment", payload }); + }); + + test("ignores review comments without the recheck command on its own line", async () => { + const payload = structuredClone(pullRequestReviewCommentPayload); + payload.comment.body = "@dcoapp recheck please"; + + await probot.receive({ name: "pull_request_review_comment", payload }); + }); + + test("creates a failing check for recheck review comments", async () => { + const payload = structuredClone(pullRequestReviewCommentPayload); + payload.comment.body = "Please rerun.\r\n@dcoapp recheck\r\nThanks!"; + + const mock = nock("https://api.github.com") + .get("/repos/robotland/test/contents/.github%2Fdco.yml") + .reply(404) + .get("/repos/robotland/.github/contents/.github%2Fdco.yml") + .reply(404) + + .get( + "/repos/robotland/test/compare/607c64cd8e37eb2db939f99a17bee5c7d1a90a31...e76ed6025cec8879c75454a6efd6081d46de4c94" + ) + .reply(200, compare) + + .post("/repos/robotland/test/check-runs", (body) => { + body.started_at = "2018-07-14T18:18:54.156Z"; + body.completed_at = "2018-07-14T18:18:54.156Z"; + expect(body).toMatchObject({ + conclusion: "action_required", + head_branch: "dco-test", + head_sha: "e76ed6025cec8879c75454a6efd6081d46de4c94", + name: "DCO", + output: { + title: "DCO", + }, + status: "completed", + }); + expect(body.output.summary).toContain("The sign-off is missing."); + + return true; + }) + .reply(200); + + await probot.receive({ name: "pull_request_review_comment", payload }); + + expect(mock.activeMocks()).toStrictEqual([]); + }); + + test("checks org membership for require.members: false review comments", async () => { + const mock = nock("https://api.github.com") + .get("/repos/robotland/test/contents/.github%2Fdco.yml") + .reply( + 200, + ` + require: + members: false` + ) + + .get( + "/repos/robotland/test/compare/607c64cd8e37eb2db939f99a17bee5c7d1a90a31...e76ed6025cec8879c75454a6efd6081d46de4c94" + ) + .reply(200, compare) + + .get("/orgs/robotland/members/bkeepers") + .reply(204) + + .post("/repos/robotland/test/check-runs", (body) => { + body.started_at = "2018-07-14T18:18:54.156Z"; + body.completed_at = "2018-07-14T18:18:54.156Z"; + expect(body).toMatchObject({ + conclusion: "action_required", + head_branch: "dco-test", + head_sha: "e76ed6025cec8879c75454a6efd6081d46de4c94", + name: "DCO", + output: { + title: "DCO", + }, + status: "completed", + }); + + return true; + }) + .reply(200); + + await probot.receive({ + name: "pull_request_review_comment", + payload: pullRequestReviewCommentPayload, + }); expect(mock.activeMocks()).toStrictEqual([]); });