From f08007068465b90b7a010d32180a177087cbfa3d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Tue, 5 Aug 2025 23:02:36 +0200 Subject: [PATCH] Count reopening an pull as opening an pull (#5370) --- .../fixtures/HookPullRequestReopened.json | 396 ++++++++++++++ server/forge/forgejo/fixtures/hooks.go | 3 + server/forge/forgejo/parse.go | 12 +- server/forge/forgejo/parse_test.go | 38 ++ .../fixtures/HookPullRequestReopened.json | 396 ++++++++++++++ server/forge/gitea/fixtures/hooks.go | 3 + server/forge/gitea/parse.go | 12 +- server/forge/gitea/parse_test.go | 38 ++ .../fixtures/HookPullRequestReopened.json | 505 ++++++++++++++++++ server/forge/github/fixtures/hooks.go | 3 + server/forge/github/parse.go | 6 +- server/forge/github/parse_test.go | 10 + .../fixtures/HookPullRequestReopened.json | 173 ++++++ server/forge/gitlab/fixtures/hooks.go | 3 + server/forge/gitlab/gitlab.go | 6 +- server/forge/gitlab/gitlab_test.go | 20 + 16 files changed, 1614 insertions(+), 10 deletions(-) create mode 100644 server/forge/forgejo/fixtures/HookPullRequestReopened.json create mode 100644 server/forge/gitea/fixtures/HookPullRequestReopened.json create mode 100644 server/forge/github/fixtures/HookPullRequestReopened.json create mode 100644 server/forge/gitlab/fixtures/HookPullRequestReopened.json diff --git a/server/forge/forgejo/fixtures/HookPullRequestReopened.json b/server/forge/forgejo/fixtures/HookPullRequestReopened.json new file mode 100644 index 000000000..9b4999282 --- /dev/null +++ b/server/forge/forgejo/fixtures/HookPullRequestReopened.json @@ -0,0 +1,396 @@ +{ + "action": "reopened", + "number": 1, + "pull_request": { + "id": 701944, + "url": "https://codeberg.org/test_it/test_ci_thing/pulls/1", + "number": 1, + "user": { + "id": 2628, + "login": "6543", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "6543@obermui.de", + "avatar_url": "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + "html_url": "https://codeberg.org/6543", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-05T17:04:55+02:00", + "created": "2019-10-12T05:05:49+02:00", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "https://mh.obermui.de", + "description": "\u003ca href=\"https://matrix.to/#/@marddl:obermui.de\" rel=\"nofollow\"\u003e\u003cimg src=\"https://codeberg.org/6543/content/raw/branch/main/matrix-logo.png\"\u003e\u003c/a\u003e\r\n\u003ca rel=\"me\" href=\"https://chaos.social/@6543\"\u003eMastodon\u003c/a\u003e", + "visibility": "public", + "followers_count": 46, + "following_count": 33, + "starred_repos_count": 92, + "username": "6543" + }, + "title": "Some ned more AAAA", + "body": "", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": [], + "requested_reviewers_teams": [], + "state": "open", + "draft": false, + "is_locked": false, + "comments": 0, + "review_comments": 1, + "additions": 1, + "deletions": 0, + "changed_files": 1, + "html_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1", + "diff_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1.diff", + "patch_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1.patch", + "mergeable": false, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "67012991d6c69b1c58378346fca366b864d8d1a1", + "repo_id": 138564, + "repo": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "ssh://git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + } + }, + "head": { + "label": "6543-patch-1", + "ref": "6543-patch-1", + "sha": "36b5813240a9d2daa29b05046d56a53e18f39a3e", + "repo_id": 138564, + "repo": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "ssh://git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + } + }, + "merge_base": "67012991d6c69b1c58378346fca366b864d8d1a1", + "due_date": null, + "created_at": "2025-07-29T16:45:09+02:00", + "updated_at": "2025-08-05T17:06:49+02:00", + "closed_at": null, + "pin_order": 0, + "flow": 0 + }, + "requested_reviewer": null, + "repository": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "ssh://git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + }, + "sender": { + "id": 2628, + "login": "6543", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "6543@noreply.codeberg.org", + "avatar_url": "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + "html_url": "https://codeberg.org/6543", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2019-10-12T05:05:49+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "https://mh.obermui.de", + "description": "\u003ca href=\"https://matrix.to/#/@marddl:obermui.de\" rel=\"nofollow\"\u003e\u003cimg src=\"https://codeberg.org/6543/content/raw/branch/main/matrix-logo.png\"\u003e\u003c/a\u003e\r\n\u003ca rel=\"me\" href=\"https://chaos.social/@6543\"\u003eMastodon\u003c/a\u003e", + "visibility": "public", + "followers_count": 46, + "following_count": 33, + "starred_repos_count": 92, + "username": "6543" + }, + "commit_id": "", + "review": null +} diff --git a/server/forge/forgejo/fixtures/hooks.go b/server/forge/forgejo/fixtures/hooks.go index 4ef70c863..fa5975dd6 100644 --- a/server/forge/forgejo/fixtures/hooks.go +++ b/server/forge/forgejo/fixtures/hooks.go @@ -52,3 +52,6 @@ var HookPullRequestClosed string //go:embed HookRelease.json var HookRelease string + +//go:embed HookPullRequestReopened.json +var HookPullRequestReopened string diff --git a/server/forge/forgejo/parse.go b/server/forge/forgejo/parse.go index 609c73a40..8bf927dcb 100644 --- a/server/forge/forgejo/parse.go +++ b/server/forge/forgejo/parse.go @@ -32,9 +32,10 @@ const ( hookPullRequest = "pull_request" hookRelease = "release" - actionOpen = "opened" - actionSync = "synchronized" - actionClose = "closed" + actionOpen = "opened" + actionSync = "synchronized" + actionClose = "closed" + actionReopen = "reopened" refBranch = "branch" refTag = "tag" @@ -111,7 +112,10 @@ func parsePullRequestHook(payload io.Reader) (*model.Repo, *model.Pipeline, erro } // Don't trigger pipelines for non-code changes ... - if pr.Action != actionOpen && pr.Action != actionSync && pr.Action != actionClose { + if pr.Action != actionOpen && + pr.Action != actionSync && + pr.Action != actionClose && + pr.Action != actionReopen { log.Debug().Msgf("pull_request action is '%s' and no open or sync", pr.Action) return nil, nil, nil } diff --git a/server/forge/forgejo/parse_test.go b/server/forge/forgejo/parse_test.go index a40777521..94cb8391f 100644 --- a/server/forge/forgejo/parse_test.go +++ b/server/forge/forgejo/parse_test.go @@ -214,6 +214,44 @@ func TestForgejoParser(t *testing.T) { PullRequestLabels: []string{}, }, }, + { + name: "pull-request reopen events should handle a PR as it was first created", + data: fixtures.HookPullRequestReopened, + event: "pull_request", + repo: &model.Repo{ + ForgeRemoteID: "138564", + Owner: "test_it", + Name: "test_ci_thing", + FullName: "test_it/test_ci_thing", + Avatar: "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + ForgeURL: "https://codeberg.org/test_it/test_ci_thing", + Clone: "https://codeberg.org/test_it/test_ci_thing.git", + CloneSSH: "ssh://git@codeberg.org/test_it/test_ci_thing.git", + Branch: "main", + PREnabled: true, + IsSCMPrivate: false, + Perm: &model.Perm{ + Pull: true, + Push: true, + Admin: true, + }, + }, + pipe: &model.Pipeline{ + Author: "6543", + Event: "pull_request", + Commit: "36b5813240a9d2daa29b05046d56a53e18f39a3e", + Branch: "main", + Ref: "refs/pull/1/head", + Refspec: "6543-patch-1:main", + Title: "Some ned more AAAA", + Message: "Some ned more AAAA", + Sender: "6543", + Avatar: "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + Email: "6543@noreply.codeberg.org", + ForgeURL: "https://codeberg.org/test_it/test_ci_thing/pulls/1", + PullRequestLabels: []string{}, + }, + }, { name: "pull-request events should handle a PR hook when PR got updated", data: fixtures.HookPullRequestUpdated, diff --git a/server/forge/gitea/fixtures/HookPullRequestReopened.json b/server/forge/gitea/fixtures/HookPullRequestReopened.json new file mode 100644 index 000000000..dee0a5054 --- /dev/null +++ b/server/forge/gitea/fixtures/HookPullRequestReopened.json @@ -0,0 +1,396 @@ +{ + "action": "reopened", + "number": 1, + "pull_request": { + "id": 701944, + "url": "https://codeberg.org/test_it/test_ci_thing/pulls/1", + "number": 1, + "user": { + "id": 2628, + "login": "6543", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "6543@obermui.de", + "avatar_url": "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + "html_url": "https://codeberg.org/6543", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-05T17:04:55+02:00", + "created": "2019-10-12T05:05:49+02:00", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "https://mh.obermui.de", + "description": "\u003ca href=\"https://matrix.to/#/@marddl:obermui.de\" rel=\"nofollow\"\u003e\u003cimg src=\"https://codeberg.org/6543/content/raw/branch/main/matrix-logo.png\"\u003e\u003c/a\u003e\r\n\u003ca rel=\"me\" href=\"https://chaos.social/@6543\"\u003eMastodon\u003c/a\u003e", + "visibility": "public", + "followers_count": 46, + "following_count": 33, + "starred_repos_count": 92, + "username": "6543" + }, + "title": "Some ned more AAAA", + "body": "", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": [], + "requested_reviewers_teams": [], + "state": "open", + "draft": false, + "is_locked": false, + "comments": 0, + "review_comments": 1, + "additions": 1, + "deletions": 0, + "changed_files": 1, + "html_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1", + "diff_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1.diff", + "patch_url": "https://codeberg.org/test_it/test_ci_thing/pulls/1.patch", + "mergeable": false, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "67012991d6c69b1c58378346fca366b864d8d1a1", + "repo_id": 138564, + "repo": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + } + }, + "head": { + "label": "6543-patch-1", + "ref": "6543-patch-1", + "sha": "36b5813240a9d2daa29b05046d56a53e18f39a3e", + "repo_id": 138564, + "repo": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + } + }, + "merge_base": "67012991d6c69b1c58378346fca366b864d8d1a1", + "due_date": null, + "created_at": "2025-07-29T16:45:09+02:00", + "updated_at": "2025-08-05T17:06:49+02:00", + "closed_at": null, + "pin_order": 0, + "flow": 0 + }, + "requested_reviewer": null, + "repository": { + "id": 138564, + "owner": { + "id": 90470, + "login": "test_it", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + "html_url": "https://codeberg.org/test_it", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2023-04-02T15:13:07+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "the [link](https://stackoverflow.com/questions/4212503/how-can-i-set-the-request-header-for-curl#4212535) us curl-ish", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "test_it" + }, + "name": "test_ci_thing", + "full_name": "test_it/test_ci_thing", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 34, + "language": "", + "languages_url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing/languages", + "html_url": "https://codeberg.org/test_it/test_ci_thing", + "url": "https://codeberg.org/api/v1/repos/test_it/test_ci_thing", + "link": "", + "ssh_url": "git@codeberg.org/test_it/test_ci_thing.git", + "clone_url": "https://codeberg.org/test_it/test_ci_thing.git", + "original_url": "", + "website": "", + "stars_count": 1, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2023-08-27T03:32:56+02:00", + "updated_at": "2025-07-29T16:45:07+02:00", + "archived_at": "1970-01-01T01:00:00+01:00", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": true, + "internal_tracker": { + "enable_time_tracker": true, + "allow_only_contributors_to_track_time": true, + "enable_issue_dependencies": true + }, + "has_wiki": true, + "wiki_branch": "master", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": false, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": false, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "merge", + "default_allow_maintainer_edit": false, + "default_update_style": "merge", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + }, + "sender": { + "id": 2628, + "login": "6543", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "6543@noreply.codeberg.org", + "avatar_url": "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + "html_url": "https://codeberg.org/6543", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2019-10-12T05:05:49+02:00", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "https://mh.obermui.de", + "description": "\u003ca href=\"https://matrix.to/#/@marddl:obermui.de\" rel=\"nofollow\"\u003e\u003cimg src=\"https://codeberg.org/6543/content/raw/branch/main/matrix-logo.png\"\u003e\u003c/a\u003e\r\n\u003ca rel=\"me\" href=\"https://chaos.social/@6543\"\u003eMastodon\u003c/a\u003e", + "visibility": "public", + "followers_count": 46, + "following_count": 33, + "starred_repos_count": 92, + "username": "6543" + }, + "commit_id": "", + "review": null +} diff --git a/server/forge/gitea/fixtures/hooks.go b/server/forge/gitea/fixtures/hooks.go index 1395fdbb1..928e2aa5a 100644 --- a/server/forge/gitea/fixtures/hooks.go +++ b/server/forge/gitea/fixtures/hooks.go @@ -52,3 +52,6 @@ var HookPullRequestClosed string //go:embed HookRelease.json var HookRelease string + +//go:embed HookPullRequestReopened.json +var HookPullRequestReopened string diff --git a/server/forge/gitea/parse.go b/server/forge/gitea/parse.go index ae873d64d..714d714d9 100644 --- a/server/forge/gitea/parse.go +++ b/server/forge/gitea/parse.go @@ -34,9 +34,10 @@ const ( hookPullRequest = "pull_request" hookRelease = "release" - actionOpen = "opened" - actionSync = "synchronized" - actionClose = "closed" + actionOpen = "opened" + actionSync = "synchronized" + actionClose = "closed" + actionReopen = "reopened" refBranch = "branch" refTag = "tag" @@ -118,7 +119,10 @@ func parsePullRequestHook(payload io.Reader) (*model.Repo, *model.Pipeline, erro } // Don't trigger pipelines for non-code changes ... - if pr.Action != actionOpen && pr.Action != actionSync && pr.Action != actionClose { + if pr.Action != actionOpen && + pr.Action != actionSync && + pr.Action != actionClose && + pr.Action != actionReopen { log.Debug().Msgf("pull_request action is '%s' and no open or sync", pr.Action) return nil, nil, nil } diff --git a/server/forge/gitea/parse_test.go b/server/forge/gitea/parse_test.go index 437376611..f573a4ab8 100644 --- a/server/forge/gitea/parse_test.go +++ b/server/forge/gitea/parse_test.go @@ -215,6 +215,44 @@ func TestGiteaParser(t *testing.T) { PullRequestLabels: []string{}, }, }, + { + name: "pull-request reopen events should handle a PR as it was first created", + data: fixtures.HookPullRequestReopened, + event: "pull_request", + repo: &model.Repo{ + ForgeRemoteID: "138564", + Owner: "test_it", + Name: "test_ci_thing", + FullName: "test_it/test_ci_thing", + Avatar: "https://codeberg.org/avatars/bb6f3159a98a869b43f20b350542f8fb", + ForgeURL: "https://codeberg.org/test_it/test_ci_thing", + Clone: "https://codeberg.org/test_it/test_ci_thing.git", + CloneSSH: "git@codeberg.org/test_it/test_ci_thing.git", + Branch: "main", + PREnabled: true, + IsSCMPrivate: false, + Perm: &model.Perm{ + Pull: true, + Push: true, + Admin: true, + }, + }, + pipe: &model.Pipeline{ + Author: "6543", + Event: "pull_request", + Commit: "36b5813240a9d2daa29b05046d56a53e18f39a3e", + Branch: "main", + Ref: "refs/pull/1/head", + Refspec: "6543-patch-1:main", + Title: "Some ned more AAAA", + Message: "Some ned more AAAA", + Sender: "6543", + Avatar: "https://codeberg.org/avatars/09a234c768cb9bca78f6b2f82d6af173", + Email: "6543@noreply.codeberg.org", + ForgeURL: "https://codeberg.org/test_it/test_ci_thing/pulls/1", + PullRequestLabels: []string{}, + }, + }, { name: "pull-request events should handle a PR hook when PR got updated", data: fixtures.HookPullRequestUpdated, diff --git a/server/forge/github/fixtures/HookPullRequestReopened.json b/server/forge/github/fixtures/HookPullRequestReopened.json new file mode 100644 index 000000000..e67657de6 --- /dev/null +++ b/server/forge/github/fixtures/HookPullRequestReopened.json @@ -0,0 +1,505 @@ +{ + "action": "reopened", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1", + "id": 2705176047, + "node_id": "PR_kwDOPU9UaM6hPbXv", + "html_url": "https://github.com/6543/test_ci_tmp/pull/1", + "diff_url": "https://github.com/6543/test_ci_tmp/pull/1.diff", + "patch_url": "https://github.com/6543/test_ci_tmp/pull/1.patch", + "issue_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Some ned more AAAA", + "user": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": "yeaaa", + "created_at": "2025-07-29T20:00:54Z", + "updated_at": "2025-08-05T14:34:19Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": null, + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [ + { + "id": 9024465376, + "node_id": "LA_kwDOPU9UaM8AAAACGeZp4A", + "url": "https://api.github.com/repos/6543/test_ci_tmp/labels/documentation", + "name": "documentation", + "color": "0075ca", + "default": true, + "description": "Improvements or additions to documentation" + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/1/comments", + "statuses_url": "https://api.github.com/repos/6543/test_ci_tmp/statuses/36b5813240a9d2daa29b05046d56a53e18f39a3e", + "head": { + "label": "6543:6543-patch-1", + "ref": "6543-patch-1", + "sha": "36b5813240a9d2daa29b05046d56a53e18f39a3e", + "user": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 1028609128, + "node_id": "R_kgDOPU9UaA", + "name": "test_ci_tmp", + "full_name": "6543/test_ci_tmp", + "private": false, + "owner": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/6543/test_ci_tmp", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/6543/test_ci_tmp", + "forks_url": "https://api.github.com/repos/6543/test_ci_tmp/forks", + "keys_url": "https://api.github.com/repos/6543/test_ci_tmp/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/6543/test_ci_tmp/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/6543/test_ci_tmp/teams", + "hooks_url": "https://api.github.com/repos/6543/test_ci_tmp/hooks", + "issue_events_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/events{/number}", + "events_url": "https://api.github.com/repos/6543/test_ci_tmp/events", + "assignees_url": "https://api.github.com/repos/6543/test_ci_tmp/assignees{/user}", + "branches_url": "https://api.github.com/repos/6543/test_ci_tmp/branches{/branch}", + "tags_url": "https://api.github.com/repos/6543/test_ci_tmp/tags", + "blobs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/6543/test_ci_tmp/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/6543/test_ci_tmp/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/6543/test_ci_tmp/statuses/{sha}", + "languages_url": "https://api.github.com/repos/6543/test_ci_tmp/languages", + "stargazers_url": "https://api.github.com/repos/6543/test_ci_tmp/stargazers", + "contributors_url": "https://api.github.com/repos/6543/test_ci_tmp/contributors", + "subscribers_url": "https://api.github.com/repos/6543/test_ci_tmp/subscribers", + "subscription_url": "https://api.github.com/repos/6543/test_ci_tmp/subscription", + "commits_url": "https://api.github.com/repos/6543/test_ci_tmp/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/6543/test_ci_tmp/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/6543/test_ci_tmp/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/6543/test_ci_tmp/contents/{+path}", + "compare_url": "https://api.github.com/repos/6543/test_ci_tmp/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/6543/test_ci_tmp/merges", + "archive_url": "https://api.github.com/repos/6543/test_ci_tmp/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/6543/test_ci_tmp/downloads", + "issues_url": "https://api.github.com/repos/6543/test_ci_tmp/issues{/number}", + "pulls_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls{/number}", + "milestones_url": "https://api.github.com/repos/6543/test_ci_tmp/milestones{/number}", + "notifications_url": "https://api.github.com/repos/6543/test_ci_tmp/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/6543/test_ci_tmp/labels{/name}", + "releases_url": "https://api.github.com/repos/6543/test_ci_tmp/releases{/id}", + "deployments_url": "https://api.github.com/repos/6543/test_ci_tmp/deployments", + "created_at": "2025-07-29T19:35:41Z", + "updated_at": "2025-07-29T19:36:23Z", + "pushed_at": "2025-07-29T19:36:21Z", + "git_url": "git://github.com/6543/test_ci_tmp.git", + "ssh_url": "git@github.com:6543/test_ci_tmp.git", + "clone_url": "https://github.com/6543/test_ci_tmp.git", + "svn_url": "https://github.com/6543/test_ci_tmp", + "homepage": null, + "size": 3, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Dockerfile", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "6543:main", + "ref": "main", + "sha": "67012991d6c69b1c58378346fca366b864d8d1a1", + "user": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 1028609128, + "node_id": "R_kgDOPU9UaA", + "name": "test_ci_tmp", + "full_name": "6543/test_ci_tmp", + "private": false, + "owner": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/6543/test_ci_tmp", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/6543/test_ci_tmp", + "forks_url": "https://api.github.com/repos/6543/test_ci_tmp/forks", + "keys_url": "https://api.github.com/repos/6543/test_ci_tmp/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/6543/test_ci_tmp/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/6543/test_ci_tmp/teams", + "hooks_url": "https://api.github.com/repos/6543/test_ci_tmp/hooks", + "issue_events_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/events{/number}", + "events_url": "https://api.github.com/repos/6543/test_ci_tmp/events", + "assignees_url": "https://api.github.com/repos/6543/test_ci_tmp/assignees{/user}", + "branches_url": "https://api.github.com/repos/6543/test_ci_tmp/branches{/branch}", + "tags_url": "https://api.github.com/repos/6543/test_ci_tmp/tags", + "blobs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/6543/test_ci_tmp/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/6543/test_ci_tmp/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/6543/test_ci_tmp/statuses/{sha}", + "languages_url": "https://api.github.com/repos/6543/test_ci_tmp/languages", + "stargazers_url": "https://api.github.com/repos/6543/test_ci_tmp/stargazers", + "contributors_url": "https://api.github.com/repos/6543/test_ci_tmp/contributors", + "subscribers_url": "https://api.github.com/repos/6543/test_ci_tmp/subscribers", + "subscription_url": "https://api.github.com/repos/6543/test_ci_tmp/subscription", + "commits_url": "https://api.github.com/repos/6543/test_ci_tmp/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/6543/test_ci_tmp/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/6543/test_ci_tmp/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/6543/test_ci_tmp/contents/{+path}", + "compare_url": "https://api.github.com/repos/6543/test_ci_tmp/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/6543/test_ci_tmp/merges", + "archive_url": "https://api.github.com/repos/6543/test_ci_tmp/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/6543/test_ci_tmp/downloads", + "issues_url": "https://api.github.com/repos/6543/test_ci_tmp/issues{/number}", + "pulls_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls{/number}", + "milestones_url": "https://api.github.com/repos/6543/test_ci_tmp/milestones{/number}", + "notifications_url": "https://api.github.com/repos/6543/test_ci_tmp/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/6543/test_ci_tmp/labels{/name}", + "releases_url": "https://api.github.com/repos/6543/test_ci_tmp/releases{/id}", + "deployments_url": "https://api.github.com/repos/6543/test_ci_tmp/deployments", + "created_at": "2025-07-29T19:35:41Z", + "updated_at": "2025-07-29T19:36:23Z", + "pushed_at": "2025-07-29T19:36:21Z", + "git_url": "git://github.com/6543/test_ci_tmp.git", + "ssh_url": "git@github.com:6543/test_ci_tmp.git", + "clone_url": "https://github.com/6543/test_ci_tmp.git", + "svn_url": "https://github.com/6543/test_ci_tmp", + "homepage": null, + "size": 3, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Dockerfile", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1" + }, + "html": { + "href": "https://github.com/6543/test_ci_tmp/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/6543/test_ci_tmp/statuses/36b5813240a9d2daa29b05046d56a53e18f39a3e" + } + }, + "author_association": "OWNER", + "auto_merge": null, + "active_lock_reason": null, + "merged": false, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 0, + "changed_files": 1 + }, + "repository": { + "id": 1028609128, + "node_id": "R_kgDOPU9UaA", + "name": "test_ci_tmp", + "full_name": "6543/test_ci_tmp", + "private": false, + "owner": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/6543/test_ci_tmp", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/6543/test_ci_tmp", + "forks_url": "https://api.github.com/repos/6543/test_ci_tmp/forks", + "keys_url": "https://api.github.com/repos/6543/test_ci_tmp/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/6543/test_ci_tmp/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/6543/test_ci_tmp/teams", + "hooks_url": "https://api.github.com/repos/6543/test_ci_tmp/hooks", + "issue_events_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/events{/number}", + "events_url": "https://api.github.com/repos/6543/test_ci_tmp/events", + "assignees_url": "https://api.github.com/repos/6543/test_ci_tmp/assignees{/user}", + "branches_url": "https://api.github.com/repos/6543/test_ci_tmp/branches{/branch}", + "tags_url": "https://api.github.com/repos/6543/test_ci_tmp/tags", + "blobs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/6543/test_ci_tmp/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/6543/test_ci_tmp/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/6543/test_ci_tmp/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/6543/test_ci_tmp/statuses/{sha}", + "languages_url": "https://api.github.com/repos/6543/test_ci_tmp/languages", + "stargazers_url": "https://api.github.com/repos/6543/test_ci_tmp/stargazers", + "contributors_url": "https://api.github.com/repos/6543/test_ci_tmp/contributors", + "subscribers_url": "https://api.github.com/repos/6543/test_ci_tmp/subscribers", + "subscription_url": "https://api.github.com/repos/6543/test_ci_tmp/subscription", + "commits_url": "https://api.github.com/repos/6543/test_ci_tmp/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/6543/test_ci_tmp/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/6543/test_ci_tmp/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/6543/test_ci_tmp/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/6543/test_ci_tmp/contents/{+path}", + "compare_url": "https://api.github.com/repos/6543/test_ci_tmp/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/6543/test_ci_tmp/merges", + "archive_url": "https://api.github.com/repos/6543/test_ci_tmp/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/6543/test_ci_tmp/downloads", + "issues_url": "https://api.github.com/repos/6543/test_ci_tmp/issues{/number}", + "pulls_url": "https://api.github.com/repos/6543/test_ci_tmp/pulls{/number}", + "milestones_url": "https://api.github.com/repos/6543/test_ci_tmp/milestones{/number}", + "notifications_url": "https://api.github.com/repos/6543/test_ci_tmp/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/6543/test_ci_tmp/labels{/name}", + "releases_url": "https://api.github.com/repos/6543/test_ci_tmp/releases{/id}", + "deployments_url": "https://api.github.com/repos/6543/test_ci_tmp/deployments", + "created_at": "2025-07-29T19:35:41Z", + "updated_at": "2025-07-29T19:36:23Z", + "pushed_at": "2025-07-29T19:36:21Z", + "git_url": "git://github.com/6543/test_ci_tmp.git", + "ssh_url": "git@github.com:6543/test_ci_tmp.git", + "clone_url": "https://github.com/6543/test_ci_tmp.git", + "svn_url": "https://github.com/6543/test_ci_tmp", + "homepage": null, + "size": 3, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Dockerfile", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "6543", + "id": 24977596, + "node_id": "MDQ6VXNlcjI0OTc3NTk2", + "avatar_url": "https://avatars.githubusercontent.com/u/24977596?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/6543", + "html_url": "https://github.com/6543", + "followers_url": "https://api.github.com/users/6543/followers", + "following_url": "https://api.github.com/users/6543/following{/other_user}", + "gists_url": "https://api.github.com/users/6543/gists{/gist_id}", + "starred_url": "https://api.github.com/users/6543/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/6543/subscriptions", + "organizations_url": "https://api.github.com/users/6543/orgs", + "repos_url": "https://api.github.com/users/6543/repos", + "events_url": "https://api.github.com/users/6543/events{/privacy}", + "received_events_url": "https://api.github.com/users/6543/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + } +} diff --git a/server/forge/github/fixtures/hooks.go b/server/forge/github/fixtures/hooks.go index e62209f79..714b0baad 100644 --- a/server/forge/github/fixtures/hooks.go +++ b/server/forge/github/fixtures/hooks.go @@ -73,3 +73,6 @@ var HookPullRequestClosed string //go:embed HookRelease.json var HookRelease string + +//go:embed HookPullRequestReopened.json +var HookPullRequestReopened string diff --git a/server/forge/github/parse.go b/server/forge/github/parse.go index bab2ecefd..67835b9f3 100644 --- a/server/forge/github/parse.go +++ b/server/forge/github/parse.go @@ -33,6 +33,7 @@ const ( hookField = "payload" actionOpen = "opened" + actionReopen = "reopened" actionClose = "closed" actionSync = "synchronize" actionReleased = "released" @@ -148,7 +149,10 @@ func parseDeployHook(hook *github.DeploymentEvent) (*model.Repo, *model.Pipeline // parsePullHook parses a pull request hook and returns the Repo and Pipeline // details. func parsePullHook(hook *github.PullRequestEvent, merge bool) (*github.PullRequest, *model.Repo, *model.Pipeline, error) { - if hook.GetAction() != actionOpen && hook.GetAction() != actionSync && hook.GetAction() != actionClose { + if hook.GetAction() != actionOpen && + hook.GetAction() != actionSync && + hook.GetAction() != actionClose && + hook.GetAction() != actionReopen { return nil, nil, nil, nil } diff --git a/server/forge/github/parse_test.go b/server/forge/github/parse_test.go index a48f0ff5a..294254d2f 100644 --- a/server/forge/github/parse_test.go +++ b/server/forge/github/parse_test.go @@ -126,4 +126,14 @@ func Test_parseHook(t *testing.T) { assert.Len(t, strings.Split(b.Ref, "/"), 3) assert.True(t, strings.HasPrefix(b.Ref, "refs/tags/")) }) + + t.Run("reopen a pull", func(t *testing.T) { + req := testHookRequest([]byte(fixtures.HookPullRequestReopened), hookPull) + p, r, b, err := parseHook(req, false) + assert.NoError(t, err) + assert.NotNil(t, r) + assert.NotNil(t, b) + assert.NotNil(t, p) + assert.Equal(t, model.EventPull, b.Event) + }) } diff --git a/server/forge/gitlab/fixtures/HookPullRequestReopened.json b/server/forge/gitlab/fixtures/HookPullRequestReopened.json new file mode 100644 index 000000000..6f242b944 --- /dev/null +++ b/server/forge/gitlab/fixtures/HookPullRequestReopened.json @@ -0,0 +1,173 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 4575606, + "name": "6543", + "username": "real6543", + "avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png", + "email": "[REDACTED]" + }, + "project": { + "id": 72081820, + "name": "test_ci_tmp", + "description": null, + "web_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "git_http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git", + "namespace": "demoaccount2-commits-group", + "visibility_level": 0, + "path_with_namespace": "demoaccount2-commits-group/test_ci_tmp", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git" + }, + "object_attributes": { + "assignee_id": null, + "author_id": 29352663, + "created_at": "2025-07-29 20:00:54 UTC", + "description": "yeaaa", + "draft": false, + "head_pipeline_id": null, + "id": 403287663, + "iid": 1, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": null, + "merge_error": null, + "merge_params": {}, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "source_branch": "6543-patch-1", + "source_project_id": 72081820, + "state_id": 1, + "target_branch": "main", + "target_project_id": 72081820, + "time_estimate": 0, + "title": "Some ned more AAAA", + "updated_at": "2025-08-05 14:44:26 UTC", + "updated_by_id": null, + "prepared_at": null, + "assignee_ids": [], + "blocking_discussions_resolved": true, + "detailed_merge_status": "mergeable", + "first_contribution": true, + "human_time_change": null, + "human_time_estimate": null, + "human_total_time_spent": null, + "labels": [ + { + "id": 41869663, + "title": "documentation", + "color": "#0075ca", + "project_id": 72081820, + "created_at": "2025-07-30 00:40:00 UTC", + "updated_at": "2025-07-30 00:40:00 UTC", + "template": false, + "description": null, + "type": "ProjectLabel", + "group_id": null + } + ], + "last_commit": { + "id": "36b5813240a9d2daa29b05046d56a53e18f39a3e", + "message": "Some ned more AAAA\n", + "title": "Some ned more AAAA", + "timestamp": "2025-07-29T16:45:02+02:00", + "url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp/-/commit/36b5813240a9d2daa29b05046d56a53e18f39a3e", + "author": { + "name": "6543", + "email": "[REDACTED]" + } + }, + "reviewer_ids": [29352668], + "source": { + "id": 72081820, + "name": "test_ci_tmp", + "description": null, + "web_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "git_http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git", + "namespace": "demoaccount2-commits-group", + "visibility_level": 0, + "path_with_namespace": "demoaccount2-commits-group/test_ci_tmp", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git" + }, + "state": "opened", + "target": { + "id": 72081820, + "name": "test_ci_tmp", + "description": null, + "web_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "avatar_url": null, + "git_ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "git_http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git", + "namespace": "demoaccount2-commits-group", + "visibility_level": 0, + "path_with_namespace": "demoaccount2-commits-group/test_ci_tmp", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp", + "url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "ssh_url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "http_url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp.git" + }, + "time_change": 0, + "total_time_spent": 0, + "url": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp/-/merge_requests/1", + "work_in_progress": false, + "approval_rules": [], + "action": "reopen" + }, + "labels": [ + { + "id": 41869663, + "title": "documentation", + "color": "#0075ca", + "project_id": 72081820, + "created_at": "2025-07-30 00:40:00 UTC", + "updated_at": "2025-07-30 00:40:00 UTC", + "template": false, + "description": null, + "type": "ProjectLabel", + "group_id": null + } + ], + "changes": { + "state_id": { + "previous": 2, + "current": 1 + }, + "updated_at": { + "previous": "2025-08-05 14:44:14 UTC", + "current": "2025-08-05 14:44:26 UTC" + } + }, + "repository": { + "name": "test_ci_tmp", + "url": "git@gitlab.com:demoaccount2-commits-group/test_ci_tmp.git", + "description": null, + "homepage": "https://gitlab.com/demoaccount2-commits-group/test_ci_tmp" + }, + "reviewers": [ + { + "id": 29352668, + "name": "Placeholder github Source User", + "username": "demoaccount2commits_placeholder_6s82rp", + "avatar_url": "https://secure.gravatar.com/avatar/6d8b40c6bd417e69e359e712b55471dfc72af88c732fed9fe8d276a210aa5dd8?s=80&d=identicon", + "email": "[REDACTED]" + } + ] +} diff --git a/server/forge/gitlab/fixtures/hooks.go b/server/forge/gitlab/fixtures/hooks.go index 6846d026c..6002d2eae 100644 --- a/server/forge/gitlab/fixtures/hooks.go +++ b/server/forge/gitlab/fixtures/hooks.go @@ -66,3 +66,6 @@ var HookPullRequestMerged []byte //go:embed WebhookReleaseBody.json var WebhookReleaseBody []byte + +//go:embed HookPullRequestReopened.json +var HookPullRequestReopened []byte diff --git a/server/forge/gitlab/gitlab.go b/server/forge/gitlab/gitlab.go index 6b52e0aa7..f1961d0ec 100644 --- a/server/forge/gitlab/gitlab.go +++ b/server/forge/gitlab/gitlab.go @@ -643,7 +643,11 @@ func (g *GitLab) Hook(ctx context.Context, req *http.Request) (*model.Repo, *mod switch event := parsed.(type) { case *gitlab.MergeEvent: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events - if event.ObjectAttributes.OldRev == "" && event.ObjectAttributes.Action != "open" && event.ObjectAttributes.Action != "close" && event.ObjectAttributes.Action != "merge" { + if event.ObjectAttributes.OldRev == "" && + event.ObjectAttributes.Action != "open" && + event.ObjectAttributes.Action != "close" && + event.ObjectAttributes.Action != "merge" && + event.ObjectAttributes.Action != "reopen" { return nil, nil, &forge_types.ErrIgnoreEvent{Event: string(eventType), Reason: "no code changes"} } mergeIID, repo, pipeline, err := convertMergeRequestHook(event, req) diff --git a/server/forge/gitlab/gitlab_test.go b/server/forge/gitlab/gitlab_test.go index 847690cbc..354da4766 100644 --- a/server/forge/gitlab/gitlab_test.go +++ b/server/forge/gitlab/gitlab_test.go @@ -188,6 +188,26 @@ func Test_GitLab(t *testing.T) { } }) + t.Run("merge request reopened", func(t *testing.T) { + req, _ := http.NewRequest( + fixtures.ServiceHookMethod, + fixtures.ServiceHookURL.String(), + bytes.NewReader(fixtures.HookPullRequestReopened), + ) + req.Header = fixtures.ServiceHookHeaders + + hookRepo, pipeline, err := client.Hook(ctx, req) + assert.NoError(t, err) + if assert.NotNil(t, hookRepo) && assert.NotNil(t, pipeline) { + assert.Equal(t, "main", hookRepo.Branch) + assert.Equal(t, "demoaccount2-commits-group", hookRepo.Owner) + assert.Equal(t, "test_ci_tmp", hookRepo.Name) + assert.Equal(t, "Some ned more AAAA", pipeline.Title) + assert.Len(t, pipeline.ChangedFiles, 0) + assert.Equal(t, model.EventPull, pipeline.Event) + } + }) + t.Run("ignore merge request hook without changes", func(t *testing.T) { req, _ := http.NewRequest( fixtures.ServiceHookMethod,