From b5c63cfb8553f70d168ae29c692e63da6418bb80 Mon Sep 17 00:00:00 2001 From: lumpleme Date: Sun, 26 May 2024 21:38:01 -0300 Subject: [PATCH] integrations: Prevent duplicate GitHub pull request review messages. GitHub sends two almost identical payloads when a pull request is reviewed, which results in two duplicative notification messages. The payloads have different "action" value, with one having the "submitted" action, whereas the other is "edited" and has an empty "changes" dict. We now ignore the payload with the "edited" action type and an empty "changes" dict. Fixes #26145. Co-authored-by: Pieter CK --- ..._request_review__edited_empty_changes.json | 515 ++++++++++++++++++ zerver/webhooks/github/tests.py | 4 + zerver/webhooks/github/view.py | 14 + 3 files changed, 533 insertions(+) create mode 100644 zerver/webhooks/github/fixtures/pull_request_review__edited_empty_changes.json diff --git a/zerver/webhooks/github/fixtures/pull_request_review__edited_empty_changes.json b/zerver/webhooks/github/fixtures/pull_request_review__edited_empty_changes.json new file mode 100644 index 0000000000..5b5ef24f86 --- /dev/null +++ b/zerver/webhooks/github/fixtures/pull_request_review__edited_empty_changes.json @@ -0,0 +1,515 @@ +{ + "action": "edited", + "review": { + "id": 1502757629, + "node_id": "PRR_kwDOJRp_V85ZkkL9", + "user": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "body": "abv", + "commit_id": "26b492c9c222ccec6cd828cedc6a5e86a71127fe", + "submitted_at": "2023-06-28T10:13:25Z", + "state": "commented", + "html_url": "https://github.com/sbansal1999/testing-gh/pull/16#pullrequestreview-1502757629", + "pull_request_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16", + "author_association": "OWNER", + "_links": { + "html": { + "href": "https://github.com/sbansal1999/testing-gh/pull/16#pullrequestreview-1502757629" + }, + "pull_request": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16" + } + } + }, + "pull_request": { + "url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16", + "id": 1411261664, + "node_id": "PR_kwDOJRp_V85UHiTg", + "html_url": "https://github.com/sbansal1999/testing-gh/pull/16", + "diff_url": "https://github.com/sbansal1999/testing-gh/pull/16.diff", + "patch_url": "https://github.com/sbansal1999/testing-gh/pull/16.patch", + "issue_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/16", + "number": 16, + "state": "open", + "locked": false, + "title": "Update first.txt", + "user": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "body": null, + "created_at": "2023-06-28T08:52:59Z", + "updated_at": "2023-06-28T10:13:26Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "4901b75d77578279eba6b380239c4645e54f9d12", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16/commits", + "review_comments_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16/comments", + "review_comment_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/16/comments", + "statuses_url": "https://api.github.com/repos/sbansal1999/testing-gh/statuses/26b492c9c222ccec6cd828cedc6a5e86a71127fe", + "head": { + "label": "sbansal1999:main", + "ref": "main", + "sha": "26b492c9c222ccec6cd828cedc6a5e86a71127fe", + "user": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 622493527, + "node_id": "R_kgDOJRp_Vw", + "name": "testing-gh", + "full_name": "sbansal1999/testing-gh", + "private": false, + "owner": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/sbansal1999/testing-gh", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/sbansal1999/testing-gh", + "forks_url": "https://api.github.com/repos/sbansal1999/testing-gh/forks", + "keys_url": "https://api.github.com/repos/sbansal1999/testing-gh/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/sbansal1999/testing-gh/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/sbansal1999/testing-gh/teams", + "hooks_url": "https://api.github.com/repos/sbansal1999/testing-gh/hooks", + "issue_events_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/events{/number}", + "events_url": "https://api.github.com/repos/sbansal1999/testing-gh/events", + "assignees_url": "https://api.github.com/repos/sbansal1999/testing-gh/assignees{/user}", + "branches_url": "https://api.github.com/repos/sbansal1999/testing-gh/branches{/branch}", + "tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/tags", + "blobs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/sbansal1999/testing-gh/statuses/{sha}", + "languages_url": "https://api.github.com/repos/sbansal1999/testing-gh/languages", + "stargazers_url": "https://api.github.com/repos/sbansal1999/testing-gh/stargazers", + "contributors_url": "https://api.github.com/repos/sbansal1999/testing-gh/contributors", + "subscribers_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscribers", + "subscription_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscription", + "commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/sbansal1999/testing-gh/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/sbansal1999/testing-gh/contents/{+path}", + "compare_url": "https://api.github.com/repos/sbansal1999/testing-gh/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/sbansal1999/testing-gh/merges", + "archive_url": "https://api.github.com/repos/sbansal1999/testing-gh/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/sbansal1999/testing-gh/downloads", + "issues_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues{/number}", + "pulls_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls{/number}", + "milestones_url": "https://api.github.com/repos/sbansal1999/testing-gh/milestones{/number}", + "notifications_url": "https://api.github.com/repos/sbansal1999/testing-gh/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/sbansal1999/testing-gh/labels{/name}", + "releases_url": "https://api.github.com/repos/sbansal1999/testing-gh/releases{/id}", + "deployments_url": "https://api.github.com/repos/sbansal1999/testing-gh/deployments", + "created_at": "2023-04-02T09:31:40Z", + "updated_at": "2023-04-02T09:31:40Z", + "pushed_at": "2023-06-28T08:52:59Z", + "git_url": "git://github.com/sbansal1999/testing-gh.git", + "ssh_url": "git@github.com:sbansal1999/testing-gh.git", + "clone_url": "https://github.com/sbansal1999/testing-gh.git", + "svn_url": "https://github.com/sbansal1999/testing-gh", + "homepage": null, + "size": 2, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 9, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 9, + "watchers": 0, + "default_branch": "fixing-typo", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "sbansal1999:fixing-typo", + "ref": "fixing-typo", + "sha": "aac9fffb3cb3f079b5555ac7476bc11e78248c99", + "user": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 622493527, + "node_id": "R_kgDOJRp_Vw", + "name": "testing-gh", + "full_name": "sbansal1999/testing-gh", + "private": false, + "owner": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/sbansal1999/testing-gh", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/sbansal1999/testing-gh", + "forks_url": "https://api.github.com/repos/sbansal1999/testing-gh/forks", + "keys_url": "https://api.github.com/repos/sbansal1999/testing-gh/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/sbansal1999/testing-gh/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/sbansal1999/testing-gh/teams", + "hooks_url": "https://api.github.com/repos/sbansal1999/testing-gh/hooks", + "issue_events_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/events{/number}", + "events_url": "https://api.github.com/repos/sbansal1999/testing-gh/events", + "assignees_url": "https://api.github.com/repos/sbansal1999/testing-gh/assignees{/user}", + "branches_url": "https://api.github.com/repos/sbansal1999/testing-gh/branches{/branch}", + "tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/tags", + "blobs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/sbansal1999/testing-gh/statuses/{sha}", + "languages_url": "https://api.github.com/repos/sbansal1999/testing-gh/languages", + "stargazers_url": "https://api.github.com/repos/sbansal1999/testing-gh/stargazers", + "contributors_url": "https://api.github.com/repos/sbansal1999/testing-gh/contributors", + "subscribers_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscribers", + "subscription_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscription", + "commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/sbansal1999/testing-gh/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/sbansal1999/testing-gh/contents/{+path}", + "compare_url": "https://api.github.com/repos/sbansal1999/testing-gh/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/sbansal1999/testing-gh/merges", + "archive_url": "https://api.github.com/repos/sbansal1999/testing-gh/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/sbansal1999/testing-gh/downloads", + "issues_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues{/number}", + "pulls_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls{/number}", + "milestones_url": "https://api.github.com/repos/sbansal1999/testing-gh/milestones{/number}", + "notifications_url": "https://api.github.com/repos/sbansal1999/testing-gh/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/sbansal1999/testing-gh/labels{/name}", + "releases_url": "https://api.github.com/repos/sbansal1999/testing-gh/releases{/id}", + "deployments_url": "https://api.github.com/repos/sbansal1999/testing-gh/deployments", + "created_at": "2023-04-02T09:31:40Z", + "updated_at": "2023-04-02T09:31:40Z", + "pushed_at": "2023-06-28T08:52:59Z", + "git_url": "git://github.com/sbansal1999/testing-gh.git", + "ssh_url": "git@github.com:sbansal1999/testing-gh.git", + "clone_url": "https://github.com/sbansal1999/testing-gh.git", + "svn_url": "https://github.com/sbansal1999/testing-gh", + "homepage": null, + "size": 2, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 9, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 9, + "watchers": 0, + "default_branch": "fixing-typo", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16" + }, + "html": { + "href": "https://github.com/sbansal1999/testing-gh/pull/16" + }, + "issue": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/issues/16" + }, + "comments": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/issues/16/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/pulls/16/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/sbansal1999/testing-gh/statuses/26b492c9c222ccec6cd828cedc6a5e86a71127fe" + } + }, + "author_association": "OWNER", + "auto_merge": null, + "active_lock_reason": null + }, + "changes": {}, + "repository": { + "id": 622493527, + "node_id": "R_kgDOJRp_Vw", + "name": "testing-gh", + "full_name": "sbansal1999/testing-gh", + "private": false, + "owner": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/sbansal1999/testing-gh", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/sbansal1999/testing-gh", + "forks_url": "https://api.github.com/repos/sbansal1999/testing-gh/forks", + "keys_url": "https://api.github.com/repos/sbansal1999/testing-gh/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/sbansal1999/testing-gh/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/sbansal1999/testing-gh/teams", + "hooks_url": "https://api.github.com/repos/sbansal1999/testing-gh/hooks", + "issue_events_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/events{/number}", + "events_url": "https://api.github.com/repos/sbansal1999/testing-gh/events", + "assignees_url": "https://api.github.com/repos/sbansal1999/testing-gh/assignees{/user}", + "branches_url": "https://api.github.com/repos/sbansal1999/testing-gh/branches{/branch}", + "tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/tags", + "blobs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/sbansal1999/testing-gh/statuses/{sha}", + "languages_url": "https://api.github.com/repos/sbansal1999/testing-gh/languages", + "stargazers_url": "https://api.github.com/repos/sbansal1999/testing-gh/stargazers", + "contributors_url": "https://api.github.com/repos/sbansal1999/testing-gh/contributors", + "subscribers_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscribers", + "subscription_url": "https://api.github.com/repos/sbansal1999/testing-gh/subscription", + "commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/sbansal1999/testing-gh/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/sbansal1999/testing-gh/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/sbansal1999/testing-gh/contents/{+path}", + "compare_url": "https://api.github.com/repos/sbansal1999/testing-gh/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/sbansal1999/testing-gh/merges", + "archive_url": "https://api.github.com/repos/sbansal1999/testing-gh/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/sbansal1999/testing-gh/downloads", + "issues_url": "https://api.github.com/repos/sbansal1999/testing-gh/issues{/number}", + "pulls_url": "https://api.github.com/repos/sbansal1999/testing-gh/pulls{/number}", + "milestones_url": "https://api.github.com/repos/sbansal1999/testing-gh/milestones{/number}", + "notifications_url": "https://api.github.com/repos/sbansal1999/testing-gh/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/sbansal1999/testing-gh/labels{/name}", + "releases_url": "https://api.github.com/repos/sbansal1999/testing-gh/releases{/id}", + "deployments_url": "https://api.github.com/repos/sbansal1999/testing-gh/deployments", + "created_at": "2023-04-02T09:31:40Z", + "updated_at": "2023-04-02T09:31:40Z", + "pushed_at": "2023-06-28T08:52:59Z", + "git_url": "git://github.com/sbansal1999/testing-gh.git", + "ssh_url": "git@github.com:sbansal1999/testing-gh.git", + "clone_url": "https://github.com/sbansal1999/testing-gh.git", + "svn_url": "https://github.com/sbansal1999/testing-gh", + "homepage": null, + "size": 2, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 9, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 9, + "watchers": 0, + "default_branch": "fixing-typo" + }, + "sender": { + "login": "sbansal1999", + "id": 35286603, + "node_id": "MDQ6VXNlcjM1Mjg2NjAz", + "avatar_url": "https://avatars.githubusercontent.com/u/35286603?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/sbansal1999", + "html_url": "https://github.com/sbansal1999", + "followers_url": "https://api.github.com/users/sbansal1999/followers", + "following_url": "https://api.github.com/users/sbansal1999/following{/other_user}", + "gists_url": "https://api.github.com/users/sbansal1999/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sbansal1999/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sbansal1999/subscriptions", + "organizations_url": "https://api.github.com/users/sbansal1999/orgs", + "repos_url": "https://api.github.com/users/sbansal1999/repos", + "events_url": "https://api.github.com/users/sbansal1999/events{/privacy}", + "received_events_url": "https://api.github.com/users/sbansal1999/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/zerver/webhooks/github/tests.py b/zerver/webhooks/github/tests.py index 1e8b9fbef1..1fac82d5c1 100644 --- a/zerver/webhooks/github/tests.py +++ b/zerver/webhooks/github/tests.py @@ -479,6 +479,10 @@ A temporary team so that I can get some webhook fixtures! payload = orjson.dumps(data).decode() self.verify_post_is_ignored(payload, "pull_request") + def test_pull_request_review_edited_empty_changes_ignore(self) -> None: + payload = self.get_body("pull_request_review__edited_empty_changes") + self.verify_post_is_ignored(payload, "pull_request_review") + def test_ignored_team_actions(self) -> None: ignored_actions = [ "added_to_repository", diff --git a/zerver/webhooks/github/view.py b/zerver/webhooks/github/view.py index ee10e23ed6..17d40ba03f 100644 --- a/zerver/webhooks/github/view.py +++ b/zerver/webhooks/github/view.py @@ -940,6 +940,12 @@ def api_github_webhook( return json_success(request) +def is_empty_pull_request_review_event(payload: WildValue) -> bool: + action = payload["action"].tame(check_string) + changes = payload.get("changes", {}) + return action == "edited" and len(changes) == 0 + + def get_zulip_event_name( header_event: str, payload: WildValue, @@ -970,6 +976,14 @@ def get_zulip_event_name( return "pull_request_auto_merge" if action in IGNORED_PULL_REQUEST_ACTIONS: return None + elif header_event == "pull_request_review": + if is_empty_pull_request_review_event(payload): + # When submitting a review, GitHub has a bug where it'll + # send a duplicate empty "edited" event for the main + # review body. Ignore those, to avoid triggering + # duplicate notifications. + return None + return "pull_request_review" elif header_event == "push": if is_merge_queue_push_event(payload): return None