diff --git a/connections/gitlab.py b/connections/gitlab.py index 30da0858..0a1c03ea 100644 --- a/connections/gitlab.py +++ b/connections/gitlab.py @@ -63,9 +63,7 @@ def connect(): else: del os.environ['GITLAB_PROJECT_ACCESS_TOKEN'] - _gl = gitlab.Gitlab(url, access_token) - _gl.timeout = timeout - _gl.retry_transient_errors = True + _gl = gitlab.Gitlab(url, access_token, timeout=timeout, retry_transient_errors=True) verify_connection(_gl) diff --git a/test/events/github/comment-created.json b/test/events/github/comment-created.json new file mode 100644 index 00000000..f1a286e2 --- /dev/null +++ b/test/events/github/comment-created.json @@ -0,0 +1,286 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "10707", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781521518638", + "User-Agent": "GitHub-Hookshot/831a06e", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "17489dc0-68aa-11f1-8ed0-d59b5d8018bb", + "X-Github-Event": "issue_comment", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=60cbee676aab387b71581fe44de1acf097698009", + "X-Hub-Signature-256": "sha256=d8e840eadfbd4e618b5b973fe724e85052e5ca9a8a4fdebe8c3614e74efd4402", + "X-Real-Ip": "140.82.115.100", + "X-Request-Id": "f19e7514808880ae7ef08dab43123b4a", + "X-Scheme": "https" + }, + "json": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "bot:help", + "created_at": "2026-06-15T11:05:16Z", + "html_url": "https://github.com/testuser/software-layer/pull/5#issuecomment-5432112345", + "id": 5432112345, + "issue_url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "node_id": "IC_kwDOQngT988AAAABQ8d02Q", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/testuser/software-layer/issues/comments/5432112345/reactions" + }, + "updated_at": "2026-06-15T11:05:16Z", + "url": "https://api.github.com/repos/testuser/software-layer/issues/comments/5432112345", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "installation": { + "id": 99999999, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uOTk5OTk5OTk=" + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "Test", + "closed_at": "2026-06-11T13:28:31Z", + "comments": 11, + "comments_url": "https://api.github.com/repos/testuser/software-layer/issues/5/comments", + "created_at": "2026-06-11T13:14:20Z", + "draft": false, + "events_url": "https://api.github.com/repos/testuser/software-layer/issues/5/events", + "html_url": "https://github.com/testuser/software-layer/pull/5", + "id": 9876543210, + "labels": [ + { + "color": "87DA77", + "default": false, + "description": "", + "id": 1234554321, + "name": "test:label", + "node_id": "LA_kwDOQngT988AAAAASZXN0Q", + "url": "https://api.github.com/repos/testuser/software-layer/labels/test:label" + } + ], + "labels_url": "https://api.github.com/repos/testuser/software-layer/issues/5/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOxmQDYCGSUsFF", + "number": 5, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/testuser/software-layer/pull/5.diff", + "html_url": "https://github.com/testuser/software-layer/pull/5", + "merged_at": "2026-06-11T13:28:31Z", + "patch_url": "https://github.com/testuser/software-layer/pull/5.patch", + "url": "https://api.github.com/repos/testuser/software-layer/pulls/5" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/testuser/software-layer/issues/5/reactions" + }, + "repository_url": "https://api.github.com/repos/testuser/software-layer", + "state": "closed", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/testuser/software-layer/issues/5/timeline", + "title": "Add software", + "updated_at": "2026-06-15T11:05:16Z", + "url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 2, + "open_issues_count": 2, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:28:31Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4528, + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-06-11T13:34:25Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/github/comment-edited.json b/test/events/github/comment-edited.json new file mode 100644 index 00000000..9665217e --- /dev/null +++ b/test/events/github/comment-edited.json @@ -0,0 +1,291 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "10746", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781521590887", + "User-Agent": "GitHub-Hookshot/831a06e", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "426dfef0-68aa-11f1-957d-14867d39f0e5", + "X-Github-Event": "issue_comment", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=9da7a5ee0eca6c56259bed8acf691b5442ed282b", + "X-Hub-Signature-256": "sha256=815eb1639d65692b4762ee9446146adb3c00cb96427cc753ffa0fc056ad23bd8", + "X-Real-Ip": "140.82.115.152", + "X-Request-Id": "3a33172d91f35ab474ab0576aba8c950", + "X-Scheme": "https" + }, + "json": { + "action": "edited", + "changes": { + "body": { + "from": "bot:help" + } + }, + "comment": { + "author_association": "OWNER", + "body": "bot: help", + "created_at": "2026-06-15T11:05:16Z", + "html_url": "https://github.com/testuser/software-layer/pull/5#issuecomment-5432112345", + "id": 5432112345, + "issue_url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "node_id": "IC_kwDOQngT988AAAABQ8d02Q", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/testuser/software-layer/issues/comments/5432112345/reactions" + }, + "updated_at": "2026-06-15T11:06:29Z", + "url": "https://api.github.com/repos/testuser/software-layer/issues/comments/5432112345", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "installation": { + "id": 99999999, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uOTk5OTk5OTk=" + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "Test", + "closed_at": "2026-06-11T13:28:31Z", + "comments": 12, + "comments_url": "https://api.github.com/repos/testuser/software-layer/issues/5/comments", + "created_at": "2026-06-11T13:14:20Z", + "draft": false, + "events_url": "https://api.github.com/repos/testuser/software-layer/issues/5/events", + "html_url": "https://github.com/testuser/software-layer/pull/5", + "id": 9876543210, + "labels": [ + { + "color": "87DA77", + "default": false, + "description": "", + "id": 1234554321, + "name": "test:label", + "node_id": "LA_kwDOQngT988AAAAASZXN0Q", + "url": "https://api.github.com/repos/testuser/software-layer/labels/test:label" + } + ], + "labels_url": "https://api.github.com/repos/testuser/software-layer/issues/5/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOxmQDYCGSUsFF", + "number": 5, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/testuser/software-layer/pull/5.diff", + "html_url": "https://github.com/testuser/software-layer/pull/5", + "merged_at": "2026-06-11T13:28:31Z", + "patch_url": "https://github.com/testuser/software-layer/pull/5.patch", + "url": "https://api.github.com/repos/testuser/software-layer/pulls/5" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/testuser/software-layer/issues/5/reactions" + }, + "repository_url": "https://api.github.com/repos/testuser/software-layer", + "state": "closed", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/testuser/software-layer/issues/5/timeline", + "title": "Add software", + "updated_at": "2026-06-15T11:05:22Z", + "url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 2, + "open_issues_count": 2, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:28:31Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4528, + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-06-11T13:34:25Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123412345?v=4", + "events_url": "https://api.github.com/users/othertestuser/events{/privacy}", + "followers_url": "https://api.github.com/users/othertestuser/followers", + "following_url": "https://api.github.com/users/othertestuser/following{/other_user}", + "gists_url": "https://api.github.com/users/othertestuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/othertestuser", + "id": 123412345, + "login": "othertestuser", + "node_id": "U_kgDOB1sfeQ", + "organizations_url": "https://api.github.com/users/othertestuser/orgs", + "received_events_url": "https://api.github.com/users/othertestuser/received_events", + "repos_url": "https://api.github.com/users/othertestuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/othertestuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/othertestuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/othertestuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/github/installation-created.json b/test/events/github/installation-created.json new file mode 100644 index 00000000..c33e85de --- /dev/null +++ b/test/events/github/installation-created.json @@ -0,0 +1,108 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "2818", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781253687553", + "User-Agent": "GitHub-Hookshot/831a06e", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "7f87ab50-663a-11f1-8fd8-f855b3665b48", + "X-Github-Event": "installation", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=c8e2663458dba026dea527d25f421a1096576350", + "X-Hub-Signature-256": "sha256=2b0c3f55b9d15f0a395453232b476e865efaea71b7effdda6a712116b39456bb", + "X-Real-Ip": "140.82.115.112", + "X-Request-Id": "700c2d29c5f2c95eaf403706223f9e1d", + "X-Scheme": "https" + }, + "json": { + "action": "created", + "installation": { + "access_tokens_url": "https://api.github.com/app/installations/99999999/access_tokens", + "account": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "app_id": 1234567, + "app_slug": "test-eessi-bot", + "client_id": "Iv2368hOu46EpbKV0zmA", + "created_at": "2026-06-12T10:41:25.000+02:00", + "events": [ + "issue_comment", + "pull_request" + ], + "has_multiple_single_files": false, + "html_url": "https://github.com/settings/installations/99999999", + "id": 99999999, + "permissions": { + "issues": "write", + "metadata": "read", + "pull_requests": "write" + }, + "repositories_url": "https://api.github.com/installation/repositories", + "repository_selection": "selected", + "single_file_name": null, + "single_file_paths": [], + "suspended_at": null, + "suspended_by": null, + "target_id": 123456789, + "target_type": "User", + "updated_at": "2026-06-12T10:41:26.000+02:00" + }, + "repositories": [ + { + "full_name": "testuser/software-layer", + "id": 1234567890, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "private": false + } + ], + "requester": null, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/github/pr-closed.json b/test/events/github/pr-closed.json new file mode 100644 index 00000000..c1ea09f0 --- /dev/null +++ b/test/events/github/pr-closed.json @@ -0,0 +1,578 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "24476", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781184514173", + "User-Agent": "GitHub-Hookshot/576ea10", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "70de6220-6599-11f1-86f1-59c488adc2c1", + "X-Github-Event": "pull_request", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=2f0154cff35b3d29c04559b13dae592e540b9273", + "X-Hub-Signature-256": "sha256=4f7bcd149bcfdb1ed13085ed70dac856f5eef05870a128d4e3fd53160424e1dd", + "X-Real-Ip": "140.82.115.47", + "X-Request-Id": "498161a3e1c8cc06e091ee3f2c6be416", + "X-Scheme": "https" + }, + "json": { + "action": "closed", + "installation": { + "id": 99999999, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uOTk5OTk5OTk=" + }, + "number": 5, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5/comments" + }, + "commits": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits" + }, + "html": { + "href": "https://github.com/testuser/software-layer/pull/5" + }, + "issue": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5" + }, + "review_comment": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments" + }, + "self": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5" + }, + "statuses": { + "href": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0" + } + }, + "active_lock_reason": null, + "additions": 2, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "testuser:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 2, + "open_issues_count": 2, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "0a1e785fad6fa4d19fa397e693dbd4ae36585fdf", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "body": "Test", + "changed_files": 1, + "closed_at": "2026-06-11T13:28:31Z", + "comments": 1, + "comments_url": "https://api.github.com/repos/testuser/software-layer/issues/5/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits", + "created_at": "2026-06-11T13:14:20Z", + "deletions": 0, + "diff_url": "https://github.com/testuser/software-layer/pull/5.diff", + "draft": false, + "head": { + "label": "testuser:add-software", + "ref": "add-software", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 2, + "open_issues_count": 2, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "html_url": "https://github.com/testuser/software-layer/pull/5", + "id": 9876543210, + "issue_url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "labels": [ + { + "color": "87DA77", + "default": false, + "description": "", + "id": 1234554321, + "name": "test:label", + "node_id": "LA_kwDOQngT988AAAAASZXN0Q", + "url": "https://api.github.com/repos/testuser/software-layer/labels/test:label" + } + ], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "8b7bf21a77ab5cbe36d7c0e5fa88948773e5ccc8", + "mergeable": null, + "mergeable_state": "unknown", + "merged": true, + "merged_at": "2026-06-11T13:28:31Z", + "merged_by": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "milestone": null, + "node_id": "PR_kwDOxmQDYCGSUsFF", + "number": 5, + "patch_url": "https://github.com/testuser/software-layer/pull/5.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments", + "state": "closed", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "title": "Add software", + "updated_at": "2026-06-11T13:28:32Z", + "url": "https://api.github.com/repos/testuser/software-layer/pulls/5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 2, + "open_issues_count": 2, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/github/pr-labeled.json b/test/events/github/pr-labeled.json new file mode 100644 index 00000000..f271bf9d --- /dev/null +++ b/test/events/github/pr-labeled.json @@ -0,0 +1,567 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "23728", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781184286813", + "User-Agent": "GitHub-Hookshot/576ea10", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "e96b3e30-6598-11f1-93dc-70f33fc65c00", + "X-Github-Event": "pull_request", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=5a93d16d8ffc16f5542ba32e8b8d6ff5f63346f7", + "X-Hub-Signature-256": "sha256=216278f604ad570ca566a7a82845c2c72acd47aa28ab27d4198d0ed024d5e596", + "X-Real-Ip": "140.82.115.58", + "X-Request-Id": "f18feb1f6e7b4a4c1597e43600736924", + "X-Scheme": "https" + }, + "json": { + "action": "labeled", + "installation": { + "id": 99999999, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uOTk5OTk5OTk=" + }, + "label": { + "color": "87DA77", + "default": false, + "description": "", + "id": 1234554321, + "name": "test:label", + "node_id": "LA_kwDOQngT988AAAAASZXN0Q", + "url": "https://api.github.com/repos/testuser/software-layer/labels/test:label" + }, + "number": 5, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5/comments" + }, + "commits": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits" + }, + "html": { + "href": "https://github.com/testuser/software-layer/pull/5" + }, + "issue": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5" + }, + "review_comment": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments" + }, + "self": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5" + }, + "statuses": { + "href": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0" + } + }, + "active_lock_reason": null, + "additions": 2, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "testuser:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "0a1e785fad6fa4d19fa397e693dbd4ae36585fdf", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "body": "Test", + "changed_files": 1, + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/testuser/software-layer/issues/5/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits", + "created_at": "2026-06-11T13:14:20Z", + "deletions": 0, + "diff_url": "https://github.com/testuser/software-layer/pull/5.diff", + "draft": false, + "head": { + "label": "testuser:add-software", + "ref": "add-software", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "html_url": "https://github.com/testuser/software-layer/pull/5", + "id": 9876543210, + "issue_url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "labels": [ + { + "color": "87DA77", + "default": false, + "description": "", + "id": 1234554321, + "name": "test:label", + "node_id": "LA_kwDOQngT988AAAAASZXN0Q", + "url": "https://api.github.com/repos/testuser/software-layer/labels/test:label" + } + ], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "8b7bf21a77ab5cbe36d7c0e5fa88948773e5ccc8", + "mergeable": true, + "mergeable_state": "clean", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOxmQDYCGSUsFF", + "number": 5, + "patch_url": "https://github.com/testuser/software-layer/pull/5.patch", + "rebaseable": true, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "title": "Add software", + "updated_at": "2026-06-11T13:24:44Z", + "url": "https://api.github.com/repos/testuser/software-layer/pulls/5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/github/pr-opened.json b/test/events/github/pr-opened.json new file mode 100644 index 00000000..80eff702 --- /dev/null +++ b/test/events/github/pr-opened.json @@ -0,0 +1,548 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "23274", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1781183668579", + "User-Agent": "GitHub-Hookshot/576ea10", + "X-Forwarded-Scheme": "https", + "X-Github-Delivery": "7596a4f0-6597-11f1-9fbc-a1db0bccdf2c", + "X-Github-Event": "pull_request", + "X-Github-Hook-Id": "123454321", + "X-Github-Hook-Installation-Target-Id": "1234567", + "X-Github-Hook-Installation-Target-Type": "integration", + "X-Hub-Signature": "sha1=aed80075f84296c584ff29561d2667c913c65a12", + "X-Hub-Signature-256": "sha256=aca9a741b401e4f792947384bf7c3b2c890a7d0e33292834f4348cebbbf0a844", + "X-Real-Ip": "140.82.115.242", + "X-Request-Id": "092aa2dc206b8db080d66997fdccd205", + "X-Scheme": "https" + }, + "json": { + "action": "opened", + "installation": { + "id": 99999999, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uOTk5OTk5OTk=" + }, + "number": 5, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5/comments" + }, + "commits": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits" + }, + "html": { + "href": "https://github.com/testuser/software-layer/pull/5" + }, + "issue": { + "href": "https://api.github.com/repos/testuser/software-layer/issues/5" + }, + "review_comment": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments" + }, + "self": { + "href": "https://api.github.com/repos/testuser/software-layer/pulls/5" + }, + "statuses": { + "href": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0" + } + }, + "active_lock_reason": null, + "additions": 2, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "testuser:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "0a1e785fad6fa4d19fa397e693dbd4ae36585fdf", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "body": "Test", + "changed_files": 1, + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/testuser/software-layer/issues/5/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/commits", + "created_at": "2026-06-11T13:14:20Z", + "deletions": 0, + "diff_url": "https://github.com/testuser/software-layer/pull/5.diff", + "draft": false, + "head": { + "label": "testuser:add-software", + "ref": "add-software", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "html_url": "https://github.com/testuser/software-layer/pull/5", + "id": 9876543210, + "issue_url": "https://api.github.com/repos/testuser/software-layer/issues/5", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": null, + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOxmQDYCGSUsFF", + "number": 5, + "patch_url": "https://github.com/testuser/software-layer/pull/5.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/testuser/software-layer/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/testuser/software-layer/pulls/5/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/353eca2f5d5f2e106e53171dc97ed0c578de49f0", + "title": "Add software", + "updated_at": "2026-06-11T13:14:20Z", + "url": "https://api.github.com/repos/testuser/software-layer/pulls/5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/testuser/software-layer/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/testuser/software-layer/assignees{/user}", + "blobs_url": "https://api.github.com/repos/testuser/software-layer/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/testuser/software-layer/branches{/branch}", + "clone_url": "https://github.com/testuser/software-layer.git", + "collaborators_url": "https://api.github.com/repos/testuser/software-layer/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/testuser/software-layer/comments{/number}", + "commits_url": "https://api.github.com/repos/testuser/software-layer/commits{/sha}", + "compare_url": "https://api.github.com/repos/testuser/software-layer/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/testuser/software-layer/contents/{+path}", + "contributors_url": "https://api.github.com/repos/testuser/software-layer/contributors", + "created_at": "2025-12-12T12:44:16Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/testuser/software-layer/deployments", + "description": "Software layer of the EESSI project", + "disabled": false, + "downloads_url": "https://api.github.com/repos/testuser/software-layer/downloads", + "events_url": "https://api.github.com/repos/testuser/software-layer/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/testuser/software-layer/forks", + "full_name": "testuser/software-layer", + "git_commits_url": "https://api.github.com/repos/testuser/software-layer/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/testuser/software-layer/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/testuser/software-layer/git/tags{/sha}", + "git_url": "git://github.com/testuser/software-layer.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_pull_requests": true, + "has_wiki": true, + "homepage": "https://eessi.github.io/docs/software_layer", + "hooks_url": "https://api.github.com/repos/testuser/software-layer/hooks", + "html_url": "https://github.com/testuser/software-layer", + "id": 1234567890, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/testuser/software-layer/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/testuser/software-layer/issues/events{/number}", + "issues_url": "https://api.github.com/repos/testuser/software-layer/issues{/number}", + "keys_url": "https://api.github.com/repos/testuser/software-layer/keys{/key_id}", + "labels_url": "https://api.github.com/repos/testuser/software-layer/labels{/name}", + "language": "Python", + "languages_url": "https://api.github.com/repos/testuser/software-layer/languages", + "license": { + "key": "gpl-2.0", + "name": "GNU General Public License v2.0", + "node_id": "MDc6TGljZW5zZTg=", + "spdx_id": "GPL-2.0", + "url": "https://api.github.com/licenses/gpl-2.0" + }, + "merges_url": "https://api.github.com/repos/testuser/software-layer/merges", + "milestones_url": "https://api.github.com/repos/testuser/software-layer/milestones{/number}", + "mirror_url": null, + "name": "software-layer", + "node_id": "R_kgDOSZYC0g", + "notifications_url": "https://api.github.com/repos/testuser/software-layer/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + }, + "private": false, + "pull_request_creation_policy": "all", + "pulls_url": "https://api.github.com/repos/testuser/software-layer/pulls{/number}", + "pushed_at": "2026-06-11T13:13:45Z", + "releases_url": "https://api.github.com/repos/testuser/software-layer/releases{/id}", + "size": 4478, + "ssh_url": "git@github.com:testuser/software-layer.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/testuser/software-layer/stargazers", + "statuses_url": "https://api.github.com/repos/testuser/software-layer/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/testuser/software-layer/subscribers", + "subscription_url": "https://api.github.com/repos/testuser/software-layer/subscription", + "svn_url": "https://github.com/testuser/software-layer", + "tags_url": "https://api.github.com/repos/testuser/software-layer/tags", + "teams_url": "https://api.github.com/repos/testuser/software-layer/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/testuser/software-layer/git/trees{/sha}", + "updated_at": "2026-03-24T08:09:21Z", + "url": "https://api.github.com/repos/testuser/software-layer", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/123456789?v=4", + "events_url": "https://api.github.com/users/testuser/events{/privacy}", + "followers_url": "https://api.github.com/users/testuser/followers", + "following_url": "https://api.github.com/users/testuser/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/testuser", + "id": 123456789, + "login": "testuser", + "node_id": "U_kgDOB1vNFQ", + "organizations_url": "https://api.github.com/users/testuser/orgs", + "received_events_url": "https://api.github.com/users/testuser/received_events", + "repos_url": "https://api.github.com/users/testuser/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", + "type": "User", + "url": "https://api.github.com/users/testuser", + "user_view_type": "public" + } + } +} diff --git a/test/events/gitlab/comment-created.json b/test/events/gitlab/comment-created.json new file mode 100644 index 00000000..cd2fe38e --- /dev/null +++ b/test/events/gitlab/comment-created.json @@ -0,0 +1,184 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "4537", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Idempotency-Key": "e5da9222-dd70-464a-8b5e-111c178b5a61", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1780906078691", + "User-Agent": "GitLab/19.1.0-pre", + "Webhook-Id": "e5da9222-dd70-464a-8b5e-111c178b5a61", + "Webhook-Signature": "v1,GuCf36yq0azLiWDqcXBiTOGA631QrW2dS9RUtLfbbDY=", + "Webhook-Timestamp": "1780906078", + "X-Forwarded-Scheme": "https", + "X-Gitlab-Event": "Note Hook", + "X-Gitlab-Event-Uuid": "2b06e3b7-2d2f-4407-a0c6-9448f3327a99", + "X-Gitlab-Instance": "https://gitlab.com", + "X-Gitlab-Webhook-Uuid": "458cad16-ed4f-4045-b6af-7cdecc3bc638", + "X-Real-Ip": "34.74.226.46", + "X-Request-Id": "20c4273dbef6cdd9cfe3dbe50d68573a", + "X-Scheme": "https" + }, + "json":{ + "event_type": "note", + "merge_request": { + "approval_rules": [], + "assignee_id": null, + "assignee_ids": [], + "author_id": 12345678, + "blocking_discussions_resolved": true, + "created_at": "2026-06-08T08:02:26.218Z", + "description": "Test 2", + "detailed_merge_status": "mergeable", + "draft": false, + "first_contribution": false, + "head_pipeline_id": null, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "id": 123456789, + "iid": 2, + "labels": [], + "last_commit": { + "author": { + "email": "commituser@example.com", + "name": "Commit User" + }, + "id": "3ebfa301dc59196f18593c45e519287a23297589", + "message": "Add more software", + "timestamp": "2026-06-08T08:01:50+00:00", + "title": "Add more software", + "url": "https://gitlab.com/testuser1/software-layer/-/commit/3ebfa301dc59196f18593c45e519287a23297589" + }, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "prepared_at": "2026-06-08T08:02:27.820Z", + "reviewer_ids": [], + "source": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "source_branch": "more-software", + "source_project_id": 87654321, + "squash_commit_sha": null, + "state": "opened", + "state_id": 1, + "system": false, + "target": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "target_branch": "main", + "target_project_id": 87654321, + "time_change": 0, + "time_estimate": 0, + "title": "Add more software", + "total_time_spent": 0, + "updated_at": "2026-06-08T08:07:57.352Z", + "updated_by_id": null, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/2", + "work_in_progress": false + }, + "object_attributes": { + "action": "create", + "author_id": 12345678, + "change_position": null, + "commit_id": null, + "created_at": "2026-06-08T08:07:57.324Z", + "description": "bot:help", + "discussion_id": "c668481a01e42e85bd637316e1d0cc7762aee59a", + "id": 1234567890, + "internal": false, + "line_code": null, + "note": "bot:help", + "noteable_id": 987654321, + "noteable_type": "MergeRequest", + "original_position": null, + "position": null, + "project_id": 87654321, + "resolved_at": null, + "resolved_by_id": null, + "resolved_by_push": null, + "st_diff": null, + "system": false, + "type": null, + "updated_at": "2026-06-08T08:07:57.324Z", + "updated_by_id": null, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/2#note_1234567890" + }, + "object_kind": "note", + "project": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "project_id": 87654321, + "repository": { + "description": null, + "homepage": "https://gitlab.com/testuser1/software-layer", + "name": "software-layer", + "url": "git@gitlab.com:testuser1/software-layer.git" + }, + "user": { + "avatar_url": "https://example.com/avatar/id", + "email": "[REDACTED]", + "id": 12345678, + "name": "Test User", + "username": "testuser" + } + } +} diff --git a/test/events/gitlab/comment-edited.json b/test/events/gitlab/comment-edited.json new file mode 100644 index 00000000..82771e4a --- /dev/null +++ b/test/events/gitlab/comment-edited.json @@ -0,0 +1,184 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "4541", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Idempotency-Key": "a8a0c205-ff28-49e7-b5c7-def2cdd4fd1e", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1780906157212", + "User-Agent": "GitLab/19.1.0-pre", + "Webhook-Id": "a8a0c205-ff28-49e7-b5c7-def2cdd4fd1e", + "Webhook-Signature": "v1,W7qlB3mBi2v1cbXbP91pjl8hLrb5b5RjKjoaIyGWKiU=", + "Webhook-Timestamp": "1780906156", + "X-Forwarded-Scheme": "https", + "X-Gitlab-Event": "Note Hook", + "X-Gitlab-Event-Uuid": "9a8db85f-8c06-43eb-9ed2-f2618b27bbba", + "X-Gitlab-Instance": "https://gitlab.com", + "X-Gitlab-Webhook-Uuid": "41baf3a3-97c7-4023-af22-8c3c97f5fcbb", + "X-Real-Ip": "34.74.226.42", + "X-Request-Id": "2a3fd171b3c191fa45a622486ac4e2c2", + "X-Scheme": "https" + }, + "json":{ + "event_type": "note", + "merge_request": { + "approval_rules": [], + "assignee_id": null, + "assignee_ids": [], + "author_id": 12345678, + "blocking_discussions_resolved": true, + "created_at": "2026-06-08T08:02:26.218Z", + "description": "Test 2", + "detailed_merge_status": "mergeable", + "draft": false, + "first_contribution": false, + "head_pipeline_id": null, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "id": 123456789, + "iid": 2, + "labels": [], + "last_commit": { + "author": { + "email": "commituser@example.com", + "name": "Commit User" + }, + "id": "3ebfa301dc59196f18593c45e519287a23297589", + "message": "Add more software", + "timestamp": "2026-06-08T08:01:50+00:00", + "title": "Add more software", + "url": "https://gitlab.com/testuser1/software-layer/-/commit/3ebfa301dc59196f18593c45e519287a23297589" + }, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "prepared_at": "2026-06-08T08:02:27.820Z", + "reviewer_ids": [], + "source": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "source_branch": "more-software", + "source_project_id": 87654321, + "squash_commit_sha": null, + "state": "opened", + "state_id": 1, + "system": false, + "target": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "target_branch": "main", + "target_project_id": 87654321, + "time_change": 0, + "time_estimate": 0, + "title": "Add more software", + "total_time_spent": 0, + "updated_at": "2026-06-08T08:09:06.132Z", + "updated_by_id": null, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/2", + "work_in_progress": false + }, + "object_attributes": { + "action": "update", + "author_id": 12345678, + "change_position": null, + "commit_id": null, + "created_at": "2026-06-08T08:07:57.324Z", + "description": "bot: help", + "discussion_id": "c668481a01e42e85bd637316e1d0cc7762aee59a", + "id": 1234567890, + "internal": false, + "line_code": null, + "note": "bot: help", + "noteable_id": 987654321, + "noteable_type": "MergeRequest", + "original_position": null, + "position": null, + "project_id": 87654321, + "resolved_at": null, + "resolved_by_id": null, + "resolved_by_push": null, + "st_diff": null, + "system": false, + "type": null, + "updated_at": "2026-06-08T08:09:16.279Z", + "updated_by_id": 12341234, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/2#note_1234567890" + }, + "object_kind": "note", + "project": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "project_id": 87654321, + "repository": { + "description": null, + "homepage": "https://gitlab.com/testuser1/software-layer", + "name": "software-layer", + "url": "git@gitlab.com:testuser1/software-layer.git" + }, + "user": { + "avatar_url": "https://example.com/avatar/otherid", + "email": "[REDACTED]", + "id": 12341234, + "name": "Other Test User", + "username": "othertestuser" + } + } +} diff --git a/test/events/gitlab/pr-closed.json b/test/events/gitlab/pr-closed.json new file mode 100644 index 00000000..04a1b7af --- /dev/null +++ b/test/events/gitlab/pr-closed.json @@ -0,0 +1,199 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "4652", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Idempotency-Key": "37265d34-ea82-4c03-8fc9-03b8de02e23a", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1780649116283", + "User-Agent": "GitLab/19.1.0-pre", + "Webhook-Id": "37265d34-ea82-4c03-8fc9-03b8de02e23a", + "Webhook-Signature": "v1,lnMeM6ohFqXKQ/CNPGeY605WivJfN/ZMkxn5DXLhxWI=", + "Webhook-Timestamp": "1780649115", + "X-Forwarded-Scheme": "https", + "X-Gitlab-Event": "Merge Request Hook", + "X-Gitlab-Event-Uuid": "22d54548-a5eb-41b9-86af-5a95dc0c7ada", + "X-Gitlab-Instance": "https://gitlab.com", + "X-Gitlab-Webhook-Uuid": "d78ccdc9-a0c9-42c7-abbe-304b9d358213", + "X-Real-Ip": "34.74.226.46", + "X-Request-Id": "58693cd8245ce89eb7af96106675b3b8", + "X-Scheme": "https" + }, + "json": { + "changes": { + "merge_commit_sha": { + "current": "e8e2ace14fcedce073756444255d2cfe24f470af", + "previous": null + }, + "state_id": { + "current": 3, + "previous": 1 + }, + "updated_at": { + "current": "2026-06-05T08:45:14.342Z", + "previous": "2026-06-05T08:44:45.590Z" + } + }, + "event_type": "merge_request", + "labels": [ + { + "color": "#dc143c", + "created_at": "2026-06-05T08:28:27.156Z", + "description": null, + "group_id": null, + "id": 12344321, + "project_id": 87654321, + "template": false, + "title": "test:label", + "type": "ProjectLabel", + "updated_at": "2026-06-05T08:28:27.156Z" + } + ], + "object_attributes": { + "action": "merge", + "actioned_at": "2026-06-05T08:45:15.346Z", + "approval_rules": [], + "assignee_id": null, + "assignee_ids": [], + "author_id": 12345678, + "blocking_discussions_resolved": true, + "created_at": "2026-06-05T07:41:52.123Z", + "description": "Test", + "detailed_merge_status": "not_open", + "draft": false, + "first_contribution": true, + "head_pipeline_id": null, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "id": 123456789, + "iid": 1, + "labels": [ + { + "color": "#dc143c", + "created_at": "2026-06-05T08:28:27.156Z", + "description": null, + "group_id": null, + "id": 12344321, + "project_id": 87654321, + "template": false, + "title": "test:label", + "type": "ProjectLabel", + "updated_at": "2026-06-05T08:28:27.156Z" + } + ], + "last_commit": { + "author": { + "email": "commituser@example.com", + "name": "Commit User" + }, + "id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "message": "Add software", + "timestamp": "2026-06-05T07:40:54+02:00", + "title": "Add software", + "url": "https://gitlab.com/testuser1/software-layer/-/commit/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" + }, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": "e8e2ace14fcedce073756444255d2cfe24f470af", + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "prepared_at": "2026-06-05T07:41:53.209Z", + "reviewer_ids": [], + "source": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "source_branch": "add-software", + "source_project_id": 87654321, + "squash_commit_sha": null, + "state": "merged", + "state_id": 3, + "system": false, + "target": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "target_branch": "main", + "target_project_id": 87654321, + "time_change": 0, + "time_estimate": 0, + "title": "Add software", + "total_time_spent": 0, + "updated_at": "2026-06-05T08:45:14.342Z", + "updated_by_id": 12345678, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/1", + "work_in_progress": false + }, + "object_kind": "merge_request", + "project": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "repository": { + "description": null, + "homepage": "https://gitlab.com/testuser1/software-layer", + "name": "software-layer", + "url": "git@gitlab.com:testuser1/software-layer.git" + }, + "user": { + "avatar_url": "https://example.com/avatar/id", + "email": "[REDACTED]", + "id": 12345678, + "name": "Test User", + "username": "testuser" + } + } +} diff --git a/test/events/gitlab/pr-labeled.json b/test/events/gitlab/pr-labeled.json new file mode 100644 index 00000000..374dc86b --- /dev/null +++ b/test/events/gitlab/pr-labeled.json @@ -0,0 +1,212 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "4884", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Idempotency-Key": "69592eec-c109-4b80-89d3-ed14ac2d21c6", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1780648109892", + "User-Agent": "GitLab/19.1.0-pre", + "Webhook-Id": "69592eec-c109-4b80-89d3-ed14ac2d21c6", + "Webhook-Signature": "v1,9pKnXRl6aX3unRlr0vCgtKynpO40cPn2H1fA/mSfUwU=", + "Webhook-Timestamp": "1780648109", + "X-Forwarded-Scheme": "https", + "X-Gitlab-Event": "Merge Request Hook", + "X-Gitlab-Event-Uuid": "79fecac6-dde1-4404-93f9-baaa4ef9bec0", + "X-Gitlab-Instance": "https://gitlab.com", + "X-Gitlab-Webhook-Uuid": "d151318c-bfad-4c1b-81da-f7e8f2c56e4f", + "X-Real-Ip": "34.74.226.46", + "X-Request-Id": "78b27853304494c16873c7d8a4bcd7a5", + "X-Scheme": "https" + }, + "json": { + "changes": { + "labels": { + "current": [ + { + "color": "#dc143c", + "created_at": "2026-06-05T08:28:27.156Z", + "description": null, + "group_id": null, + "id": 12344321, + "project_id": 87654321, + "template": false, + "title": "test:label", + "type": "ProjectLabel", + "updated_at": "2026-06-05T08:28:27.156Z" + } + ], + "previous": [] + }, + "updated_at": { + "current": "2026-06-05T08:28:28.999Z", + "previous": "2026-06-05T07:41:53.215Z" + }, + "updated_by_id": { + "current": 12345678, + "previous": null + } + }, + "event_type": "merge_request", + "labels": [ + { + "color": "#dc143c", + "created_at": "2026-06-05T08:28:27.156Z", + "description": null, + "group_id": null, + "id": 12344321, + "project_id": 87654321, + "template": false, + "title": "test:label", + "type": "ProjectLabel", + "updated_at": "2026-06-05T08:28:27.156Z" + } + ], + "object_attributes": { + "action": "update", + "actioned_at": "2026-06-05T08:28:29.068Z", + "approval_rules": [], + "assignee_id": null, + "assignee_ids": [], + "author_id": 12345678, + "blocking_discussions_resolved": true, + "created_at": "2026-06-05T07:41:52.123Z", + "description": "Test", + "detailed_merge_status": "commits_status", + "draft": false, + "first_contribution": true, + "head_pipeline_id": null, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "id": 123456789, + "iid": 1, + "labels": [ + { + "color": "#dc143c", + "created_at": "2026-06-05T08:28:27.156Z", + "description": null, + "group_id": null, + "id": 12344321, + "project_id": 87654321, + "template": false, + "title": "test:label", + "type": "ProjectLabel", + "updated_at": "2026-06-05T08:28:27.156Z" + } + ], + "last_commit": { + "author": { + "email": "commituser@example.com", + "name": "Commit User" + }, + "id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "message": "Add software", + "timestamp": "2026-06-05T07:40:54+02:00", + "title": "Add software", + "url": "https://gitlab.com/testuser1/software-layer/-/commit/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" + }, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "cannot_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "prepared_at": "2026-06-05T07:41:53.209Z", + "reviewer_ids": [], + "source": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "source_branch": "add-software", + "source_project_id": 87654321, + "squash_commit_sha": null, + "state": "opened", + "state_id": 1, + "system": false, + "target": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "target_branch": "main", + "target_project_id": 87654321, + "time_change": 0, + "time_estimate": 0, + "title": "Add software", + "total_time_spent": 0, + "updated_at": "2026-06-05T08:28:28.999Z", + "updated_by_id": 12345678, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/1", + "work_in_progress": false + }, + "object_kind": "merge_request", + "project": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "repository": { + "description": null, + "homepage": "https://gitlab.com/testuser1/software-layer", + "name": "software-layer", + "url": "git@gitlab.com:testuser1/software-layer.git" + }, + "user": { + "avatar_url": "https://example.com/avatar/id", + "email": "[REDACTED]", + "id": 12345678, + "name": "Test User", + "username": "testuser" + } + } +} diff --git a/test/events/gitlab/pr-opened.json b/test/events/gitlab/pr-opened.json new file mode 100644 index 00000000..be9c0446 --- /dev/null +++ b/test/events/gitlab/pr-opened.json @@ -0,0 +1,173 @@ +{ + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "Accept-Language": "*", + "Connection": "keep-alive", + "Content-Length": "4213", + "Content-Type": "application/json", + "Host": "127.0.0.1:3000", + "Idempotency-Key": "b6de2702-c354-4bdd-8207-e634971623bb", + "Sec-Fetch-Mode": "cors", + "Timestamp": "1780645314004", + "User-Agent": "GitLab/19.1.0-pre", + "Webhook-Id": "b6de2702-c354-4bdd-8207-e634971623bb", + "Webhook-Signature": "v1,Fj4cEsqlXB6tkqVZoVig8I7P8ZrbuKofCj5dru7HK4M=", + "Webhook-Timestamp": "1780645313", + "X-Forwarded-Scheme": "https", + "X-Gitlab-Event": "Merge Request Hook", + "X-Gitlab-Event-Uuid": "a082cd15-7607-4608-b214-7edb77efb3f4", + "X-Gitlab-Instance": "https://gitlab.com", + "X-Gitlab-Webhook-Uuid": "782cd6c3-0dd8-40f1-b165-c0480773a769", + "X-Real-Ip": "34.74.226.42", + "X-Request-Id": "55b4d958185fff8cddad766fbeeea9b2", + "X-Scheme": "https" + }, + "json": { + "changes": { + "merge_status": { + "current": "checking", + "previous": "preparing" + }, + "prepared_at": { + "current": "2026-06-05T07:41:53.209Z", + "previous": null + }, + "updated_at": { + "current": "2026-06-05T07:41:53.215Z", + "previous": "2026-06-05T07:41:52.123Z" + } + }, + "event_type": "merge_request", + "labels": [], + "object_attributes": { + "action": "open", + "actioned_at": "2026-06-05T07:41:53.239Z", + "approval_rules": [], + "assignee_id": null, + "assignee_ids": [], + "author_id": 12345678, + "blocking_discussions_resolved": true, + "created_at": "2026-06-05T07:41:52.123Z", + "description": "Test", + "detailed_merge_status": "checking", + "draft": false, + "first_contribution": true, + "head_pipeline_id": null, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "id": 123456789, + "iid": 1, + "labels": [], + "last_commit": { + "author": { + "email": "commituser@example.com", + "name": "Commit User" + }, + "id": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "message": "Add software", + "timestamp": "2026-06-05T07:40:54+02:00", + "title": "Add software", + "url": "https://gitlab.com/testuser1/software-layer/-/commit/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" + }, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "checking", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "prepared_at": "2026-06-05T07:41:53.209Z", + "reviewer_ids": [], + "source": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "source_branch": "add-software", + "source_project_id": 87654321, + "squash_commit_sha": null, + "state": "opened", + "state_id": 1, + "system": false, + "target": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "target_branch": "main", + "target_project_id": 87654321, + "time_change": 0, + "time_estimate": 0, + "title": "Add software", + "total_time_spent": 0, + "updated_at": "2026-06-05T07:41:53.215Z", + "updated_by_id": null, + "url": "https://gitlab.com/testuser1/software-layer/-/merge_requests/1", + "work_in_progress": false + }, + "object_kind": "merge_request", + "project": { + "avatar_url": null, + "ci_config_path": "", + "default_branch": "main", + "description": null, + "git_http_url": "https://gitlab.com/testuser1/software-layer.git", + "git_ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "homepage": "https://gitlab.com/testuser1/software-layer", + "http_url": "https://gitlab.com/testuser1/software-layer.git", + "id": 87654321, + "name": "software-layer", + "namespace": "testuser1", + "path_with_namespace": "testuser1/software-layer", + "ssh_url": "git@gitlab.com:testuser1/software-layer.git", + "url": "git@gitlab.com:testuser1/software-layer.git", + "visibility_level": 0, + "web_url": "https://gitlab.com/testuser1/software-layer" + }, + "repository": { + "description": null, + "homepage": "https://gitlab.com/testuser1/software-layer", + "name": "software-layer", + "url": "git@gitlab.com:testuser1/software-layer.git" + }, + "user": { + "avatar_url": "https://example.com/avatar/id", + "email": "[REDACTED]", + "id": 12345678, + "name": "Test User", + "username": "testuser" + } + } +} diff --git a/tests/test_app.cfg b/tests/test_app.cfg index db1e1982..1b9614f6 100644 --- a/tests/test_app.cfg +++ b/tests/test_app.cfg @@ -5,6 +5,7 @@ # EESSI software layer, see https://github.com/EESSI/software-layer # # author: Thomas Roeblitz (@trz42) +# author: Sondre Bergsvaag Risanger (@sondrebr) # # license: GPLv2 # @@ -14,6 +15,14 @@ [git] hosting_platform = github +[github] +app_name = test-app-github + +[gitlab] +api_timeout = 123 +bot_name = test-bot-gl +instance_url = https://notdefault.gitlab.com/ + [buildenv] job_handover_protocol = hold_release diff --git a/tests/test_connections_gitlab.py b/tests/test_connections_gitlab.py new file mode 100644 index 00000000..ad5c7a23 --- /dev/null +++ b/tests/test_connections_gitlab.py @@ -0,0 +1,145 @@ +# Tests for 'connections/gitlab.py' of the EESSI build-and-deploy bot, +# see https://github.com/EESSI/eessi-bot-software-layer +# +# The bot helps with requests to add software installations to the +# EESSI software layer, see https://github.com/EESSI/software-layer +# +# author: Sondre Bergsvaag Risanger (@sondrebr) +# +# license: GPLv2 +# + +# Standard library imports +import os +from unittest.mock import patch + +# Third party imports (anything installed into the local Python environment) +from gitlab.exceptions import GitlabAuthenticationError, GitlabHttpError +import pytest + +# Local application imports (anything from EESSI/eessi-bot-software-layer) +from connections import gitlab +from tools import config + + +PAT_ENV_VAR_NAME = "GITLAB_PROJECT_ACCESS_TOKEN" +ACCESS_TOKEN = "gl_access_token_123" + +CFG = config.read_config() +GITLAB_CFG = CFG[config.SECTION_GITLAB] +INSTANCE_URL = GITLAB_CFG.get(config.GITLAB_SETTING_INSTANCE_URL) +API_TIMEOUT = int(GITLAB_CFG.get(config.GITLAB_SETTING_API_TIMEOUT)) + + +class MockCurrentUser: + pass + + +class MockObjects: + pass + + +class MockGitlab: + # python-gitlab Gitlab class has lots of arguments and attributes + # Only the ones currently used are included here + def __init__(self, url=None, private_token=None, timeout=None, retry_transient_errors=False): + if not url: + url = "https://gitlab.com" + self.url = url + self.private_token = private_token + self.retry_transient_errors = retry_transient_errors + self.timeout = timeout + self.user = None + self._objects = MockObjects() + self._objects.CurrentUser = MockCurrentUser + + if not self.private_token: + raise ValueError("'private_token' not set") + + def auth(self): + # Set 'user' when calling auth() + self.user = self._objects.CurrentUser() + + +# Test verify_connection() +def test_verify_connection(capfd): + # Token is valid and current user is successfully retrieved and stored + mock_gl = MockGitlab(private_token=ACCESS_TOKEN) + gitlab.verify_connection(mock_gl) + + with patch.object(MockGitlab, "auth") as mock_auth: + # Token is invalid - should exit + INVALID_TOKEN_MSG = "Invalid access token" + mock_auth.side_effect = GitlabAuthenticationError(INVALID_TOKEN_MSG) + with pytest.raises(SystemExit): + gitlab.verify_connection(mock_gl) + assert INVALID_TOKEN_MSG in capfd.readouterr().err + + # HTTP error occurs - should exit + HTTP_ERROR_MSG = "Unable to retrieve user" + mock_auth.side_effect = GitlabHttpError(HTTP_ERROR_MSG) + with pytest.raises(SystemExit): + gitlab.verify_connection(mock_gl) + assert HTTP_ERROR_MSG in capfd.readouterr().err + + # 'user' is not of type 'CurrentUser' - should exit + # Make auth() do nothing + mock_auth.side_effect = None + mock_gl.user = "Not CurrentUser" + with pytest.raises(SystemExit): + gitlab.verify_connection(mock_gl) + # Error message should mention the 'user' attribute and the 'CurrentUser' type + err_msg = capfd.readouterr().err + assert "'user'" in err_msg + assert "'CurrentUser'" in err_msg + + +# Test connect() +@patch("connections.gitlab.gitlab.Gitlab", MockGitlab) +def test_connect(capfd): + # Test successful connection + os.environ[PAT_ENV_VAR_NAME] = ACCESS_TOKEN + with patch("connections.gitlab.verify_connection") as mock_verify_connection: + gitlab.connect() + # connect() should verify connection + mock_verify_connection.assert_called() + # Created connection should be stored as '_gl' - verify properties + gl = gitlab._gl + assert isinstance(gl, MockGitlab) + assert gl.url == INSTANCE_URL + assert gl.private_token == ACCESS_TOKEN + assert gl.timeout == API_TIMEOUT + assert gl.retry_transient_errors is True + # connect() should unset environment variable 'GITLAB_PROJECT_ACCESS_TOKEN' + assert os.getenv(PAT_ENV_VAR_NAME) is None + + # Test with missing environment variable 'GITLAB_PROJECT_ACCESS_TOKEN' - should exit + with pytest.raises(SystemExit): + gitlab.connect() + # Error message should mention the environment variable + assert PAT_ENV_VAR_NAME in capfd.readouterr().err + + +# Test get_instance() +@patch("connections.gitlab.gitlab.Gitlab", MockGitlab) +def test_get_instance(): + gitlab._gl = None + mock_gl = MockGitlab(private_token=ACCESS_TOKEN) + + # To be used as mock connect() + def set_gl(): + gitlab._gl = mock_gl + + # No existing connection - Connect and return + with patch("connections.gitlab.connect", side_effect=set_gl) as mock_connect: + gl = gitlab.get_instance() + mock_connect.assert_called_once() + assert gl is gitlab._gl + assert gl is mock_gl + + # Existing connection - Verify and return + with patch("connections.gitlab.connect") as mock_connect: + with patch("connections.gitlab.verify_connection") as mock_verify_connection: + gl = gitlab.get_instance() + mock_verify_connection.assert_called() + mock_connect.assert_not_called() diff --git a/tests/test_tools_commands.py b/tests/test_tools_commands.py index da0d70af..0237c82f 100644 --- a/tests/test_tools_commands.py +++ b/tests/test_tools_commands.py @@ -11,12 +11,52 @@ # Standard library imports from contextlib import nullcontext +from unittest.mock import patch # Third party imports (anything installed into the local Python environment) import pytest # Local application imports (anything from EESSI/eessi-bot-software-layer) -from tools import commands +from tools import commands, git + + +# Test SUPPORTED_COMMANDS_PER_GIT_HOST +@pytest.mark.parametrize("git_host", git.SUPPORTED_GIT_HOSTS) +def test_support_commands_per_git_host(git_host): + # There should be an entry for each supported Git hosting platform + assert git_host in commands.SUPPORTED_COMMANDS_PER_GIT_HOST + + # Each entry should be a list of commands + supported_commands = commands.SUPPORTED_COMMANDS_PER_GIT_HOST[git_host] + assert isinstance(supported_commands, list) + assert all([command in commands.ALL_COMMANDS for command in supported_commands]) + + +# Test get_supported_commands() +def test_get_supported_commands(): + HOSTING_PLATFORM = "hosting_platform" + + github_supported_commands = commands.SUPPORTED_COMMANDS_PER_GIT_HOST[git.GITHUB] + gitlab_supported_commands = commands.SUPPORTED_COMMANDS_PER_GIT_HOST[git.GITLAB] + + # Use as mock get_git_hosting_platform() + def get_git_host(cfg=None): + if cfg is None: + return git.GITHUB + return cfg.get(HOSTING_PLATFORM) + + with patch("tools.commands.get_git_hosting_platform", side_effect=get_git_host) as mock_get_git_host: + # Test without provided cfg - mock get_git_hosting_platform() defaults to 'github' + assert commands.get_supported_commands() is github_supported_commands + mock_get_git_host.assert_called_once() + + # Test with provided cfg - 'hosting_platform' set to 'github' + assert commands.get_supported_commands({HOSTING_PLATFORM: git.GITHUB}) == github_supported_commands + assert mock_get_git_host.call_count == 2 + + # Test with provided cfg - 'hosting_platform' set to 'gitlab' + assert commands.get_supported_commands({HOSTING_PLATFORM: git.GITLAB}) == gitlab_supported_commands + assert mock_get_git_host.call_count == 3 # Test contains_any_bot_command() with both single-line and multi-line comments @@ -73,7 +113,7 @@ def test_get_bot_command(): # Test different commands with varying formatting test_cmds = [ # All existing commands - "build", "cancel", "help", "show_config", "status", + *commands.ALL_COMMANDS, # Build command with filters "build on:arch=icelake for:arch=x86_64/intel/icelake,accel=nvidia/cc90 repo:eessi.io-2025.06-software", # Non-existant command diff --git a/tests/test_tools_event_info.py b/tests/test_tools_event_info.py new file mode 100644 index 00000000..e937a217 --- /dev/null +++ b/tests/test_tools_event_info.py @@ -0,0 +1,371 @@ +# Tests for 'tools/event_info.py' of the EESSI build-and-deploy bot, +# see https://github.com/EESSI/eessi-bot-software-layer +# +# The bot helps with requests to add software installations to the +# EESSI software layer, see https://github.com/EESSI/software-layer +# +# author: Sondre Bergsvaag Risanger (@sondrebr) +# +# license: GPLv2 +# + +# Standard library imports +from functools import cached_property +import json +from unittest.mock import patch + +# Third party imports (anything installed into the local Python environment) +from pyghee.lib import CaseInsensitiveDict, get_event_info +import pytest + +# Local application imports (anything from EESSI/eessi-bot-software-layer) +from tools import event_info, git + + +# All properties to be implemented by the EventInfo classes +EVENT_INFO_PROPERTIES = [ + "action", "comment_id", "comment_body", "comment_created_by", + "event_id", "event_triggered_by", "event_type", + "issue_number", "issue_url", "label_name", + "pr_number", "pr_merged_status", "pr_url", "repo_name", +] + +# Event type + action combinations with sample event files +# Used as keys in *_EVENT_PATHS dicts below +PR_OPENED = "pr_opened" +PR_LABELED = "pr_labeled" +PR_CLOSED = "pr_closed" +COMMENT_CREATED = "comment_created" +COMMENT_EDITED = "comment_edited" +INSTALLATION_CREATED = "installation_created" + +# Sample event files for GitHubEventInfo tests +GITHUB_EVENT_PATHS = { + # Pull request events + PR_OPENED: "test/events/github/pr-opened.json", + PR_LABELED: "test/events/github/pr-labeled.json", + PR_CLOSED: "test/events/github/pr-closed.json", + + # Comment events + COMMENT_CREATED: "test/events/github/comment-created.json", + COMMENT_EDITED: "test/events/github/comment-edited.json", + + # Installation event + INSTALLATION_CREATED: "test/events/github/installation-created.json" +} + +# Sample event files for GitLabEventInfo tests +GITLAB_EVENT_PATHS = { + # Pull request events + PR_OPENED: "test/events/gitlab/pr-opened.json", + PR_LABELED: "test/events/gitlab/pr-labeled.json", + PR_CLOSED: "test/events/gitlab/pr-closed.json", + + # Comment events + COMMENT_CREATED: "test/events/gitlab/comment-created.json", + COMMENT_EDITED: "test/events/gitlab/comment-edited.json", +} + + +# PyGHee's get_event_info() expects a flask.Request object as input +# This class roughly implements the attributes used by the PyGHee function +# 'event' passed on initialization must be a dict read from one of the sample event files +class MockRequest(): + def __init__(self, event): + self.json = event["json"] + self.data = json.dumps(self.json).encode() + self.headers = CaseInsensitiveDict(event["headers"]) + + +# Mock class handling individual user information in MockGitlab +class MockGLUser(): + def __init__(self, id, username): + self.id = id + self.username = username + + +# Mock class handling collections of users in MockGitlab +class MockGLUsers(): + def __init__(self, users): + # Store ID -> User mappings + self._users = {id: MockGLUser(id, username) for id, username in users.items()} + + def get(self, id, *args, **kwargs): + user = self._users.get(id) + if user is None: + raise ValueError("User does not exist!") + return user + + +# Mock class imitating python-gitlab's Gitlab class +class MockGitlab(): + def __init__(self, users=None): + self.users = MockGLUsers(users) + + +# Read event from file, create a MockRequest and return event_info dict from PyGHee's get_event_info() +def get_event_info_from_file(path): + # Use get_git_hosting_platform() imported by event_info - return value should be patched by tests + event_source = event_info.get_git_hosting_platform() + with open(path, "r") as f: + event = json.load(f) + request = MockRequest(event) + event_info_dict = get_event_info(request, event_source) + return event_info_dict + + +# Verify EventInfo type definition +def test_EventInfo(): + expected_event_info_types = set((event_info.GitHubEventInfo, event_info.GitLabEventInfo)) + # Need to use __args__ for Python 3.9 compatibility + actual_event_info_types = set(event_info.EventInfo.__args__) + assert actual_event_info_types == expected_event_info_types + + +# Test BaseEventInfo class +def test_BaseEventInfo(): + # Creating a BaseEventInfo instance should fail + with pytest.raises(NotImplementedError): + event_info.BaseEventInfo({}) + + # Overriding __getitem__ in subclasses should fail + with pytest.raises(Exception): + class _(event_info.BaseEventInfo): + def __getitem__(self, _): + return None + + with patch("tools.event_info.BaseEventInfo.__init__") as mock_init: + # Mock __init__ to allow creating an instance + mock_init.return_value = None + event_info_obj = event_info.BaseEventInfo() + + # Subscripting should subscript the event_info dict attribute + event_info_obj.event_info = {"test": 123} + assert event_info_obj["test"] is event_info_obj.event_info["test"] + assert event_info_obj["test"] == 123 + + # All properties should be cached_property and raise a NotImplementedError + for prop in EVENT_INFO_PROPERTIES: + # Test property type + attr = getattr(event_info.BaseEventInfo, prop) + assert type(attr) is cached_property + + # Test property getter - should fail with NotImplementedError + with pytest.raises(NotImplementedError): + attr.__get__(event_info_obj) + + +# Test GitHubEventInfo class on each supported event + action +@patch("tools.event_info.get_git_hosting_platform", return_value="github") +def test_GitHubEventInfo(_): + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[PR_OPENED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + + # Test common properties + assert event_info_obj.action == "opened" + assert event_info_obj.event_id == event_info_dict["id"] + assert event_info_obj.event_triggered_by == event_info_dict["raw_request_body"]["sender"]["login"] + assert event_info_obj.event_type == "pull_request" + assert event_info_obj.repo_name == event_info_dict["raw_request_body"]["repository"]["full_name"] + + # Test properties for pull_request events + assert event_info_obj.pr_number == event_info_dict["raw_request_body"]["pull_request"]["number"] + assert event_info_obj.pr_url == event_info_dict["raw_request_body"]["pull_request"]["html_url"] + + # Test properties for pull_request opened + assert event_info_obj.pr_merged_status is False + + # Test pull_request labeled + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[PR_LABELED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "labeled" + assert event_info_obj.label_name == event_info_dict["raw_request_body"]["label"]["name"] + + # Test pull_request closed + # Closed by merging + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[PR_CLOSED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "closed" + assert event_info_obj.pr_merged_status is True + + # Closed without merging + event_info_dict["raw_request_body"]["pull_request"]["merged"] = False + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "closed" + assert event_info_obj.pr_merged_status is False + + # Test properties for issue_comment events + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[COMMENT_CREATED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "issue_comment" + assert event_info_obj.comment_id == event_info_dict["raw_request_body"]["comment"]["id"] + assert event_info_obj.comment_body == event_info_dict["raw_request_body"]["comment"]["body"] + assert event_info_obj.issue_number == event_info_dict["raw_request_body"]["issue"]["number"] + assert event_info_obj.issue_url == event_info_dict["raw_request_body"]["issue"]["html_url"] + + # Test issue_comment created + assert event_info_obj.action == "created" + assert event_info_obj.comment_created_by == event_info_dict["raw_request_body"]["comment"]["user"]["login"] + assert event_info_obj.comment_created_by == event_info_obj.event_triggered_by + + # Test issue_comment edited + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[COMMENT_EDITED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "issue_comment" + assert event_info_obj.action == "edited" + + # Check who created vs. updated the comment - should be different users + assert event_info_obj.event_triggered_by == event_info_dict["raw_request_body"]["sender"]["login"] + assert event_info_obj.comment_created_by == event_info_dict["raw_request_body"]["comment"]["user"]["login"] + assert event_info_obj.event_triggered_by != event_info_obj.comment_created_by + + # Test installation created + event_info_dict = get_event_info_from_file(GITHUB_EVENT_PATHS[INSTALLATION_CREATED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "installation" + assert event_info_obj.action == "created" + + +# Test GitLabEventInfo class on each supported event + action +@patch("tools.event_info.get_git_hosting_platform", return_value="gitlab") +def test_GitLabEventInfo(_): + event_info_dict = get_event_info_from_file(GITLAB_EVENT_PATHS[PR_OPENED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + + # Test common properties + assert event_info_obj.action == "opened" + assert event_info_obj.event_id == event_info_dict["id"] + assert event_info_obj.event_triggered_by == event_info_dict["raw_request_body"]["user"]["username"] + assert event_info_obj.event_type == "pull_request" + assert event_info_obj.repo_name == event_info_dict["raw_request_body"]["project"]["path_with_namespace"] + + # Test properties for pull_request events + assert event_info_obj.pr_number == event_info_dict["raw_request_body"]["object_attributes"]["iid"] + assert event_info_obj.pr_url == event_info_dict["raw_request_body"]["object_attributes"]["url"] + + # Test properties for pull_request opened + assert event_info_obj.pr_merged_status is False + + # Test properties for pull_request labeled + event_info_dict = get_event_info_from_file(GITLAB_EVENT_PATHS[PR_LABELED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "labeled" + + # 'label_name' should be None if 'bot:deploy' was not added + # label added in sample event is 'test:label' + current_labels = event_info_dict["raw_request_body"]["changes"]["labels"]["current"] + label = current_labels[0] + assert label["title"] == "test:label" + assert event_info_obj.label_name is None + + # Append several labels to the list of current labels, including 'bot:deploy' + # 'label_name' getter should look for 'bot:deploy' among all added labels + bot_deploy_label = {**label, "title": "bot:deploy"} + current_labels.append(bot_deploy_label) + current_labels.append({**label, "title": "test2:label"}) + current_labels.append({**label, "title": "test:label2"}) + event_info_dict["raw_request_body"]["changes"]["labels"]["current"] = current_labels + event_info_obj = event_info.create_event_info_instance(event_info_dict) + # 'label_name' should now be 'bot:deploy' + assert event_info_obj.label_name == "bot:deploy" + + # Add 'bot:deploy' label to list of previous labels, meaning it was already present + # 'label_name' should again be None + event_info_dict["raw_request_body"]["changes"]["labels"]["previous"].append(bot_deploy_label) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.label_name is None + + # Test unknown pull_request update action + event_info_dict["raw_request_body"]["changes"] = {} + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "UNKNOWN" + + # Test properties for pull_request closed + # Closed by merging + event_info_dict = get_event_info_from_file(GITLAB_EVENT_PATHS[PR_CLOSED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "closed" + assert event_info_obj.pr_merged_status is True + + # Closed without merging + event_info_dict["action"] = "close" + event_info_dict["raw_request_body"]["object_attributes"]["state"] = "closed" + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.action == "closed" + assert event_info_obj.pr_merged_status is False + + # Test properties for issue_comment events + event_info_dict = get_event_info_from_file(GITLAB_EVENT_PATHS[COMMENT_CREATED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "issue_comment" + assert event_info_obj.comment_id == event_info_dict["raw_request_body"]["object_attributes"]["id"] + assert event_info_obj.comment_body == event_info_dict["raw_request_body"]["object_attributes"]["note"] + assert event_info_obj.issue_number == event_info_dict["raw_request_body"]["merge_request"]["iid"] + assert event_info_obj.issue_url == event_info_dict["raw_request_body"]["merge_request"]["url"] + assert event_info_obj.pr_number == event_info_dict["raw_request_body"]["merge_request"]["iid"] + pr_merged_status = (event_info_dict["raw_request_body"]["merge_request"]["state"] == "merged") + assert event_info_obj.pr_merged_status is pr_merged_status + assert event_info_obj.pr_url == event_info_dict["raw_request_body"]["merge_request"]["url"] + + # Test properties for issue_comment created + assert event_info_obj.action == "created" + assert event_info_obj.comment_created_by == event_info_dict["raw_request_body"]["user"]["username"] + assert event_info_obj.comment_created_by == event_info_obj.event_triggered_by + + # Store the author of the comment + user_dict = event_info_dict["raw_request_body"]["user"] + users = {user_dict["id"]: user_dict["username"]} + comment_created_by = user_dict["username"] + + # Test properties for issue_comment edited + event_info_dict = get_event_info_from_file(GITLAB_EVENT_PATHS[COMMENT_EDITED]) + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "issue_comment" + assert event_info_obj.action == "edited" + + # Check who created vs. updated the comment - should be different users + assert event_info_obj.event_triggered_by == event_info_dict["raw_request_body"]["user"]["username"] + with patch("tools.event_info.gitlab.get_instance") as mock_get_instance: + mock_get_instance.return_value = MockGitlab(users) + assert event_info_obj.comment_created_by == comment_created_by + mock_get_instance.assert_called() + assert event_info_obj.event_triggered_by != event_info_obj.comment_created_by + + # Test handling of non-PR comments + # Test Issue comment handling + event_info_dict["raw_request_body"]["object_attributes"]["noteable_type"] = "Issue" + mr_dict = event_info_dict["raw_request_body"].pop("merge_request") + issue_dict = {} + issue_dict["iid"] = mr_dict["iid"] + issue_dict["url"] = mr_dict["url"] + event_info_dict["raw_request_body"]["issue"] = issue_dict + event_info_obj = event_info.create_event_info_instance(event_info_dict) + event_info_obj.issue_number == issue_dict["iid"] + event_info_obj.issue_url == issue_dict["url"] + + # Test Commit comment handling - should return defaults + event_info_dict["raw_request_body"]["object_attributes"]["noteable_type"] = "Commit" + event_info_dict["raw_request_body"].pop("issue") + event_info_obj = event_info.create_event_info_instance(event_info_dict) + event_info_obj.issue_number == -1 + event_info_obj.issue_url == "" + + # Test unknown event type and action + event_info_dict["type"] = "invalidtype" + event_info_dict["action"] = "invalidaction" + event_info_obj = event_info.create_event_info_instance(event_info_dict) + assert event_info_obj.event_type == "UNKNOWN" + assert event_info_obj.action == "UNKNOWN" + + +# Test create_event_info_instance() +@pytest.mark.parametrize("git_host,expected_type", [ + (git.GITHUB, event_info.GitHubEventInfo), + (git.GITLAB, event_info.GitLabEventInfo), + ("doesnotexist", type(None)) +]) +@patch("tools.event_info.get_git_hosting_platform") +def test_create_event_info_instance(mock_get_git_host, git_host, expected_type): + mock_get_git_host.return_value = git_host + event_info_obj = event_info.create_event_info_instance({"raw_request_body": {}}) + assert type(event_info_obj) is expected_type diff --git a/tests/test_tools_git.py b/tests/test_tools_git.py new file mode 100644 index 00000000..a06ec51c --- /dev/null +++ b/tests/test_tools_git.py @@ -0,0 +1,136 @@ +# Tests for 'tools/git.py' of the EESSI build-and-deploy bot, +# see https://github.com/EESSI/eessi-bot-software-layer +# +# The bot helps with requests to add software installations to the +# EESSI software layer, see https://github.com/EESSI/software-layer +# +# author: Sondre Bergsvaag Risanger (@sondrebr) +# +# license: GPLv2 +# + +# Standard library imports +from contextlib import nullcontext +import copy +from unittest.mock import MagicMock, patch + +# Third party imports (anything installed into the local Python environment) +import pytest + +# Local application imports (anything from EESSI/eessi-bot-software-layer) +from tools import config, git + + +# Set up configs +CFG = config.read_config() + +GITHUB_CFG = copy.deepcopy(CFG) +GITHUB_CFG.set(config.SECTION_GIT, config.GIT_SETTING_HOSTING_PLATFORM, git.GITHUB) + +GITLAB_CFG = copy.deepcopy(CFG) +GITLAB_CFG.set(config.SECTION_GIT, config.GIT_SETTING_HOSTING_PLATFORM, git.GITLAB) + +UNSUPPORTED_PLATFORM = "unsupported_platform" +UNSUPPORTED_PLATFORM_CFG = copy.deepcopy(CFG) +UNSUPPORTED_PLATFORM_CFG.set(config.SECTION_GIT, config.GIT_SETTING_HOSTING_PLATFORM, UNSUPPORTED_PLATFORM) + +NO_HOSTING_PLATFORM_CFG = copy.deepcopy(CFG) +NO_HOSTING_PLATFORM_CFG.remove_option(config.SECTION_GIT, config.GIT_SETTING_HOSTING_PLATFORM) + +# Get configured app/bot name +GITHUB_APP_NAME = GITHUB_CFG.get(config.SECTION_GITHUB, config.GITHUB_SETTING_APP_NAME) +GITLAB_BOT_NAME = GITLAB_CFG.get(config.SECTION_GITLAB, config.GITLAB_SETTING_BOT_NAME) + + +# Test get_git_hosting_platform() +@pytest.mark.parametrize("cfg,expectation", [ + # 'hosting_platform' set to 'github' + (CFG, nullcontext(git.GITHUB)), + (GITHUB_CFG, nullcontext(git.GITHUB)), + + # 'hosting_platform' set to 'gitlab' + (GITLAB_CFG, nullcontext(git.GITLAB)), + + # 'hosting_platform' set to an invalid value - should exit + (UNSUPPORTED_PLATFORM_CFG, pytest.raises(SystemExit)), + + # 'hosting_platform' not set - should exit + (NO_HOSTING_PLATFORM_CFG, pytest.raises(SystemExit)), +]) +@patch("tools.config.read_config") +def test_get_git_hosting_platform(mock_read_config, cfg, expectation): + # Ensure that the Git hosting platform is not cached + git._git_host = None + + mock_read_config.return_value = cfg + + git._git_host = None + + # Test with provided cfg + with expectation as expected: + assert git.get_git_hosting_platform(cfg) == expected + mock_read_config.assert_not_called() + + git._git_host = None + + # Test without provided cfg + with expectation as expected: + assert git.get_git_hosting_platform() == expected + mock_read_config.assert_called_once() + + git._git_host = None + + +# Test connect_to_git_hosting_platform() +@pytest.mark.parametrize("hosting_platform,context", [ + # 'hosting_platform' set to 'github' + (git.GITHUB, patch("connections.github.connect")), + + # 'hosting_platform' set to 'gitlab' + (git.GITLAB, patch("connections.gitlab.connect")), + + # 'hosting_platform' set to an invalid value - should exit + (UNSUPPORTED_PLATFORM, pytest.raises(SystemExit)), + + # 'hosting_platform' not set - should exit + (None, pytest.raises(SystemExit)), +]) +@patch("tools.git.get_git_hosting_platform") +def test_connect_to_git_hosting_platform(mock_get_git_host, hosting_platform, context): + mock_get_git_host.return_value = hosting_platform + with context as context_obj: + git.connect_to_git_hosting_platform() + # For the valid 'hosting_platform' values, assert that connect() is called + if isinstance(context_obj, MagicMock): + context_obj.assert_called_once() + + +# Test get_app_name() +@pytest.mark.parametrize("cfg,expected", [ + # 'hosting_platform' set to 'github', test_app.cfg has 'app_name' set to 'test-app-github' + (CFG, GITHUB_APP_NAME), + (GITHUB_CFG, GITHUB_APP_NAME), + + # 'hosting_platform' set to 'gitlab', test_app.cfg has 'bot_name' set to 'test-bot-gl' + (GITLAB_CFG, GITLAB_BOT_NAME), + + # 'hosting_platform' set to an invalid value + (UNSUPPORTED_PLATFORM_CFG, None), + + # 'hosting_platform' not set + (NO_HOSTING_PLATFORM_CFG, None), +]) +@patch("tools.config.read_config") +@patch("tools.git.get_git_hosting_platform") +def test_get_app_name(mock_get_git_host, mock_read_config, cfg, expected): + hosting_platform = cfg.get(config.SECTION_GIT, config.GIT_SETTING_HOSTING_PLATFORM, fallback=None) + mock_get_git_host.return_value = hosting_platform + mock_read_config.return_value = cfg + + # Test with provided cfg + assert git.get_app_name(cfg) == expected + mock_read_config.assert_not_called() + + # Test without provided cfg + assert git.get_app_name() == expected + mock_read_config.assert_called_once() diff --git a/tools/event_info.py b/tools/event_info.py index 1b6d1bb2..065a7174 100644 --- a/tools/event_info.py +++ b/tools/event_info.py @@ -194,7 +194,7 @@ def __init__(self, event_info): @cached_property def action(self): - gl_action = self._object_attributes["action"] + gl_action = self.event_info["action"] # GL uses a single 'update' action for MRs # Need to check changes to find exact action, e.g. 'labeled' if self.event_type == "pull_request" and gl_action == "update": @@ -279,9 +279,15 @@ def issue_url(self): def label_name(self): # GL sends a single event containing all previous and current labels. # Since we currently only use one label, 'bot:deploy', we can check just for that. + def get_label_titles(labels): + return {label["title"] for label in labels} + label_changes = self._request_body["changes"]["labels"] + current_labels = get_label_titles(label_changes["current"]) + previous_labels = get_label_titles(label_changes["previous"]) + # The difference between the sets will yield all newly added labels - added_labels = set(label_changes["current"]) - set(label_changes["previous"]) + added_labels = current_labels - previous_labels if "bot:deploy" in added_labels: return "bot:deploy" else: