From fb9033f0c589393873ba8e1cef6b7e18585584a4 Mon Sep 17 00:00:00 2001 From: mynk8 <166798988+mynk8@users.noreply.github.com> Date: Thu, 7 Aug 2025 22:17:48 +0530 Subject: [PATCH 1/4] Implement Forgejo event handling in Packit Service --- packit_service/events/__init__.py | 2 + packit_service/events/forgejo/__init__.py | 6 + packit_service/events/forgejo/abstract.py | 17 ++ packit_service/events/forgejo/issue.py | 92 +++++++++ packit_service/events/forgejo/pr.py | 121 ++++++++++++ packit_service/events/forgejo/push.py | 29 +++ packit_service/service/api/webhooks.py | 138 +++++++++++++ packit_service/worker/parser.py | 182 ++++++++++++++++++ .../worker/reporting/reporters/base.py | 4 + .../worker/reporting/reporters/forgejo.py | 46 +++++ 10 files changed, 637 insertions(+) create mode 100644 packit_service/events/forgejo/__init__.py create mode 100644 packit_service/events/forgejo/abstract.py create mode 100644 packit_service/events/forgejo/issue.py create mode 100644 packit_service/events/forgejo/pr.py create mode 100644 packit_service/events/forgejo/push.py create mode 100644 packit_service/worker/reporting/reporters/forgejo.py diff --git a/packit_service/events/__init__.py b/packit_service/events/__init__.py index 58382dc16..472ac9c94 100644 --- a/packit_service/events/__init__.py +++ b/packit_service/events/__init__.py @@ -7,6 +7,7 @@ copr, enums, event, + forgejo, github, gitlab, koji, @@ -22,6 +23,7 @@ anitya.__name__, github.__name__, gitlab.__name__, + forgejo.__name__, koji.__name__, openscanhub.__name__, pagure.__name__, diff --git a/packit_service/events/forgejo/__init__.py b/packit_service/events/forgejo/__init__.py new file mode 100644 index 000000000..5197842b6 --- /dev/null +++ b/packit_service/events/forgejo/__init__.py @@ -0,0 +1,6 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +from . import abstract, issue, pr, push + +__all__ = [abstract.__name__, push.__name__, issue.__name__, pr.__name__] diff --git a/packit_service/events/forgejo/abstract.py b/packit_service/events/forgejo/abstract.py new file mode 100644 index 000000000..8debe6a51 --- /dev/null +++ b/packit_service/events/forgejo/abstract.py @@ -0,0 +1,17 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +from typing import Optional + +from ..abstract.base import ForgeIndependent + + +class ForgejoEvent(ForgeIndependent): + def __init__(self, project_url: str, pr_id: Optional[int] = None, **kwargs): + super().__init__(pr_id=pr_id) + self.project_url: str = project_url + # git ref that can be 'git checkout'-ed + self.git_ref: Optional[str] = None + self.identifier: Optional[str] = ( + None # will be shown to users -- e.g. in logs or in the copr-project name + ) diff --git a/packit_service/events/forgejo/issue.py b/packit_service/events/forgejo/issue.py new file mode 100644 index 000000000..13415a896 --- /dev/null +++ b/packit_service/events/forgejo/issue.py @@ -0,0 +1,92 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +# SPDX-License-Identifier: MIT + +from typing import Optional + +from ogr.abstract import Comment as OgrComment + +from ..abstract.comment import Issue as AbstractIssueCommentEvent +from ..enums import IssueCommentAction +from .abstract import ForgejoEvent + + +class Comment(AbstractIssueCommentEvent, ForgejoEvent): + def __init__( + self, + action: IssueCommentAction, + issue_id: int, + repo_namespace: str, + repo_name: str, + target_repo: str, + project_url: str, + actor: str, + comment: str, + comment_id: int, + tag_name: str = "", + base_ref: Optional[str] = "main", + comment_object: Optional[OgrComment] = None, + dist_git_project_url=None, + ) -> None: + super().__init__( + issue_id=issue_id, + repo_namespace=repo_namespace, + repo_name=repo_name, + project_url=project_url, + comment=comment, + comment_id=comment_id, + tag_name=tag_name, + comment_object=comment_object, + dist_git_project_url=dist_git_project_url, + ) + self.action = action + self.actor = actor + self.base_ref = base_ref + self.target_repo = target_repo + self.identifier = str(issue_id) + + @classmethod + def event_type(cls) -> str: + return "forgejo.issue.Comment" + + @property + def tag_name(self): + """ + For Forgejo issue comments, return the tag_name passed in constructor + without making API calls to avoid authentication issues. + """ + return self._tag_name + + @tag_name.setter + def tag_name(self, value: str) -> None: + self._tag_name = value + + @property + def commit_sha(self) -> Optional[str]: + """ + For Forgejo issue comments, return the commit_sha passed in constructor + without making API calls to avoid authentication issues. + """ + return self._commit_sha + + @commit_sha.setter + def commit_sha(self, value: Optional[str]) -> None: + self._commit_sha = value + + def get_dict(self, default_dict: Optional[dict] = None) -> dict: + """ + Override get_dict to avoid accessing properties that make API calls. + """ + # Get the basic dict from CommentEvent, not from Issue to avoid tag_name access + from ..abstract.comment import CommentEvent + + result = CommentEvent.get_dict(self, default_dict=default_dict) + + # Add the specific fields we need without triggering API calls + result["action"] = self.action.value + result["issue_id"] = self.issue_id + result["tag_name"] = self._tag_name # Use the private attribute directly + result["commit_sha"] = self._commit_sha # Use the private attribute directly + + return result diff --git a/packit_service/events/forgejo/pr.py b/packit_service/events/forgejo/pr.py new file mode 100644 index 000000000..a2138998b --- /dev/null +++ b/packit_service/events/forgejo/pr.py @@ -0,0 +1,121 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +from typing import Optional + +from ogr.abstract import Comment as OgrComment +from ogr.abstract import GitProject + +from packit_service.service.db_project_events import AddPullRequestEventToDb + +from ..abstract.comment import PullRequest as AbstractPRCommentEvent +from ..enums import PullRequestAction, PullRequestCommentAction +from .abstract import ForgejoEvent + + +class Action(AddPullRequestEventToDb, ForgejoEvent): + def __init__( + self, + action: PullRequestAction, + pr_id: int, + base_repo_namespace: str, + base_repo_name: str, + base_ref: str, + target_repo_namespace: str, + target_repo_name: str, + project_url: str, + commit_sha: str, + commit_sha_before: str, + actor: str, + body: str, + ): + super().__init__(project_url=project_url, pr_id=pr_id) + self.action = action + self.base_repo_namespace = base_repo_namespace + self.base_repo_name = base_repo_name + self.base_ref = base_ref + self.target_repo_namespace = target_repo_namespace + self.target_repo_name = target_repo_name + self.commit_sha = commit_sha + self.commit_sha_before = commit_sha_before + self.actor = actor + self.identifier = str(pr_id) + self._pr_id = pr_id + self.git_ref = None # use pr_id for checkout + self.body = body + + def get_dict(self, default_dict: Optional[dict] = None) -> dict: + result = super().get_dict() + result["action"] = result["action"].value + return result + + @classmethod + def event_type(cls) -> str: + return "forgejo.pr.Action" + + def get_base_project(self) -> GitProject: + return self.project.service.get_project( + namespace=self.target_repo_namespace, + repo=self.target_repo_name, + ) + + +class Comment(AbstractPRCommentEvent, ForgejoEvent): + def __init__( + self, + action: PullRequestCommentAction, + pr_id: int, + base_repo_namespace: str, + base_repo_name: Optional[str], + base_ref: Optional[str], + target_repo_namespace: str, + target_repo_name: str, + project_url: str, + actor: str, + comment: str, + comment_id: int, + commit_sha: Optional[str] = None, + comment_object: Optional[OgrComment] = None, + ) -> None: + super().__init__( + pr_id=pr_id, + project_url=project_url, + comment=comment, + comment_id=comment_id, + commit_sha=commit_sha, + comment_object=comment_object, + ) + self.action = action + self.base_repo_namespace = base_repo_namespace + self.base_repo_name = base_repo_name + self.base_ref = base_ref + self.target_repo_namespace = target_repo_namespace + self.target_repo_name = target_repo_name + self.actor = actor + self.identifier = str(pr_id) + self.git_ref = None + self.pr_id = pr_id + + @classmethod + def event_type(cls) -> str: + return "forgejo.pr.Comment" + + def get_dict(self, default_dict: Optional[dict] = None) -> dict: + """ + Override get_dict to avoid accessing properties that make API calls. + Use private attributes directly, similar to forgejo/issue.py. + """ + from ..abstract.comment import CommentEvent + + result = CommentEvent.get_dict(self, default_dict=default_dict) + result.pop("_comment_object") + result["action"] = self.action.value + result["pr_id"] = self.pr_id + result["commit_sha"] = self._commit_sha + return result + + def get_base_project(self) -> GitProject: + return self.project.service.get_project( + namespace=self.target_repo_namespace, + repo=self.target_repo_name, + ) diff --git a/packit_service/events/forgejo/push.py b/packit_service/events/forgejo/push.py new file mode 100644 index 000000000..cc88b21ba --- /dev/null +++ b/packit_service/events/forgejo/push.py @@ -0,0 +1,29 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +from packit_service.service.db_project_events import AddBranchPushEventToDb + +from .abstract import ForgejoEvent + + +class Commit(AddBranchPushEventToDb, ForgejoEvent): + def __init__( + self, + repo_namespace: str, + repo_name: str, + git_ref: str, + project_url: str, + commit_sha: str, + commit_sha_before: str, + ): + super().__init__(project_url=project_url) + self.repo_namespace = repo_namespace + self.repo_name = repo_name + self.git_ref = git_ref + self.commit_sha = commit_sha + self.commit_sha_before = commit_sha_before + self.identifier = git_ref + + @classmethod + def event_type(cls) -> str: + return "forgejo.push.Commit" diff --git a/packit_service/service/api/webhooks.py b/packit_service/service/api/webhooks.py index 1e792f4de..01fbc80a9 100644 --- a/packit_service/service/api/webhooks.py +++ b/packit_service/service/api/webhooks.py @@ -45,6 +45,15 @@ }, ) +ping_payload_forgejo = ns.model( + "Forgejo webhook ping", + { + "zen": fields.String(required=False), + "hook_id": fields.String(required=False), + "hook": fields.String(required=False), + }, +) + github_webhook_calls = Counter( "github_webhook_calls", "Number of times the GitHub webhook is called", @@ -344,3 +353,132 @@ def interested(): logger.debug(f"{event_type} {' (not interested)' if not _interested else ''}") return _interested + + +forgejo_webhook_calls = Counter( + "forgejo_webhook_calls", + "Number of times the Forgejo webhook is called", + ["result", "process_id"], +) + + +@ns.route("/forgejo") +class ForgejoWebhook(Resource): + @ns.response(HTTPStatus.OK.value, "Webhook accepted, returning reply") + @ns.response( + HTTPStatus.ACCEPTED.value, + "Webhook accepted, request is being processed", + ) + @ns.response(HTTPStatus.BAD_REQUEST.value, "Bad request data") + @ns.response(HTTPStatus.UNAUTHORIZED.value, "X-Forgejo-Signature validation failed") + @ns.expect(ping_payload_forgejo) + def post(self): + msg = request.json + + if not msg: + logger.debug("/webhooks/forgejo: no JSON data received.") + forgejo_webhook_calls.labels(result="no_data", process_id=os.getpid()).inc() + + return "No JSON data.", HTTPStatus.BAD_REQUEST + + if all([msg.get("zen"), msg.get("hook_id"), msg.get("hook")]): + logger.debug(f"/webhooks/forgejo received ping event: {msg['hook']}") + forgejo_webhook_calls.labels(result="pong", process_id=os.getpid()).inc() + return "Pong!", HTTPStatus.OK + # TODO + # try: + # self.validate_token() + # except ValidationFailed as exc: + # logger.info(f"/webhooks/forgejo {exc}") + # forgejo_webhook_calls.labels( + # result="invalid_signature", + # process_id=os.getpid(), + # ).inc() + # return str(exc), HTTPStatus.UNAUTHORIZED + # + if not self.interested(msg): + forgejo_webhook_calls.labels( + result="not_interested", + process_id=os.getpid(), + ).inc() + return "Thanks but we don't care about this event", HTTPStatus.ACCEPTED + + celery_app.send_task( + name=getenv("CELERY_MAIN_TASK_NAME") or CELERY_DEFAULT_MAIN_TASK_NAME, + kwargs={ + "event": msg, + "source": "forgejo", + "event_type": request.headers.get("X-Forgejo-Event"), + }, + ) + forgejo_webhook_calls.labels(result="accepted", process_id=os.getpid()).inc() + + return "Webhook accepted. We thank you, Forgejo.", HTTPStatus.ACCEPTED + + def validate_token(self): + """ + Validate the Forgejo webhook signature. + The signature is a direct SHA256 HMAC hex digest of the raw request body + using the webhook secret as the key, in a similar fashion to Github. + + """ + if "X-Forgejo-Signature" not in request.headers: + logger.debug("Ain't validating signatures.") + return + + if not (webhook_secret := getenv("WEBHOOK_SECRET")): + msg = "'webhook_secret' not specified in the config." + logger.error(msg) + raise ValidationFailed(msg) + + # Get raw payload + + payload = request.get_data() + if not payload: + msg = "No payload received." + logger.error(msg) + raise ValidationFailed(msg) + + data_hmac = hmac.new(webhook_secret.encode(), msg=payload, digestmod=sha256) + payload_signature = data_hmac.hexdigest() + header_sig = request.headers["X-Forgejo-Signature"] + + if header_sig != payload_signature: + msg = "Payload signature validation failed." + + logger.warning(msg) + logger.debug( + f"X-Forgejo-Signature: {header_sig!r} != computed: {payload_signature}", + ) + raise ValidationFailed(msg) + + @staticmethod + def interested(msg): + """ + + Check whether we want to process this event. + + + Args: + msg: The webhook payload as a dictionary + + Returns: + bool: False if we are not interested in this kind of event + """ + event = request.headers.get("X-Forgejo-Event") + uuid = request.headers.get("X-Forgejo-Delivery") + action = msg.get("action") if msg else None + deleted = msg.get("deleted") if msg else None + + interests = { + "push": not deleted, + "release": action == "published", + "issues": action in {"opened", "edited", "closed", "reopened"}, + "issue_comment": action in {"created", "edited"}, + "pull_request": action in {"opened", "edited", "closed", "reopened", "synchronize"}, + } + + _interested = interests.get(event or "", False) + + logger.debug(f"{event} {uuid}{'' if _interested else ' (not interested)'}") + return _interested diff --git a/packit_service/worker/parser.py b/packit_service/worker/parser.py index 7128e5057..f5f68c3b0 100644 --- a/packit_service/worker/parser.py +++ b/packit_service/worker/parser.py @@ -26,6 +26,7 @@ abstract, anitya, copr, + forgejo, github, gitlab, koji, @@ -1924,6 +1925,182 @@ def parse_logdetective_analysis_event(event) -> Optional[logdetective.Result]: pr_id=pr_id, ) + @staticmethod + def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]: + raw_ref = event.get("ref") + before = event.get("before") + after = event.get("after") + pusher = nested_get(event, "pusher", "login") or nested_get(event, "pusher", "name") + + if not (raw_ref and after and before and pusher): + return None + + # Forgejo sets `deleted` identically to GitHub + if event.get("deleted"): + logger.info(f"Forgejo push event on '{raw_ref}' by {pusher} to delete ref") + + return None + + # Number of commits introduced by this push + commits = event.get("commits") or [] + num_commits = len(commits) + + # Strip the ref prefix to get the branch/tag name + _, ref_type, ref_name = raw_ref.split("/", 2) + if ref_type != "heads": + logger.debug(f"Forgejo push event ignored – not a branch push ('{raw_ref}')") + return None + + logger.info( + f"Forgejo push event on '{ref_name}': " + f"{before[:8]} → {after[:8]} by {pusher} " + f"({num_commits} {'commit' if num_commits == 1 else 'commits'})" + ) + + repo_namespace = nested_get(event, "repository", "owner", "login") + repo_name = nested_get(event, "repository", "name") + repo_url = nested_get(event, "repository", "html_url") + + if not (repo_namespace and repo_name): + logger.warning("Forgejo push event missing repository namespace/name") + return None + + return forgejo.push.Commit( + repo_namespace=repo_namespace, + repo_name=repo_name, + git_ref=ref_name, + project_url=repo_url, + commit_sha=after, + commit_sha_before=before, + ) + + @staticmethod + def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: + """ + Parse Forgejo PR action events, only triggering for relevant actions. + Supported actions: 'opened', 'reopened', 'synchronize'. + Skips others like 'closed'. + + """ + action_str = event.get("action") + # Only trigger for these actions + supported_actions = {"opened", "reopened", "synchronize"} + if action_str not in supported_actions: + logger.info(f"Skipping PR action: {action_str}") + return None + + pr = event.get("pull_request") + if not pr: + logger.warning("No pull_request in event.") + return None + + pr_id = pr.get("number") + actor = event.get("sender", {}).get("login") + repo = event.get("repository", {}) + base = pr.get("base") + head = pr.get("head") + body = pr.get("body") + + # Check all required nested fields + try: + base_repo_namespace = base["repo"]["owner"]["login"] + base_repo_name = base["repo"]["name"] + base_ref = base["ref"] + target_repo_namespace = head["repo"]["owner"]["login"] + target_repo_name = head["repo"]["name"] + project_url = repo["html_url"] + commit_sha = head["sha"] + except (TypeError, KeyError): + logger.warning("Missing required nested fields in PR event.") + return None + + return forgejo.pr.Action( + action=PullRequestAction[action_str], + pr_id=pr_id, + base_repo_namespace=base_repo_namespace, + base_repo_name=base_repo_name, + base_ref=base_ref, + target_repo_namespace=target_repo_namespace, + target_repo_name=target_repo_name, + project_url=project_url, + commit_sha=commit_sha, + commit_sha_before=event.get("before", ""), # Optional, might be empty + actor=actor, + body=body, + ) + + @staticmethod + def parse_forgejo_comment_event( + event: dict, + ) -> Optional[Union[forgejo.pr.Comment, forgejo.issue.Comment]]: + """Since Forgejo treats PR as special issues the comments are basically on issues, + we need to distinguish between Forgejo issue and PR comments and parse accordingly.""" + + issue_id = nested_get(event, "issue", "number") + action = event.get("action") + if action not in {"created", "edited"} or not issue_id: + return None + + # Only treat as PR if 'pull_request' is present and not None + issue_dict = event.get("issue", {}) + is_pr = "pull_request" in issue_dict and issue_dict["pull_request"] is not None + + comment = nested_get(event, "comment", "body") + comment_id = nested_get(event, "comment", "id") + logger.info( + f"Forgejo {'PR' if is_pr else 'issue'}#{issue_id} " + f"comment: {comment!r} id#{comment_id} {action!r} event." + ) + + base_repo_namespace = nested_get(event, "issue", "user", "login") + base_repo_name = nested_get(event, "repository", "name") + + user_login = nested_get(event, "comment", "user", "login") + target_repo_namespace = nested_get(event, "repository", "owner", "login") + + target_repo_name = nested_get(event, "repository", "name") + https_url = nested_get(event, "repository", "html_url") + + if not ( + base_repo_name and base_repo_namespace and target_repo_name and target_repo_namespace + ): + logger.warning("Missing repo info in Forgejo event.") + return None + + if not user_login: + logger.warning("No user login in comment.") + return None + + if is_pr: + return forgejo.pr.Comment( + action=PullRequestCommentAction[action], + pr_id=issue_id, + base_ref="", + base_repo_namespace=base_repo_namespace, + base_repo_name=base_repo_name, + target_repo_namespace=target_repo_namespace, + target_repo_name=target_repo_name, + project_url=https_url, + actor=user_login, + comment=comment, + comment_id=comment_id, + commit_sha=None, + ) + return forgejo.issue.Comment( + action=IssueCommentAction[action], + issue_id=issue_id, + repo_namespace=base_repo_namespace, + repo_name=base_repo_name, + target_repo=f"{target_repo_namespace}/{target_repo_name}", + project_url=https_url, + actor=user_login, + comment=comment, + comment_id=comment_id, + tag_name="", + base_ref="", + dist_git_project_url=None, + ) + # The .__func__ are needed for Python < 3.10 MAPPING: ClassVar[dict[str, dict[str, Callable]]] = { "github": { @@ -1944,6 +2121,11 @@ def parse_logdetective_analysis_event(event) -> Optional[logdetective.Result]: "Pipeline Hook": parse_pipeline_event.__func__, # type: ignore "Release Hook": parse_gitlab_release_event.__func__, # type: ignore }, + "forgejo": { + "push": parse_forgejo_push_event.__func__, # type: ignore + "issue_comment": parse_forgejo_comment_event.__func__, # type: ignore + "pull_request": parse_forgejo_pr_event.__func__, # type: ignore + }, "fedora-messaging": { "pagure.pull-request.flag.added": parse_pagure_pr_flag_event.__func__, # type: ignore "pagure.pull-request.flag.updated": parse_pagure_pr_flag_event.__func__, # type: ignore diff --git a/packit_service/worker/reporting/reporters/base.py b/packit_service/worker/reporting/reporters/base.py index 7c9905c92..c34eaa873 100644 --- a/packit_service/worker/reporting/reporters/base.py +++ b/packit_service/worker/reporting/reporters/base.py @@ -6,6 +6,7 @@ from typing import Callable, Optional, Union from ogr.abstract import GitProject, PullRequest +from ogr.services.forgejo import ForgejoProject from ogr.services.github import GithubProject from ogr.services.gitlab import GitlabProject from ogr.services.pagure import PagureProject @@ -56,6 +57,7 @@ def get_instance( The `project` determines type of the reporter returned. All other parameters are passed to the initializer of the chosen reporter. """ + from .forgejo import StatusReporterForgejo from .github import StatusReporterGithubChecks from .gitlab import StatusReporterGitlab from .pagure import StatusReporterPagure @@ -67,6 +69,8 @@ def get_instance( reporter = StatusReporterGitlab elif isinstance(project, PagureProject): reporter = StatusReporterPagure + elif isinstance(project, ForgejoProject): + reporter = StatusReporterForgejo return reporter(project, commit_sha, packit_user, project_event_id, pr_id) @property diff --git a/packit_service/worker/reporting/reporters/forgejo.py b/packit_service/worker/reporting/reporters/forgejo.py new file mode 100644 index 000000000..76a706320 --- /dev/null +++ b/packit_service/worker/reporting/reporters/forgejo.py @@ -0,0 +1,46 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +import logging +from typing import Optional + +from ogr.abstract import CommitStatus +from ogr.exceptions import ForgejoAPIException + +from packit_service.worker.reporting import BaseCommitStatus +from packit_service.worker.reporting.reporters.base import StatusReporter + +logger = logging.getLogger(__name__) + + +class StatusReporterForgejo(StatusReporter): + @staticmethod + def get_commit_status(state: BaseCommitStatus): + mapped_state = StatusReporter.get_commit_status(state) + + if mapped_state == CommitStatus.error: + mapped_state = CommitStatus.failure + return mapped_state + + def set_status( + self, + state: BaseCommitStatus, + description: str, + check_name: str, + url: str = "", + links_to_external_services: Optional[dict[str, str]] = None, + markdown_content: Optional[str] = None, + target_branch: Optional[str] = None, + ): + state_to_set = self.get_commit_status(state) + logger.debug(f"Setting Forgejo status '{state_to_set.name}'") + + try: + self.project_with_commit.set_commit_status( + self.commit_sha, state_to_set, url, description, check_name, trim=True + ) + + except ForgejoAPIException as e: + logger.debug(f"Failed to set status: {e}") + + self._add_commit_comment_with_status(state, description, check_name, url) From c975387d655c0e6a63ef8bf76c820853bb90a8e7 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Tue, 2 Sep 2025 13:07:10 +0200 Subject: [PATCH 2/4] test(data): add Forgejo webhooks for tests --- .../data/webhooks/forgejo/issue_comment.json | 221 +++++++ tests/data/webhooks/forgejo/pr_comment.json | 581 ++++++++++++++++++ tests/data/webhooks/forgejo/pr_opened.json | 484 +++++++++++++++ .../webhooks/forgejo/push_new_branch.json | 197 ++++++ .../forgejo/push_with_many_commits.json | 277 +++++++++ .../forgejo/push_with_one_commit.json | 197 ++++++ tests/data/webhooks/forgejo/tag_push.json | 176 ++++++ 7 files changed, 2133 insertions(+) create mode 100644 tests/data/webhooks/forgejo/issue_comment.json create mode 100644 tests/data/webhooks/forgejo/pr_comment.json create mode 100644 tests/data/webhooks/forgejo/pr_opened.json create mode 100644 tests/data/webhooks/forgejo/push_new_branch.json create mode 100644 tests/data/webhooks/forgejo/push_with_many_commits.json create mode 100644 tests/data/webhooks/forgejo/push_with_one_commit.json create mode 100644 tests/data/webhooks/forgejo/tag_push.json diff --git a/tests/data/webhooks/forgejo/issue_comment.json b/tests/data/webhooks/forgejo/issue_comment.json new file mode 100644 index 000000000..f3c945c18 --- /dev/null +++ b/tests/data/webhooks/forgejo/issue_comment.json @@ -0,0 +1,221 @@ +{ + "action": "created", + "issue": { + "id": 1118, + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/issues/1", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1", + "number": 1, + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@example.com", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-18T17:54:40Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "original_author": "", + "original_author_id": 0, + "title": "new issue", + "body": "", + "ref": "", + "assets": [], + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "state": "open", + "is_locked": false, + "comments": 0, + "created_at": "2025-08-19T08:34:42Z", + "updated_at": "2025-08-19T08:36:14Z", + "closed_at": null, + "due_date": null, + "pull_request": null, + "repository": { + "id": 681, + "name": "test-repo-to-generate-events", + "owner": "packit", + "full_name": "packit/test-repo-to-generate-events" + }, + "pin_order": 0 + }, + "comment": { + "id": 3144, + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1#issuecomment-3144", + "pull_request_url": "", + "issue_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1", + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "original_author": "", + "original_author_id": 0, + "body": "issue comment", + "assets": [], + "created_at": "2025-08-19T08:36:14Z", + "updated_at": "2025-08-19T08:36:14Z" + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 27, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:33:58Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "is_pull": false +} diff --git a/tests/data/webhooks/forgejo/pr_comment.json b/tests/data/webhooks/forgejo/pr_comment.json new file mode 100644 index 000000000..1afcb99d9 --- /dev/null +++ b/tests/data/webhooks/forgejo/pr_comment.json @@ -0,0 +1,581 @@ +{ + "action": "created", + "issue": { + "id": 1119, + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/issues/2", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "number": 2, + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@example.com", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-18T17:54:40Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "original_author": "", + "original_author_id": 0, + "title": "feature-branch-to-be-merged-via-pr", + "body": "", + "ref": "", + "assets": [], + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "state": "open", + "is_locked": false, + "comments": 0, + "created_at": "2025-08-19T08:44:27Z", + "updated_at": "2025-08-19T08:45:58Z", + "closed_at": null, + "due_date": null, + "pull_request": { + "merged": false, + "merged_at": null, + "draft": false, + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2" + }, + "repository": { + "id": 681, + "name": "test-repo-to-generate-events", + "owner": "packit", + "full_name": "packit/test-repo-to-generate-events" + }, + "pin_order": 0 + }, + "pull_request": { + "id": 505, + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "number": 2, + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@example.com", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-18T17:54:40Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "title": "feature-branch-to-be-merged-via-pr", + "body": "", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": null, + "requested_reviewers_teams": null, + "state": "open", + "draft": false, + "is_locked": false, + "comments": 0, + "review_comments": 0, + "additions": 0, + "deletions": 0, + "changed_files": 0, + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "diff_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.diff", + "patch_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.patch", + "mergeable": true, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "repo_id": 681, + "repo": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 1, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + } + }, + "head": { + "label": "feature-branch-to-be-merged-via-pr", + "ref": "feature-branch-to-be-merged-via-pr", + "sha": "37182f59ccaaa21584e7b580442fd33b60fe3f80", + "repo_id": 682, + "repo": { + "id": 682, + "owner": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "name": "test-repo-to-generate-events", + "full_name": "mfocko/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": true, + "template": false, + "parent": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 1, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/mfocko/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:59:49Z", + "updated_at": "2025-08-19T08:43:17Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "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": true, + "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": null + } + }, + "merge_base": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "due_date": null, + "created_at": "2025-08-19T08:44:27Z", + "updated_at": "2025-08-19T08:45:58Z", + "closed_at": null, + "pin_order": 0 + }, + "comment": { + "id": 3146, + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2#issuecomment-3146", + "pull_request_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "issue_url": "", + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "original_author": "", + "original_author_id": 0, + "body": "PR comment", + "assets": [], + "created_at": "2025-08-19T08:45:58Z", + "updated_at": "2025-08-19T08:45:58Z" + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 1, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "is_pull": true +} diff --git a/tests/data/webhooks/forgejo/pr_opened.json b/tests/data/webhooks/forgejo/pr_opened.json new file mode 100644 index 000000000..32f6304f2 --- /dev/null +++ b/tests/data/webhooks/forgejo/pr_opened.json @@ -0,0 +1,484 @@ +{ + "action": "opened", + "number": 2, + "pull_request": { + "id": 505, + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "number": 2, + "user": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@example.com", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "en-US", + "is_admin": false, + "last_login": "2025-08-18T17:54:40Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "title": "feature-branch-to-be-merged-via-pr", + "body": "", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": null, + "requested_reviewers_teams": null, + "state": "open", + "draft": false, + "is_locked": false, + "comments": 0, + "review_comments": 0, + "additions": 0, + "deletions": 0, + "changed_files": 0, + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", + "diff_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.diff", + "patch_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.patch", + "mergeable": true, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "repo_id": 681, + "repo": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + } + }, + "head": { + "label": "feature-branch-to-be-merged-via-pr", + "ref": "feature-branch-to-be-merged-via-pr", + "sha": "37182f59ccaaa21584e7b580442fd33b60fe3f80", + "repo_id": 682, + "repo": { + "id": 682, + "owner": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "name": "test-repo-to-generate-events", + "full_name": "mfocko/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": true, + "template": false, + "parent": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 1, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/mfocko/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 1, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:59:49Z", + "updated_at": "2025-08-19T08:43:17Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "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": true, + "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": null + } + }, + "merge_base": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "due_date": null, + "created_at": "2025-08-19T08:44:27Z", + "updated_at": "2025-08-19T08:44:34Z", + "closed_at": null, + "pin_order": 0 + }, + "requested_reviewer": null, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 28, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:37:25Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "commit_id": "", + "review": null +} diff --git a/tests/data/webhooks/forgejo/push_new_branch.json b/tests/data/webhooks/forgejo/push_new_branch.json new file mode 100644 index 000000000..43c223a3e --- /dev/null +++ b/tests/data/webhooks/forgejo/push_new_branch.json @@ -0,0 +1,197 @@ +{ + "ref": "refs/heads/new-branch", + "before": "0000000000000000000000000000000000000000", + "after": "24f660b69e4608f63ddd55d5c5b459f348e5f272", + "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/fa9bbf46c6ae89b755716683814b03b6a2c82263...24f660b69e4608f63ddd55d5c5b459f348e5f272", + "commits": [ + { + "id": "24f660b69e4608f63ddd55d5c5b459f348e5f272", + "message": "huh\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/24f660b69e4608f63ddd55d5c5b459f348e5f272", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:36:37+02:00", + "added": [], + "removed": [], + "modified": [] + } + ], + "total_commits": 1, + "head_commit": { + "id": "24f660b69e4608f63ddd55d5c5b459f348e5f272", + "message": "huh\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/24f660b69e4608f63ddd55d5c5b459f348e5f272", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:36:37+02:00", + "added": [], + "removed": [], + "modified": [] + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 27, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 1, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:33:58Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "pusher": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + } +} diff --git a/tests/data/webhooks/forgejo/push_with_many_commits.json b/tests/data/webhooks/forgejo/push_with_many_commits.json new file mode 100644 index 000000000..02d8f0514 --- /dev/null +++ b/tests/data/webhooks/forgejo/push_with_many_commits.json @@ -0,0 +1,277 @@ +{ + "ref": "refs/heads/main", + "before": "c85008a0b44a60370e48a45a9f9d39da5b472e11", + "after": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/c85008a0b44a60370e48a45a9f9d39da5b472e11...fa9bbf46c6ae89b755716683814b03b6a2c82263", + "commits": [ + { + "id": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "message": "seventh of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/fa9bbf46c6ae89b755716683814b03b6a2c82263", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:23+02:00", + "added": [], + "removed": [], + "modified": [] + }, + { + "id": "da5184eb5c8a16247ce3025af1b72da8086c1337", + "message": "sixth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/da5184eb5c8a16247ce3025af1b72da8086c1337", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:19+02:00", + "added": [], + "removed": [], + "modified": [] + }, + { + "id": "b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", + "message": "fifth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:15+02:00", + "added": [], + "removed": [], + "modified": [] + }, + { + "id": "8d6033f1165c66acf8a4e2d0dffaf3ab10182a93", + "message": "fourth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/8d6033f1165c66acf8a4e2d0dffaf3ab10182a93", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:10+02:00", + "added": [], + "removed": [], + "modified": [] + }, + { + "id": "28c86b1224488c6fbf2b8018ebdee9b7251e804a", + "message": "third of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/28c86b1224488c6fbf2b8018ebdee9b7251e804a", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:05+02:00", + "added": [], + "removed": [], + "modified": [] + } + ], + "total_commits": 7, + "head_commit": { + "id": "fa9bbf46c6ae89b755716683814b03b6a2c82263", + "message": "seventh of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/fa9bbf46c6ae89b755716683814b03b6a2c82263", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:23+02:00", + "added": [], + "removed": [], + "modified": [] + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 23, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:29:32Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "pusher": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + } +} diff --git a/tests/data/webhooks/forgejo/push_with_one_commit.json b/tests/data/webhooks/forgejo/push_with_one_commit.json new file mode 100644 index 000000000..93aed4420 --- /dev/null +++ b/tests/data/webhooks/forgejo/push_with_one_commit.json @@ -0,0 +1,197 @@ +{ + "ref": "refs/heads/main", + "before": "b5827a36fbab61567da4376f7494a0e519d38a6e", + "after": "c85008a0b44a60370e48a45a9f9d39da5b472e11", + "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/b5827a36fbab61567da4376f7494a0e519d38a6e...c85008a0b44a60370e48a45a9f9d39da5b472e11", + "commits": [ + { + "id": "c85008a0b44a60370e48a45a9f9d39da5b472e11", + "message": "pushing one empty commit\n\nSigned-off-by: Matej Focko \u003cme@mfocko.xyz\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/c85008a0b44a60370e48a45a9f9d39da5b472e11", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:28:44+02:00", + "added": [], + "removed": [], + "modified": [] + } + ], + "total_commits": 1, + "head_commit": { + "id": "c85008a0b44a60370e48a45a9f9d39da5b472e11", + "message": "pushing one empty commit\n\nSigned-off-by: Matej Focko \u003cme@mfocko.xyz\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/c85008a0b44a60370e48a45a9f9d39da5b472e11", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:28:44+02:00", + "added": [], + "removed": [], + "modified": [] + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 23, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-18T17:59:07Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "pusher": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + } +} diff --git a/tests/data/webhooks/forgejo/tag_push.json b/tests/data/webhooks/forgejo/tag_push.json new file mode 100644 index 000000000..b73447e9b --- /dev/null +++ b/tests/data/webhooks/forgejo/tag_push.json @@ -0,0 +1,176 @@ +{ + "ref": "refs/tags/fifth", + "before": "0000000000000000000000000000000000000000", + "after": "9abc2644c3b9828db4bbe30c795b140c6c55089f", + "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/0000000000000000000000000000000000000000...9abc2644c3b9828db4bbe30c795b140c6c55089f", + "commits": [], + "total_commits": 0, + "head_commit": { + "id": "b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", + "message": "fifth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", + "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", + "author": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "committer": { + "name": "Matej Focko", + "email": "mf@example.com", + "username": "" + }, + "verification": null, + "timestamp": "2025-08-19T10:31:15+02:00", + "added": [], + "removed": [], + "modified": [] + }, + "repository": { + "id": 681, + "owner": { + "id": 450, + "login": "packit", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "", + "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", + "html_url": "https://v10.next.forgejo.org/packit", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-01-29T09:25:44Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "packit" + }, + "name": "test-repo-to-generate-events", + "full_name": "packit/test-repo-to-generate-events", + "description": "", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 27, + "language": "", + "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", + "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", + "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", + "link": "", + "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", + "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 1, + "watchers_count": 3, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-08-18T17:58:42Z", + "updated_at": "2025-08-19T08:32:16Z", + "archived_at": "1970-01-01T00:00:00Z", + "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": "main", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": true, + "allow_rebase": true, + "allow_rebase_explicit": true, + "allow_squash_merge": true, + "allow_fast_forward_only_merge": true, + "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": null + }, + "pusher": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + }, + "sender": { + "id": 601, + "login": "mfocko", + "login_name": "", + "source_id": 0, + "full_name": "", + "email": "mfocko@noreply.v10.next.forgejo.org", + "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", + "html_url": "https://v10.next.forgejo.org/mfocko", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-02-12T13:52:32Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "mfocko" + } +} From 71820656a5698d05324038002a5a2164e62d7fd7 Mon Sep 17 00:00:00 2001 From: mynk8 Date: Wed, 24 Sep 2025 00:21:00 +0530 Subject: [PATCH 3/4] include unit tests for forgejo event; fixes Update packit_service/worker/reporting/reporters/base.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Update packit_service/service/api/webhooks.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Update packit_service/worker/parser.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Update packit_service/events/forgejo/pr.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> pre-commit and mypy fixes test(data): add Forgejo webhooks for tests include unit tests for forgejo event; fixes add check for prioritising Forgejo before parsing events; fixes pre-commit remove redundant entries in parser list; fix bug Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> implement validate_token for ForgejoWebhooks; correct the pr.Action impl for Forgejo; fix a problem in parser that could have caused keynotfound errors. implement validate_token for ForgejoWebhooks; correct the pr.Action impl for Forgejo; fix a problem in parser that could have caused keynotfound errors. Implement Forgejo event handling in Packit Service. --- packit_service/events/__init__.py | 1 + packit_service/events/abstract/comment.py | 3 +- packit_service/events/forgejo/__init__.py | 2 +- packit_service/events/forgejo/issue.py | 40 +-- packit_service/events/forgejo/pr.py | 15 +- packit_service/service/api/webhooks.py | 50 +-- packit_service/worker/parser.py | 121 +++++-- tests/conftest.py | 3 +- tests/unit/events/test_forgejo.py | 389 ++++++++++++++++++++++ tests/unit/test_webhooks.py | 42 +++ 10 files changed, 571 insertions(+), 95 deletions(-) create mode 100644 tests/unit/events/test_forgejo.py diff --git a/packit_service/events/__init__.py b/packit_service/events/__init__.py index 472ac9c94..8b275a005 100644 --- a/packit_service/events/__init__.py +++ b/packit_service/events/__init__.py @@ -21,6 +21,7 @@ __all__ = [ abstract.__name__, anitya.__name__, + forgejo.__name__, github.__name__, gitlab.__name__, forgejo.__name__, diff --git a/packit_service/events/abstract/comment.py b/packit_service/events/abstract/comment.py index 943dba20b..e3c6bd872 100644 --- a/packit_service/events/abstract/comment.py +++ b/packit_service/events/abstract/comment.py @@ -152,6 +152,7 @@ def __init__( tag_name: str = "", comment_object: Optional[Comment] = None, dist_git_project_url=None, + commit_sha: Optional[str] = None, ) -> None: super().__init__( project_url=project_url, @@ -168,7 +169,7 @@ def __init__( # Lazy properties self._tag_name = tag_name - self._commit_sha: Optional[str] = None + self._commit_sha: Optional[str] = commit_sha self._comment_object = comment_object self._issue_object: Optional[OgrIssue] = None diff --git a/packit_service/events/forgejo/__init__.py b/packit_service/events/forgejo/__init__.py index 5197842b6..111d7935e 100644 --- a/packit_service/events/forgejo/__init__.py +++ b/packit_service/events/forgejo/__init__.py @@ -3,4 +3,4 @@ from . import abstract, issue, pr, push -__all__ = [abstract.__name__, push.__name__, issue.__name__, pr.__name__] +__all__ = [abstract.__name__, issue.__name__, pr.__name__, push.__name__] diff --git a/packit_service/events/forgejo/issue.py b/packit_service/events/forgejo/issue.py index 13415a896..d2b23fec8 100644 --- a/packit_service/events/forgejo/issue.py +++ b/packit_service/events/forgejo/issue.py @@ -1,8 +1,6 @@ # Copyright Contributors to the Packit project. # SPDX-License-Identifier: MIT -# SPDX-License-Identifier: MIT - from typing import Optional from ogr.abstract import Comment as OgrComment @@ -50,43 +48,7 @@ def __init__( def event_type(cls) -> str: return "forgejo.issue.Comment" - @property - def tag_name(self): - """ - For Forgejo issue comments, return the tag_name passed in constructor - without making API calls to avoid authentication issues. - """ - return self._tag_name - - @tag_name.setter - def tag_name(self, value: str) -> None: - self._tag_name = value - - @property - def commit_sha(self) -> Optional[str]: - """ - For Forgejo issue comments, return the commit_sha passed in constructor - without making API calls to avoid authentication issues. - """ - return self._commit_sha - - @commit_sha.setter - def commit_sha(self, value: Optional[str]) -> None: - self._commit_sha = value - def get_dict(self, default_dict: Optional[dict] = None) -> dict: - """ - Override get_dict to avoid accessing properties that make API calls. - """ - # Get the basic dict from CommentEvent, not from Issue to avoid tag_name access - from ..abstract.comment import CommentEvent - - result = CommentEvent.get_dict(self, default_dict=default_dict) - - # Add the specific fields we need without triggering API calls + result = super().get_dict() result["action"] = self.action.value - result["issue_id"] = self.issue_id - result["tag_name"] = self._tag_name # Use the private attribute directly - result["commit_sha"] = self._commit_sha # Use the private attribute directly - return result diff --git a/packit_service/events/forgejo/pr.py b/packit_service/events/forgejo/pr.py index a2138998b..a2a531eea 100644 --- a/packit_service/events/forgejo/pr.py +++ b/packit_service/events/forgejo/pr.py @@ -36,12 +36,10 @@ def __init__( self.base_ref = base_ref self.target_repo_namespace = target_repo_namespace self.target_repo_name = target_repo_name - self.commit_sha = commit_sha - self.commit_sha_before = commit_sha_before self.actor = actor self.identifier = str(pr_id) - self._pr_id = pr_id - self.git_ref = None # use pr_id for checkout + self.commit_sha = commit_sha + self.commit_sha_before = commit_sha_before self.body = body def get_dict(self, default_dict: Optional[dict] = None) -> dict: @@ -55,8 +53,8 @@ def event_type(cls) -> str: def get_base_project(self) -> GitProject: return self.project.service.get_project( - namespace=self.target_repo_namespace, - repo=self.target_repo_name, + namespace=self.base_repo_namespace, + repo=self.base_repo_name, ) @@ -94,7 +92,6 @@ def __init__( self.actor = actor self.identifier = str(pr_id) self.git_ref = None - self.pr_id = pr_id @classmethod def event_type(cls) -> str: @@ -116,6 +113,6 @@ def get_dict(self, default_dict: Optional[dict] = None) -> dict: def get_base_project(self) -> GitProject: return self.project.service.get_project( - namespace=self.target_repo_namespace, - repo=self.target_repo_name, + namespace=self.base_repo_namespace, + repo=self.base_repo_name, ) diff --git a/packit_service/service/api/webhooks.py b/packit_service/service/api/webhooks.py index 01fbc80a9..01057fe95 100644 --- a/packit_service/service/api/webhooks.py +++ b/packit_service/service/api/webhooks.py @@ -373,6 +373,9 @@ class ForgejoWebhook(Resource): @ns.response(HTTPStatus.UNAUTHORIZED.value, "X-Forgejo-Signature validation failed") @ns.expect(ping_payload_forgejo) def post(self): + """ + A webhook used by Packit-as-a-Service Forgejo hook. + """ msg = request.json if not msg: @@ -385,17 +388,17 @@ def post(self): logger.debug(f"/webhooks/forgejo received ping event: {msg['hook']}") forgejo_webhook_calls.labels(result="pong", process_id=os.getpid()).inc() return "Pong!", HTTPStatus.OK - # TODO - # try: - # self.validate_token() - # except ValidationFailed as exc: - # logger.info(f"/webhooks/forgejo {exc}") - # forgejo_webhook_calls.labels( - # result="invalid_signature", - # process_id=os.getpid(), - # ).inc() - # return str(exc), HTTPStatus.UNAUTHORIZED - # + + try: + self.validate_token() + except ValidationFailed as exc: + logger.info(f"/webhooks/forgejo {exc}") + forgejo_webhook_calls.labels( + result="invalid_signature", + process_id=os.getpid(), + ).inc() + return str(exc), HTTPStatus.UNAUTHORIZED + if not self.interested(msg): forgejo_webhook_calls.labels( result="not_interested", @@ -419,39 +422,44 @@ def validate_token(self): """ Validate the Forgejo webhook signature. The signature is a direct SHA256 HMAC hex digest of the raw request body - using the webhook secret as the key, in a similar fashion to Github. - + using the webhook secret as the key, in a similar fashion to GitHub. """ if "X-Forgejo-Signature" not in request.headers: + if config.validate_webhooks: + msg = "X-Forgejo-Signature not in request.headers" + logger.warning(msg) + raise ValidationFailed(msg) + + # don't validate signatures when testing locally logger.debug("Ain't validating signatures.") return - if not (webhook_secret := getenv("WEBHOOK_SECRET")): + if not (webhook_secret := config.webhook_secret): msg = "'webhook_secret' not specified in the config." logger.error(msg) raise ValidationFailed(msg) - # Get raw payload - payload = request.get_data() if not payload: msg = "No payload received." logger.error(msg) raise ValidationFailed(msg) + # Calculate payload signature using HMAC-SHA256 data_hmac = hmac.new(webhook_secret.encode(), msg=payload, digestmod=sha256) payload_signature = data_hmac.hexdigest() - header_sig = request.headers["X-Forgejo-Signature"] + header_signature = request.headers["X-Forgejo-Signature"] - if header_sig != payload_signature: + if not hmac.compare_digest(header_signature, payload_signature): msg = "Payload signature validation failed." - logger.warning(msg) logger.debug( - f"X-Forgejo-Signature: {header_sig!r} != computed: {payload_signature}", + f"X-Forgejo-Signature: {header_signature!r} != computed: {payload_signature}", ) raise ValidationFailed(msg) + logger.debug("Payload signature is OK.") + @staticmethod def interested(msg): """ @@ -475,7 +483,7 @@ def interested(msg): "release": action == "published", "issues": action in {"opened", "edited", "closed", "reopened"}, "issue_comment": action in {"created", "edited"}, - "pull_request": action in {"opened", "edited", "closed", "reopened", "synchronize"}, + "pull_request": action in {"opened", "reopened", "synchronize"}, } _interested = interests.get(event or "", False) diff --git a/packit_service/worker/parser.py b/packit_service/worker/parser.py index f5f68c3b0..d37098628 100644 --- a/packit_service/worker/parser.py +++ b/packit_service/worker/parser.py @@ -105,6 +105,48 @@ class Parser: we need to have method inside the `Parser` class to create objects defined in `event.py`. """ + @staticmethod + def is_forgejo_event(event: dict) -> bool: + """ + Detect if an event is from Forgejo based on platform-specific fields. + Forgejo events have additional fields that GitHub events don't have. + """ + + # Check for Forgejo-specific fields in user objects + def has_forgejo_user_fields(user_obj): + if not isinstance(user_obj, dict): + return False + forgejo_fields = { + "login_name", + "source_id", + "full_name", + "is_admin", + "last_login", + "created", + "restricted", + "active", + "prohibit_login", + "location", + "pronouns", + "website", + "description", + "visibility", + "followers_count", + "following_count", + "starred_repos_count", + "username", + } + return any(field in user_obj for field in forgejo_fields) + + return ( + has_forgejo_user_fields(event.get("user")) + or has_forgejo_user_fields(nested_get(event, "pull_request", "user")) + or has_forgejo_user_fields(nested_get(event, "comment", "user")) + or has_forgejo_user_fields(nested_get(event, "issue", "user")) + or has_forgejo_user_fields(event.get("pusher")) + or has_forgejo_user_fields(event.get("sender")) + ) + @staticmethod def parse_event( event: dict, @@ -130,6 +172,10 @@ def parse_event( gitlab.push.Commit, gitlab.push.Tag, gitlab.release.Release, + forgejo.pr.Comment, + forgejo.pr.Action, + forgejo.push.Commit, + forgejo.issue.Comment, koji.result.Build, koji.tag.Build, koji.result.Task, @@ -160,6 +206,23 @@ def parse_event( logger.warning("No event to process!") return None + # Check if this is a Forgejo event and prioritize Forgejo parsers + # We have to prioritize Forgejo events as they are similar in structure + # to github event payloads and hence can accidentally be parsed as + # Github objects. + is_forgejo = Parser.is_forgejo_event(event) + + if is_forgejo: + forgejo_parsers = ( + Parser.parse_forgejo_push_event, + Parser.parse_forgejo_pr_event, + Parser.parse_forgejo_comment_event, + ) + for parser in forgejo_parsers: + forgejo_response = parser(event) + if forgejo_response: + return forgejo_response + for response in ( parser(event) for parser in ( @@ -649,7 +712,6 @@ def parse_issue_comment_event(event) -> Optional[github.issue.Comment]: # but it's needed when called from parse_event(). if nested_get(event, "issue", "pull_request"): return None - issue_id = nested_get(event, "issue", "number") action = event.get("action") if action != "created" or not issue_id: @@ -1930,7 +1992,7 @@ def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]: raw_ref = event.get("ref") before = event.get("before") after = event.get("after") - pusher = nested_get(event, "pusher", "login") or nested_get(event, "pusher", "name") + pusher = nested_get(event, "pusher", "login") if not (raw_ref and after and before and pusher): return None @@ -1942,13 +2004,12 @@ def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]: return None # Number of commits introduced by this push - commits = event.get("commits") or [] - num_commits = len(commits) + num_commits = event.get("total_commits") # Strip the ref prefix to get the branch/tag name _, ref_type, ref_name = raw_ref.split("/", 2) - if ref_type != "heads": - logger.debug(f"Forgejo push event ignored – not a branch push ('{raw_ref}')") + if ref_type not in ("heads", "tags"): + logger.debug(f"Forgejo push event ignored – not a branch or tag push ('{raw_ref}')") return None logger.info( @@ -1980,7 +2041,6 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: Parse Forgejo PR action events, only triggering for relevant actions. Supported actions: 'opened', 'reopened', 'synchronize'. Skips others like 'closed'. - """ action_str = event.get("action") # Only trigger for these actions @@ -1995,7 +2055,7 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: return None pr_id = pr.get("number") - actor = event.get("sender", {}).get("login") + actor = nested_get(event, "pull_request", "user", "login") repo = event.get("repository", {}) base = pr.get("base") head = pr.get("head") @@ -2003,11 +2063,11 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: # Check all required nested fields try: - base_repo_namespace = base["repo"]["owner"]["login"] - base_repo_name = base["repo"]["name"] - base_ref = base["ref"] - target_repo_namespace = head["repo"]["owner"]["login"] - target_repo_name = head["repo"]["name"] + target_repo_namespace = base["repo"]["owner"]["login"] + target_repo_name = base["repo"]["name"] + base_ref = head["sha"] + base_repo_namespace = head["repo"]["owner"]["login"] + base_repo_name = head["repo"]["name"] project_url = repo["html_url"] commit_sha = head["sha"] except (TypeError, KeyError): @@ -2024,7 +2084,7 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: target_repo_name=target_repo_name, project_url=project_url, commit_sha=commit_sha, - commit_sha_before=event.get("before", ""), # Optional, might be empty + commit_sha_before=event.get("before", ""), actor=actor, body=body, ) @@ -2043,8 +2103,7 @@ def parse_forgejo_comment_event( # Only treat as PR if 'pull_request' is present and not None issue_dict = event.get("issue", {}) - is_pr = "pull_request" in issue_dict and issue_dict["pull_request"] is not None - + is_pr = issue_dict.get("pull_request") is not None comment = nested_get(event, "comment", "body") comment_id = nested_get(event, "comment", "id") logger.info( @@ -2052,11 +2111,22 @@ def parse_forgejo_comment_event( f"comment: {comment!r} id#{comment_id} {action!r} event." ) - base_repo_namespace = nested_get(event, "issue", "user", "login") - base_repo_name = nested_get(event, "repository", "name") - user_login = nested_get(event, "comment", "user", "login") - target_repo_namespace = nested_get(event, "repository", "owner", "login") + + if is_pr: + # For PR comments, extract repo info from pull_request section + base_repo_namespace = nested_get( + event, "pull_request", "head", "repo", "owner", "login" + ) + base_repo_name = nested_get(event, "pull_request", "head", "repo", "name") + target_repo_namespace = nested_get( + event, "pull_request", "base", "repo", "owner", "login" + ) + else: + # For issue comments, extract from repository section + base_repo_namespace = nested_get(event, "repository", "owner", "login") + base_repo_name = nested_get(event, "repository", "name") + target_repo_namespace = nested_get(event, "repository", "owner", "login") target_repo_name = nested_get(event, "repository", "name") https_url = nested_get(event, "repository", "html_url") @@ -2072,10 +2142,12 @@ def parse_forgejo_comment_event( return None if is_pr: + base_ref = nested_get(event, "pull_request", "head", "ref") + commit_sha = nested_get(event, "pull_request", "head", "sha") return forgejo.pr.Comment( action=PullRequestCommentAction[action], pr_id=issue_id, - base_ref="", + base_ref=base_ref, base_repo_namespace=base_repo_namespace, base_repo_name=base_repo_name, target_repo_namespace=target_repo_namespace, @@ -2084,8 +2156,11 @@ def parse_forgejo_comment_event( actor=user_login, comment=comment, comment_id=comment_id, - commit_sha=None, + commit_sha=commit_sha, ) + # For issue comments, get the default branch + default_branch = nested_get(event, "repository", "default_branch") or "main" + return forgejo.issue.Comment( action=IssueCommentAction[action], issue_id=issue_id, @@ -2097,7 +2172,7 @@ def parse_forgejo_comment_event( comment=comment, comment_id=comment_id, tag_name="", - base_ref="", + base_ref=default_branch, dist_git_project_url=None, ) diff --git a/tests/conftest.py b/tests/conftest.py index f1a8fe891..54a6351bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,7 @@ import pytest from deepdiff import DeepDiff from flexmock import flexmock -from ogr import GithubService, GitlabService, PagureService +from ogr import ForgejoService, GithubService, GitlabService, PagureService from packit.config import JobConfig, JobConfigTriggerType, PackageConfig from packit.config.common_package_config import Deployment @@ -43,6 +43,7 @@ def global_service_config(): GitlabService(token="token"), PagureService(instance_url="https://src.fedoraproject.org", token="token"), PagureService(instance_url="https://git.stg.centos.org", token="6789"), + ForgejoService(instance_url="https://codeberg.org", token="token"), } service_config.server_name = "localhost" service_config.github_requests_log_path = "/path" diff --git a/tests/unit/events/test_forgejo.py b/tests/unit/events/test_forgejo.py new file mode 100644 index 000000000..97973443b --- /dev/null +++ b/tests/unit/events/test_forgejo.py @@ -0,0 +1,389 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +import json + +import pytest +from flexmock import flexmock +from ogr.services.forgejo import ForgejoProject + +from packit_service.config import ServiceConfig +from packit_service.events.enums import ( + IssueCommentAction, + PullRequestAction, + PullRequestCommentAction, +) +from packit_service.events.forgejo import issue, pr, push +from packit_service.package_config_getter import PackageConfigGetter +from packit_service.worker.parser import Parser +from tests.spellbook import DATA_DIR + +PATH_TO_FORGEJO_WEBHOOKS = DATA_DIR / "webhooks" / "forgejo" + + +@pytest.fixture() +def pull_request_opened(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "pr_opened.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def pull_request_comment(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "pr_comment.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def issue_comment(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "issue_comment.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def push_new_branch(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "push_new_branch.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def tag_push(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "tag_push.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def push_with_many_commit(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "push_with_many_commits.json") as outfile: + return json.load(outfile) + + +@pytest.fixture() +def push_with_one_commit(): + with open(PATH_TO_FORGEJO_WEBHOOKS / "push_with_one_commit.json") as outfile: + return json.load(outfile) + + +def test_parse_forgejo_tag_push(tag_push): + mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(tag_push) + + assert isinstance(event_object, push.Commit) + assert event_object.repo_namespace == "packit" + assert event_object.repo_name == "test-repo-to-generate-events" + assert event_object.commit_sha == "9abc2644c3b9828db4bbe30c795b140c6c55089f" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.git_ref == "fifth" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert not event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=None, + reference="9abc2644c3b9828db4bbe30c795b140c6c55089f", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_pull_request(pull_request_opened): + mock_service = flexmock(get_project=lambda namespace, repo: flexmock()) + mock_project = flexmock( + full_repo_name="packit/test-repo-to-generate-events", service=mock_service + ) + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(pull_request_opened) + + assert isinstance(event_object, pr.Action) + assert event_object.action == PullRequestAction.opened + assert event_object.pr_id == 2 + assert event_object.base_repo_namespace == "mfocko" + assert event_object.base_repo_name == "test-repo-to-generate-events" + assert event_object.base_ref == "37182f59ccaaa21584e7b580442fd33b60fe3f80" + assert event_object.target_repo_namespace == "packit" + assert event_object.target_repo_name == "test-repo-to-generate-events" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.commit_sha == "37182f59ccaaa21584e7b580442fd33b60fe3f80" + assert event_object.actor == "mfocko" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=2, + reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_pull_request_comment(pull_request_comment): + mock_project = flexmock( + full_repo_name="packit/test-repo-to-generate-events", + get_pr=lambda pr_id: flexmock(head_commit="37182f59ccaaa21584e7b580442fd33b60fe3f80"), + service=flexmock(get_project=lambda namespace, repo: flexmock()), + ) + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(pull_request_comment) + + assert isinstance(event_object, pr.Comment) + assert event_object.action == PullRequestCommentAction.created + assert event_object.pr_id == 2 + assert event_object.base_repo_namespace == "mfocko" + assert event_object.base_repo_name == "test-repo-to-generate-events" + assert event_object.target_repo_namespace == "packit" + assert event_object.target_repo_name == "test-repo-to-generate-events" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.actor == "mfocko" + assert event_object.comment == "PR comment" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=2, + reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_issue_comment(issue_comment): + mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(issue_comment) + + assert isinstance(event_object, issue.Comment) + assert event_object.action == IssueCommentAction.created + assert event_object.issue_id == 1 + assert event_object.repo_namespace == "packit" + assert event_object.repo_name == "test-repo-to-generate-events" + assert event_object.target_repo == "packit/test-repo-to-generate-events" + assert event_object.base_ref == "main" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.actor == "mfocko" + assert event_object.comment == "issue comment" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert not event_object.base_project + + flexmock(event_object.project).should_receive("get_releases").and_return([]) + flexmock(ForgejoProject).should_receive("get_sha_from_tag").never() + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=None, + reference=None, + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + assert event_object.commit_sha is None + assert event_object.tag_name == "" + + +def test_parse_forgejo_push_many_commits(push_with_many_commit): + mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(push_with_many_commit) + + assert isinstance(event_object, push.Commit) + assert event_object.repo_namespace == "packit" + assert event_object.repo_name == "test-repo-to-generate-events" + assert event_object.commit_sha == "fa9bbf46c6ae89b755716683814b03b6a2c82263" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.git_ref == "main" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert not event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=None, + reference="fa9bbf46c6ae89b755716683814b03b6a2c82263", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_forgejo_push_new_branch(push_new_branch): + mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(push_new_branch) + + assert isinstance(event_object, push.Commit) + assert event_object.repo_namespace == "packit" + assert event_object.repo_name == "test-repo-to-generate-events" + assert event_object.commit_sha == "24f660b69e4608f63ddd55d5c5b459f348e5f272" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.git_ref == "new-branch" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert not event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=None, + reference="24f660b69e4608f63ddd55d5c5b459f348e5f272", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_forgejo_push_one_commit(push_with_one_commit): + mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + event_object = Parser.parse_event(push_with_one_commit) + + assert isinstance(event_object, push.Commit) + assert event_object.repo_namespace == "packit" + assert event_object.repo_name == "test-repo-to-generate-events" + assert event_object.commit_sha == "c85008a0b44a60370e48a45a9f9d39da5b472e11" + assert ( + event_object.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + assert event_object.git_ref == "main" + + assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" + assert not event_object.base_project + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=None, + reference="c85008a0b44a60370e48a45a9f9d39da5b472e11", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + assert event_object.packages_config + + +def test_parse_forgejo_pr_vs_issue_comment_discrimination(pull_request_comment, issue_comment): + """ + Test that the parser correctly discriminates between PR comments and issue comments. + In Forgejo, PRs are treated as special issues, so the parser needs to distinguish + between them based on the webhook payload structure. + """ + mock_project = flexmock( + full_repo_name="packit/test-repo-to-generate-events", + get_pr=lambda pr_id: flexmock(head_commit="37182f59ccaaa21584e7b580442fd33b60fe3f80"), + get_releases=list, + service=flexmock(get_project=lambda namespace, repo: flexmock()), + ) + flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) + + # Test PR comment parsing + pr_comment_event = Parser.parse_event(pull_request_comment) + + assert isinstance(pr_comment_event, pr.Comment) + assert pr_comment_event.action == PullRequestCommentAction.created + assert pr_comment_event.pr_id == 2 + assert pr_comment_event.comment == "PR comment" + assert pr_comment_event.actor == "mfocko" + + # Test issue comment parsing + issue_comment_event = Parser.parse_event(issue_comment) + + assert isinstance(issue_comment_event, issue.Comment) + assert issue_comment_event.action == IssueCommentAction.created + assert issue_comment_event.issue_id == 1 + assert issue_comment_event.comment == "issue comment" + assert issue_comment_event.actor == "mfocko" + + assert pr_comment_event.event_type() == "forgejo.pr.Comment" + assert issue_comment_event.event_type() == "forgejo.issue.Comment" + + assert pr_comment_event.project_url == issue_comment_event.project_url + assert ( + pr_comment_event.project_url + == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" + ) + + flexmock(ForgejoProject).should_receive("get_sha_from_tag").never() + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=pr_comment_event.base_project, + project=pr_comment_event.project, + pr_id=2, + reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo", + ).with_args( + base_project=issue_comment_event.base_project, + project=issue_comment_event.project, + pr_id=None, + reference=None, + fail_when_missing=False, + ).and_return( + flexmock(get_package_config_views=dict), + ).once() + + assert pr_comment_event.packages_config + assert issue_comment_event.packages_config diff --git a/tests/unit/test_webhooks.py b/tests/unit/test_webhooks.py index b8372eead..b503aea1c 100644 --- a/tests/unit/test_webhooks.py +++ b/tests/unit/test_webhooks.py @@ -246,3 +246,45 @@ def test_interested(mock_config, headers, payload, interested): headers=headers, ): assert webhooks.GithubWebhook.interested() == interested + + +@pytest.mark.parametrize( + "headers, is_good", + [ + ( + { + "X-Forgejo-Signature": ( + "7884c9fc5f880c17920b2066e85aae7b57489505a16aa9b56806a924df78f846" + ), + }, + True, + ), + ( + { + "X-Forgejo-Signature": ( + "feedfacecafebeef920b2066e85aae7b57489505a16aa9b56806a924df78f666" + ), + }, + False, + ), + ({}, False), + ], +) +def test_validate_forgejo_token(mock_config, headers, is_good): + flexmock(ServiceConfig).should_receive("get_service_config").and_return( + flexmock(validate_webhooks=True), + ) + from packit_service.service.api import webhooks + + webhooks.config = mock_config + + with Flask(__name__).test_request_context(): + payload = {"zen": "Keep it logically awesome."} + + request._cached_data = request.data = dumps(payload).encode() + request.headers = headers + if not is_good: + with pytest.raises(ValidationFailed): + webhooks.ForgejoWebhook.validate_token(webhooks.ForgejoWebhook()) + else: + webhooks.ForgejoWebhook.validate_token(webhooks.ForgejoWebhook()) From e2278a36371d76c99ff3bd1be866456f395dc40f Mon Sep 17 00:00:00 2001 From: mynk8 Date: Mon, 1 Jun 2026 19:13:50 +0530 Subject: [PATCH 4/4] use fedora-messaging for forgejo events --- packit_service/service/api/webhooks.py | 148 ---- packit_service/worker/parser.py | 138 ++-- tests/data/fedmsg/forgejo_issue_comment.json | 655 ++++++++++++++++++ tests/data/fedmsg/forgejo_pr.json | 583 ++++++++++++++++ tests/data/fedmsg/forgejo_push.json | 241 +++++++ .../data/webhooks/forgejo/issue_comment.json | 221 ------ tests/data/webhooks/forgejo/pr_comment.json | 581 ---------------- tests/data/webhooks/forgejo/pr_opened.json | 484 ------------- .../webhooks/forgejo/push_new_branch.json | 197 ------ .../forgejo/push_with_many_commits.json | 277 -------- .../forgejo/push_with_one_commit.json | 197 ------ tests/data/webhooks/forgejo/tag_push.json | 176 ----- tests/unit/events/test_forgejo.py | 419 ++--------- 13 files changed, 1569 insertions(+), 2748 deletions(-) create mode 100644 tests/data/fedmsg/forgejo_issue_comment.json create mode 100644 tests/data/fedmsg/forgejo_pr.json create mode 100644 tests/data/fedmsg/forgejo_push.json delete mode 100644 tests/data/webhooks/forgejo/issue_comment.json delete mode 100644 tests/data/webhooks/forgejo/pr_comment.json delete mode 100644 tests/data/webhooks/forgejo/pr_opened.json delete mode 100644 tests/data/webhooks/forgejo/push_new_branch.json delete mode 100644 tests/data/webhooks/forgejo/push_with_many_commits.json delete mode 100644 tests/data/webhooks/forgejo/push_with_one_commit.json delete mode 100644 tests/data/webhooks/forgejo/tag_push.json diff --git a/packit_service/service/api/webhooks.py b/packit_service/service/api/webhooks.py index 01057fe95..048ae5c78 100644 --- a/packit_service/service/api/webhooks.py +++ b/packit_service/service/api/webhooks.py @@ -45,21 +45,7 @@ }, ) -ping_payload_forgejo = ns.model( - "Forgejo webhook ping", - { - "zen": fields.String(required=False), - "hook_id": fields.String(required=False), - "hook": fields.String(required=False), - }, -) -github_webhook_calls = Counter( - "github_webhook_calls", - "Number of times the GitHub webhook is called", - # process_id = label the metric with respective process ID, so we can aggregate - ["result", "process_id"], -) @ns.route("/github") @@ -355,138 +341,4 @@ def interested(): return _interested -forgejo_webhook_calls = Counter( - "forgejo_webhook_calls", - "Number of times the Forgejo webhook is called", - ["result", "process_id"], -) - - -@ns.route("/forgejo") -class ForgejoWebhook(Resource): - @ns.response(HTTPStatus.OK.value, "Webhook accepted, returning reply") - @ns.response( - HTTPStatus.ACCEPTED.value, - "Webhook accepted, request is being processed", - ) - @ns.response(HTTPStatus.BAD_REQUEST.value, "Bad request data") - @ns.response(HTTPStatus.UNAUTHORIZED.value, "X-Forgejo-Signature validation failed") - @ns.expect(ping_payload_forgejo) - def post(self): - """ - A webhook used by Packit-as-a-Service Forgejo hook. - """ - msg = request.json - - if not msg: - logger.debug("/webhooks/forgejo: no JSON data received.") - forgejo_webhook_calls.labels(result="no_data", process_id=os.getpid()).inc() - - return "No JSON data.", HTTPStatus.BAD_REQUEST - - if all([msg.get("zen"), msg.get("hook_id"), msg.get("hook")]): - logger.debug(f"/webhooks/forgejo received ping event: {msg['hook']}") - forgejo_webhook_calls.labels(result="pong", process_id=os.getpid()).inc() - return "Pong!", HTTPStatus.OK - - try: - self.validate_token() - except ValidationFailed as exc: - logger.info(f"/webhooks/forgejo {exc}") - forgejo_webhook_calls.labels( - result="invalid_signature", - process_id=os.getpid(), - ).inc() - return str(exc), HTTPStatus.UNAUTHORIZED - - if not self.interested(msg): - forgejo_webhook_calls.labels( - result="not_interested", - process_id=os.getpid(), - ).inc() - return "Thanks but we don't care about this event", HTTPStatus.ACCEPTED - - celery_app.send_task( - name=getenv("CELERY_MAIN_TASK_NAME") or CELERY_DEFAULT_MAIN_TASK_NAME, - kwargs={ - "event": msg, - "source": "forgejo", - "event_type": request.headers.get("X-Forgejo-Event"), - }, - ) - forgejo_webhook_calls.labels(result="accepted", process_id=os.getpid()).inc() - - return "Webhook accepted. We thank you, Forgejo.", HTTPStatus.ACCEPTED - - def validate_token(self): - """ - Validate the Forgejo webhook signature. - The signature is a direct SHA256 HMAC hex digest of the raw request body - using the webhook secret as the key, in a similar fashion to GitHub. - """ - if "X-Forgejo-Signature" not in request.headers: - if config.validate_webhooks: - msg = "X-Forgejo-Signature not in request.headers" - logger.warning(msg) - raise ValidationFailed(msg) - - # don't validate signatures when testing locally - logger.debug("Ain't validating signatures.") - return - - if not (webhook_secret := config.webhook_secret): - msg = "'webhook_secret' not specified in the config." - logger.error(msg) - raise ValidationFailed(msg) - - payload = request.get_data() - if not payload: - msg = "No payload received." - logger.error(msg) - raise ValidationFailed(msg) - - # Calculate payload signature using HMAC-SHA256 - data_hmac = hmac.new(webhook_secret.encode(), msg=payload, digestmod=sha256) - payload_signature = data_hmac.hexdigest() - header_signature = request.headers["X-Forgejo-Signature"] - if not hmac.compare_digest(header_signature, payload_signature): - msg = "Payload signature validation failed." - logger.warning(msg) - logger.debug( - f"X-Forgejo-Signature: {header_signature!r} != computed: {payload_signature}", - ) - raise ValidationFailed(msg) - - logger.debug("Payload signature is OK.") - - @staticmethod - def interested(msg): - """ - - Check whether we want to process this event. - - - Args: - msg: The webhook payload as a dictionary - - Returns: - bool: False if we are not interested in this kind of event - """ - event = request.headers.get("X-Forgejo-Event") - uuid = request.headers.get("X-Forgejo-Delivery") - action = msg.get("action") if msg else None - deleted = msg.get("deleted") if msg else None - - interests = { - "push": not deleted, - "release": action == "published", - "issues": action in {"opened", "edited", "closed", "reopened"}, - "issue_comment": action in {"created", "edited"}, - "pull_request": action in {"opened", "reopened", "synchronize"}, - } - - _interested = interests.get(event or "", False) - - logger.debug(f"{event} {uuid}{'' if _interested else ' (not interested)'}") - return _interested diff --git a/packit_service/worker/parser.py b/packit_service/worker/parser.py index af6660bbc..841b45131 100644 --- a/packit_service/worker/parser.py +++ b/packit_service/worker/parser.py @@ -105,47 +105,6 @@ class Parser: we need to have method inside the `Parser` class to create objects defined in `event.py`. """ - @staticmethod - def is_forgejo_event(event: dict) -> bool: - """ - Detect if an event is from Forgejo based on platform-specific fields. - Forgejo events have additional fields that GitHub events don't have. - """ - - # Check for Forgejo-specific fields in user objects - def has_forgejo_user_fields(user_obj): - if not isinstance(user_obj, dict): - return False - forgejo_fields = { - "login_name", - "source_id", - "full_name", - "is_admin", - "last_login", - "created", - "restricted", - "active", - "prohibit_login", - "location", - "pronouns", - "website", - "description", - "visibility", - "followers_count", - "following_count", - "starred_repos_count", - "username", - } - return any(field in user_obj for field in forgejo_fields) - - return ( - has_forgejo_user_fields(event.get("user")) - or has_forgejo_user_fields(nested_get(event, "pull_request", "user")) - or has_forgejo_user_fields(nested_get(event, "comment", "user")) - or has_forgejo_user_fields(nested_get(event, "issue", "user")) - or has_forgejo_user_fields(event.get("pusher")) - or has_forgejo_user_fields(event.get("sender")) - ) @staticmethod def parse_event( @@ -206,22 +165,6 @@ def parse_event( logger.warning("No event to process!") return None - # Check if this is a Forgejo event and prioritize Forgejo parsers - # We have to prioritize Forgejo events as they are similar in structure - # to github event payloads and hence can accidentally be parsed as - # Github objects. - is_forgejo = Parser.is_forgejo_event(event) - - if is_forgejo: - forgejo_parsers = ( - Parser.parse_forgejo_push_event, - Parser.parse_forgejo_pr_event, - Parser.parse_forgejo_comment_event, - ) - for parser in forgejo_parsers: - forgejo_response = parser(event) - if forgejo_response: - return forgejo_response for response in ( parser(event) @@ -2008,22 +1951,26 @@ def parse_logdetective_analysis_event(event) -> Optional[logdetective.Result]: @staticmethod def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]: - raw_ref = event.get("ref") - before = event.get("before") - after = event.get("after") - pusher = nested_get(event, "pusher", "login") + if "forgejo.push" not in event.get("topic", ""): + return None + + payload = event.get("body", {}) + raw_ref = payload.get("ref") + before = payload.get("before") + after = payload.get("after") + pusher = nested_get(payload, "pusher", "login") if not (raw_ref and after and before and pusher): return None # Forgejo sets `deleted` identically to GitHub - if event.get("deleted"): + if payload.get("deleted"): logger.info(f"Forgejo push event on '{raw_ref}' by {pusher} to delete ref") return None # Number of commits introduced by this push - num_commits = event.get("total_commits") + num_commits = payload.get("total_commits") # Strip the ref prefix to get the branch/tag name _, ref_type, ref_name = raw_ref.split("/", 2) @@ -2037,9 +1984,9 @@ def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]: f"({num_commits} {'commit' if num_commits == 1 else 'commits'})" ) - repo_namespace = nested_get(event, "repository", "owner", "login") - repo_name = nested_get(event, "repository", "name") - repo_url = nested_get(event, "repository", "html_url") + repo_namespace = nested_get(payload, "repository", "owner", "login") + repo_name = nested_get(payload, "repository", "name") + repo_url = nested_get(payload, "repository", "html_url") if not (repo_namespace and repo_name): logger.warning("Forgejo push event missing repository namespace/name") @@ -2061,21 +2008,25 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: Supported actions: 'opened', 'reopened', 'synchronize'. Skips others like 'closed'. """ - action_str = event.get("action") + if "forgejo.pull_request" not in event.get("topic", ""): + return None + + payload = event.get("body", {}) + action_str = payload.get("action") # Only trigger for these actions supported_actions = {"opened", "reopened", "synchronize"} if action_str not in supported_actions: logger.info(f"Skipping PR action: {action_str}") return None - pr = event.get("pull_request") + pr = payload.get("pull_request") if not pr: logger.warning("No pull_request in event.") return None pr_id = pr.get("number") - actor = nested_get(event, "pull_request", "user", "login") - repo = event.get("repository", {}) + actor = nested_get(payload, "pull_request", "user", "login") + repo = payload.get("repository", {}) base = pr.get("base") head = pr.get("head") body = pr.get("body") @@ -2103,7 +2054,7 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]: target_repo_name=target_repo_name, project_url=project_url, commit_sha=commit_sha, - commit_sha_before=event.get("before", ""), + commit_sha_before=payload.get("before", ""), actor=actor, body=body, ) @@ -2114,41 +2065,44 @@ def parse_forgejo_comment_event( ) -> Optional[Union[forgejo.pr.Comment, forgejo.issue.Comment]]: """Since Forgejo treats PR as special issues the comments are basically on issues, we need to distinguish between Forgejo issue and PR comments and parse accordingly.""" + if "forgejo.issue_comment" not in event.get("topic", ""): + return None - issue_id = nested_get(event, "issue", "number") - action = event.get("action") + payload = event.get("body", {}) + issue_id = nested_get(payload, "issue", "number") + action = payload.get("action") if action not in {"created", "edited"} or not issue_id: return None # Only treat as PR if 'pull_request' is present and not None - issue_dict = event.get("issue", {}) + issue_dict = payload.get("issue", {}) is_pr = issue_dict.get("pull_request") is not None - comment = nested_get(event, "comment", "body") - comment_id = nested_get(event, "comment", "id") + comment = nested_get(payload, "comment", "body") + comment_id = nested_get(payload, "comment", "id") logger.info( f"Forgejo {'PR' if is_pr else 'issue'}#{issue_id} " f"comment: {comment!r} id#{comment_id} {action!r} event." ) - user_login = nested_get(event, "comment", "user", "login") + user_login = nested_get(payload, "comment", "user", "login") if is_pr: # For PR comments, extract repo info from pull_request section base_repo_namespace = nested_get( - event, "pull_request", "head", "repo", "owner", "login" + payload, "pull_request", "head", "repo", "owner", "login" ) - base_repo_name = nested_get(event, "pull_request", "head", "repo", "name") + base_repo_name = nested_get(payload, "pull_request", "head", "repo", "name") target_repo_namespace = nested_get( - event, "pull_request", "base", "repo", "owner", "login" + payload, "pull_request", "base", "repo", "owner", "login" ) else: # For issue comments, extract from repository section - base_repo_namespace = nested_get(event, "repository", "owner", "login") - base_repo_name = nested_get(event, "repository", "name") - target_repo_namespace = nested_get(event, "repository", "owner", "login") + base_repo_namespace = nested_get(payload, "repository", "owner", "login") + base_repo_name = nested_get(payload, "repository", "name") + target_repo_namespace = nested_get(payload, "repository", "owner", "login") - target_repo_name = nested_get(event, "repository", "name") - https_url = nested_get(event, "repository", "html_url") + target_repo_name = nested_get(payload, "repository", "name") + https_url = nested_get(payload, "repository", "html_url") if not ( base_repo_name and base_repo_namespace and target_repo_name and target_repo_namespace @@ -2161,8 +2115,8 @@ def parse_forgejo_comment_event( return None if is_pr: - base_ref = nested_get(event, "pull_request", "head", "ref") - commit_sha = nested_get(event, "pull_request", "head", "sha") + base_ref = nested_get(payload, "pull_request", "head", "ref") + commit_sha = nested_get(payload, "pull_request", "head", "sha") return forgejo.pr.Comment( action=PullRequestCommentAction[action], pr_id=issue_id, @@ -2178,7 +2132,7 @@ def parse_forgejo_comment_event( commit_sha=commit_sha, ) # For issue comments, get the default branch - default_branch = nested_get(event, "repository", "default_branch") or "main" + default_branch = nested_get(payload, "repository", "default_branch") or "main" return forgejo.issue.Comment( action=IssueCommentAction[action], @@ -2215,12 +2169,10 @@ def parse_forgejo_comment_event( "Pipeline Hook": parse_pipeline_event.__func__, # type: ignore "Release Hook": parse_gitlab_release_event.__func__, # type: ignore }, - "forgejo": { - "push": parse_forgejo_push_event.__func__, # type: ignore - "issue_comment": parse_forgejo_comment_event.__func__, # type: ignore - "pull_request": parse_forgejo_pr_event.__func__, # type: ignore - }, "fedora-messaging": { + "forgejo.push": parse_forgejo_push_event.__func__, # type: ignore + "forgejo.pull_request": parse_forgejo_pr_event.__func__, # type: ignore + "forgejo.issue_comment": parse_forgejo_comment_event.__func__, # type: ignore "pagure.pull-request.flag.added": parse_pagure_pr_flag_event.__func__, # type: ignore "pagure.pull-request.flag.updated": parse_pagure_pr_flag_event.__func__, # type: ignore "pagure.pull-request.comment.added": parse_pagure_pull_request_comment_event.__func__, # type: ignore diff --git a/tests/data/fedmsg/forgejo_issue_comment.json b/tests/data/fedmsg/forgejo_issue_comment.json new file mode 100644 index 000000000..015c7d31a --- /dev/null +++ b/tests/data/fedmsg/forgejo_issue_comment.json @@ -0,0 +1,655 @@ +{ + "body": { + "action": "created", + "issue": { + "id": 131957, + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/issues/3366", + "html_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "number": 3366, + "user": { + "id": 2471, + "login": "jgroman", + "login_name": "", + "source_id": 0, + "full_name": "Jaroslav Groman", + "email": "jgroman@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "original_author": "", + "original_author_id": 0, + "title": "quality: blockerbugs app - update health check probes", + "body": "- update health check probes to use dedicated endpoint to reduce server and db load\r\n- add startup check to monitor app startup", + "ref": "", + "assets": [], + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "state": "open", + "is_locked": false, + "comments": 1, + "created_at": "2026-05-25T10:59:54Z", + "updated_at": "2026-05-25T13:14:09Z", + "closed_at": null, + "due_date": null, + "pull_request": { + "merged": false, + "merged_at": null, + "draft": false, + "html_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366" + }, + "repository": { + "id": 664, + "name": "ansible", + "owner": "infra", + "full_name": "infra/ansible" + }, + "pin_order": 0 + }, + "pull_request": { + "id": 41986, + "url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "number": 3366, + "user": { + "id": 2471, + "login": "jgroman", + "login_name": "", + "source_id": 0, + "full_name": "Jaroslav Groman", + "email": "jgroman@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "title": "quality: blockerbugs app - update health check probes", + "body": "- update health check probes to use dedicated endpoint to reduce server and db load\r\n- add startup check to monitor app startup", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": [ + { + "id": 138, + "login": "adamwill", + "login_name": "", + "source_id": 0, + "full_name": "Adam Williamson", + "email": "adamwill@noreply.forge.fedoraproject.org", + "avatar_url": "https://seccdn.libravatar.org/avatar/c7147e0eeef52c5999f2334cfeaf0f7a?d=identicon", + "html_url": "https://forge.fedoraproject.org/adamwill", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T10:52:45Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 1, + "following_count": 0, + "starred_repos_count": 0, + "username": "adamwill" + } + ], + "requested_reviewers_teams": [], + "state": "open", + "draft": false, + "is_locked": false, + "comments": 1, + "review_comments": 0, + "additions": 13, + "deletions": 6, + "changed_files": 1, + "html_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "diff_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366.diff", + "patch_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366.patch", + "mergeable": true, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "004fb438fe0c77ba1dc266a0b508f2c1ddb3d705", + "repo_id": 664, + "repo": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + } + }, + "head": { + "label": "main", + "ref": "main", + "sha": "d0bb319af8dfa9944649231d09573ca02650ff9d", + "repo_id": 1295, + "repo": { + "id": 1295, + "owner": { + "id": 2471, + "login": "jgroman", + "login_name": "", + "source_id": 0, + "full_name": "Jaroslav Groman", + "email": "jgroman@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "name": "ansible", + "full_name": "jgroman/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": true, + "template": false, + "parent": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + }, + "mirror": false, + "size": 128149, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/jgroman/ansible/languages", + "html_url": "https://forge.fedoraproject.org/jgroman/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/jgroman/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/jgroman/ansible.git", + "clone_url": "https://forge.fedoraproject.org/jgroman/ansible.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 0, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-05-25T10:41:17Z", + "updated_at": "2026-05-25T10:56:34Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/jgroman/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/jgroman/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "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": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": "004fb438fe0c77ba1dc266a0b508f2c1ddb3d705", + "due_date": null, + "created_at": "2026-05-25T10:59:54Z", + "updated_at": "2026-05-25T13:14:09Z", + "closed_at": null, + "pin_order": 0, + "flow": 0 + }, + "comment": { + "id": 759973, + "html_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366#issuecomment-759973", + "pull_request_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "issue_url": "", + "user": { + "id": 19, + "login": "kparal", + "login_name": "", + "source_id": 0, + "full_name": "Kamil Páral", + "email": "kparal@noreply.forge.fedoraproject.org", + "avatar_url": "https://seccdn.libravatar.org/avatar/b8a9c0099f88846ba77fd6dc39008d95?d=identicon", + "html_url": "https://forge.fedoraproject.org/kparal", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T10:49:56Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "kparal" + }, + "original_author": "", + "original_author_id": 0, + "body": "Even though I haven't studied what the variables exactly mean (I hope infra folks do know), it looks OK to me.\r\n\r\nBut shouldn't we push the latest BBA version implementing the health probe at least to staging, so that the endpoint can be easily tested? Jaroslav, can you do that please?", + "assets": [], + "created_at": "2026-05-25T13:14:09Z", + "updated_at": "2026-05-25T13:14:09Z" + }, + "repository": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + }, + "sender": { + "id": 19, + "login": "kparal", + "login_name": "", + "source_id": 0, + "full_name": "Kamil Páral", + "email": "kparal@noreply.forge.fedoraproject.org", + "avatar_url": "https://seccdn.libravatar.org/avatar/b8a9c0099f88846ba77fd6dc39008d95?d=identicon", + "html_url": "https://forge.fedoraproject.org/kparal", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T10:49:56Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "kparal" + }, + "is_pull": true + }, + "headers": { + "user-agent": "Go-http-client/1.1", + "authorization": "Basic 973bf765c2eb40ebada712bddfeef1ed", + "content-type": "application/json", + "x-forgejo-delivery": "0619b8b1-60f2-4242-9004-489b58c7a8eb", + "x-forgejo-event": "issue_comment", + "x-forgejo-event-type": "pull_request_comment", + "x-forgejo-signature": "518834c1f8125adc105a306a4c4a6334b4099b1606db017ef01c3ef5713b1932", + "x-github-delivery": "0619b8b1-60f2-4242-9004-489b58c7a8eb", + "x-github-event": "issue_comment", + "x-github-event-type": "pull_request_comment", + "x-gitea-delivery": "0619b8b1-60f2-4242-9004-489b58c7a8eb", + "x-gitea-event": "issue_comment", + "x-gitea-event-type": "pull_request_comment", + "x-gitea-signature": "518834c1f8125adc105a306a4c4a6334b4099b1606db017ef01c3ef5713b1932", + "x-gogs-delivery": "0619b8b1-60f2-4242-9004-489b58c7a8eb", + "x-gogs-event": "issue_comment", + "x-gogs-event-type": "pull_request_comment", + "x-gogs-signature": "518834c1f8125adc105a306a4c4a6334b4099b1606db017ef01c3ef5713b1932", + "x-hub-signature": "sha1=a1bbc0d69ca9dff5e4346e16928588af7eb55079", + "x-hub-signature-256": "sha256=518834c1f8125adc105a306a4c4a6334b4099b1606db017ef01c3ef5713b1932", + "accept-encoding": "gzip", + "x-forwarded-scheme": "https", + "x-forwarded-proto": "https", + "x-fedora-requestid": "ahRLIpyULu7F-7KMfU5pzQAAFE4", + "x-forwarded-for": "10.16.163.75", + "x-forwarded-host": "webhook.fedoraproject.org", + "x-forwarded-server": "webhook.fedoraproject.org", + "content-length": "21388", + "host": "webhook.fedoraproject.org", + "x-forwarded-port": "443", + "forwarded": "for=10.16.163.75;host=webhook.fedoraproject.org;proto=https" + }, + "agent": null, + "topic": "org.fedoraproject.prod.forgejo.issue_comment" +} diff --git a/tests/data/fedmsg/forgejo_pr.json b/tests/data/fedmsg/forgejo_pr.json new file mode 100644 index 000000000..c9d762091 --- /dev/null +++ b/tests/data/fedmsg/forgejo_pr.json @@ -0,0 +1,583 @@ +{ + "body": { + "action": "review_requested", + "number": 3366, + "pull_request": { + "id": 41986, + "url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "number": 3366, + "user": { + "id": 2471, + "login": "jgroman", + "login_name": "jgroman", + "source_id": 1, + "full_name": "Jaroslav Groman", + "email": "jgroman@redhat.com", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "en-US", + "is_admin": false, + "last_login": "2026-05-21T08:41:02Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": true, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "title": "quality: blockerbugs app - update health check probes", + "body": "- update health check probes to use dedicated endpoint to reduce server and db load\r\n- add startup check to monitor app startup", + "labels": [], + "milestone": null, + "assignee": null, + "assignees": null, + "requested_reviewers": [ + { + "id": 138, + "login": "adamwill", + "login_name": "", + "source_id": 0, + "full_name": "Adam Williamson", + "email": "adamwill@noreply.forge.fedoraproject.org", + "avatar_url": "https://seccdn.libravatar.org/avatar/c7147e0eeef52c5999f2334cfeaf0f7a?d=identicon", + "html_url": "https://forge.fedoraproject.org/adamwill", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T10:52:45Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 1, + "following_count": 0, + "starred_repos_count": 0, + "username": "adamwill" + } + ], + "requested_reviewers_teams": [], + "state": "open", + "draft": false, + "is_locked": false, + "comments": 0, + "review_comments": 0, + "additions": 13, + "deletions": 6, + "changed_files": 1, + "html_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366", + "diff_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366.diff", + "patch_url": "https://forge.fedoraproject.org/infra/ansible/pulls/3366.patch", + "mergeable": true, + "merged": false, + "merged_at": null, + "merge_commit_sha": null, + "merged_by": null, + "allow_maintainer_edit": false, + "base": { + "label": "main", + "ref": "main", + "sha": "004fb438fe0c77ba1dc266a0b508f2c1ddb3d705", + "repo_id": 664, + "repo": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + } + }, + "head": { + "label": "main", + "ref": "main", + "sha": "d0bb319af8dfa9944649231d09573ca02650ff9d", + "repo_id": 1295, + "repo": { + "id": 1295, + "owner": { + "id": 2471, + "login": "jgroman", + "login_name": "", + "source_id": 0, + "full_name": "Jaroslav Groman", + "email": "jgroman@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "name": "ansible", + "full_name": "jgroman/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": true, + "template": false, + "parent": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + }, + "mirror": false, + "size": 128149, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/jgroman/ansible/languages", + "html_url": "https://forge.fedoraproject.org/jgroman/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/jgroman/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/jgroman/ansible.git", + "clone_url": "https://forge.fedoraproject.org/jgroman/ansible.git", + "original_url": "", + "website": "", + "stars_count": 0, + "forks_count": 0, + "watchers_count": 0, + "open_issues_count": 0, + "open_pr_counter": 0, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-05-25T10:41:17Z", + "updated_at": "2026-05-25T10:56:34Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/jgroman/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/jgroman/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "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": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": "004fb438fe0c77ba1dc266a0b508f2c1ddb3d705", + "due_date": null, + "created_at": "2026-05-25T10:59:54Z", + "updated_at": "2026-05-25T11:00:12Z", + "closed_at": null, + "pin_order": 0, + "flow": 0 + }, + "requested_reviewer": { + "id": 138, + "login": "adamwill", + "login_name": "", + "source_id": 0, + "full_name": "Adam Williamson", + "email": "adamwill@noreply.forge.fedoraproject.org", + "avatar_url": "https://seccdn.libravatar.org/avatar/c7147e0eeef52c5999f2334cfeaf0f7a?d=identicon", + "html_url": "https://forge.fedoraproject.org/adamwill", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T10:52:45Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 1, + "following_count": 0, + "starred_repos_count": 0, + "username": "adamwill" + }, + "repository": { + "id": 664, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "ansible", + "full_name": "infra/ansible", + "description": "Fedora Infrastructure Ansible Repository", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 158866, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible/languages", + "html_url": "https://forge.fedoraproject.org/infra/ansible", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/ansible", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.git", + "clone_url": "https://forge.fedoraproject.org/infra/ansible.git", + "original_url": "https://pagure.io/fedora-infra/ansible/", + "website": "", + "stars_count": 3, + "forks_count": 44, + "watchers_count": 23, + "open_issues_count": 0, + "open_pr_counter": 13, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2026-02-17T14:43:41Z", + "updated_at": "2026-05-25T08:08:03Z", + "archived_at": "1970-01-01T00:00:00Z", + "permissions": { + "admin": false, + "push": false, + "pull": true + }, + "has_issues": false, + "has_wiki": false, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/ansible.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/ansible.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": false, + "has_releases": false, + "has_packages": false, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "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": [ + "ansible", + "fedora", + "fedora-infra" + ] + }, + "sender": { + "id": 2471, + "login": "jgroman", + "login_name": "", + "source_id": 0, + "full_name": "Jaroslav Groman", + "email": "jgroman@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/83090da2cf07c84197ec3f3512f4b428bfb4f533048ce29dcd2b9c9bdbef469e", + "html_url": "https://forge.fedoraproject.org/jgroman", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-11-26T08:55:37Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "jgroman" + }, + "commit_id": "", + "review": null + }, + "headers": { + "user-agent": "Go-http-client/1.1", + "authorization": "Basic 973bf765c2eb40ebada712bddfeef1ed", + "content-type": "application/json", + "x-forgejo-delivery": "ff00c4bb-10be-49d9-b38a-4e2787e0f205", + "x-forgejo-event": "pull_request", + "x-forgejo-event-type": "pull_request_review_request", + "x-forgejo-signature": "23a4c4d690a53661671c6c063cb96af954cbb39bdfb2d5da0b3c175d6bb747bd", + "x-github-delivery": "ff00c4bb-10be-49d9-b38a-4e2787e0f205", + "x-github-event": "pull_request", + "x-github-event-type": "pull_request_review_request", + "x-gitea-delivery": "ff00c4bb-10be-49d9-b38a-4e2787e0f205", + "x-gitea-event": "pull_request", + "x-gitea-event-type": "pull_request_review_request", + "x-gitea-signature": "23a4c4d690a53661671c6c063cb96af954cbb39bdfb2d5da0b3c175d6bb747bd", + "x-gogs-delivery": "ff00c4bb-10be-49d9-b38a-4e2787e0f205", + "x-gogs-event": "pull_request", + "x-gogs-event-type": "pull_request_review_request", + "x-gogs-signature": "23a4c4d690a53661671c6c063cb96af954cbb39bdfb2d5da0b3c175d6bb747bd", + "x-hub-signature": "sha1=14916c2df5f2dbbe6d19366c2c276d8677dadde6", + "x-hub-signature-256": "sha256=23a4c4d690a53661671c6c063cb96af954cbb39bdfb2d5da0b3c175d6bb747bd", + "accept-encoding": "gzip", + "x-forwarded-scheme": "https", + "x-forwarded-proto": "https", + "x-fedora-requestid": "ahQrvkJSPhgX7fbf4PonVwAAA0c", + "x-forwarded-for": "10.16.163.74", + "x-forwarded-host": "webhook.fedoraproject.org", + "x-forwarded-server": "webhook.fedoraproject.org", + "content-length": "18755", + "host": "webhook.fedoraproject.org", + "x-forwarded-port": "443", + "forwarded": "for=10.16.163.74;host=webhook.fedoraproject.org;proto=https" + }, + "agent": null, + "topic": "org.fedoraproject.prod.forgejo.pull_request" +} diff --git a/tests/data/fedmsg/forgejo_push.json b/tests/data/fedmsg/forgejo_push.json new file mode 100644 index 000000000..c32cbe227 --- /dev/null +++ b/tests/data/fedmsg/forgejo_push.json @@ -0,0 +1,241 @@ +{ + "body": { + "ref": "refs/heads/main", + "before": "8848429b902c7747e1b36af8b5225117b6254fb5", + "after": "139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "compare_url": "https://forge.fedoraproject.org/infra/docs/compare/8848429b902c7747e1b36af8b5225117b6254fb5...139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "commits": [ + { + "id": "139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "message": "copr: update Pulp team slack handle\n\nWe had a meeting with @dkliban and @bmbouter today and they said they are\nmoving things to the new handle.\n", + "url": "https://forge.fedoraproject.org/infra/docs/commit/139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "author": { + "name": "Jakub Kadlcik", + "email": "frostyx@email.cz", + "username": "" + }, + "committer": { + "name": "Michal Konečný", + "email": "zlopez@noreply.forge.fedoraproject.org", + "username": "zlopez" + }, + "verification": null, + "timestamp": "2026-05-20T18:11:26+02:00", + "added": [], + "removed": [], + "modified": [ + "modules/sysadmin_sops/pages/copr.adoc" + ] + } + ], + "total_commits": 1, + "head_commit": { + "id": "139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "message": "copr: update Pulp team slack handle\n\nWe had a meeting with @dkliban and @bmbouter today and they said they are\nmoving things to the new handle.\n", + "url": "https://forge.fedoraproject.org/infra/docs/commit/139828ad0b8fd3c5d172ccc0fc695a6d7a98f4c5", + "author": { + "name": "Jakub Kadlcik", + "email": "frostyx@email.cz", + "username": "" + }, + "committer": { + "name": "Michal Konečný", + "email": "zlopez@noreply.forge.fedoraproject.org", + "username": "zlopez" + }, + "verification": null, + "timestamp": "2026-05-20T18:11:26+02:00", + "added": [], + "removed": [], + "modified": [ + "modules/sysadmin_sops/pages/copr.adoc" + ] + }, + "repository": { + "id": 378, + "owner": { + "id": 2492, + "login": "infra", + "login_name": "", + "source_id": 0, + "full_name": "Infrastructure", + "email": "", + "avatar_url": "https://forge.fedoraproject.org/avatars/3a8323a7c9fd05c0cc41d2f54f17309ca71e02cd5f713a2e05de96ebc82996f0", + "html_url": "https://forge.fedoraproject.org/infra", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-12-01T18:43:16Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 21, + "following_count": 0, + "starred_repos_count": 0, + "username": "infra" + }, + "name": "docs", + "full_name": "infra/docs", + "description": "Fedora Infrastructure Documentation", + "empty": false, + "private": false, + "fork": false, + "template": false, + "parent": null, + "mirror": false, + "size": 6653, + "language": "", + "languages_url": "https://forge.fedoraproject.org/api/v1/repos/infra/docs/languages", + "html_url": "https://forge.fedoraproject.org/infra/docs", + "url": "https://forge.fedoraproject.org/api/v1/repos/infra/docs", + "link": "", + "ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/docs.git", + "clone_url": "https://forge.fedoraproject.org/infra/docs.git", + "original_url": "https://pagure.io/infra-docs-fpo", + "website": "", + "stars_count": 1, + "forks_count": 24, + "watchers_count": 19, + "open_issues_count": 55, + "open_pr_counter": 2, + "release_counter": 0, + "default_branch": "main", + "archived": false, + "created_at": "2025-12-12T11:19:25Z", + "updated_at": "2026-05-23T16:58:39Z", + "archived_at": "1970-01-01T00:00:00Z", + "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, + "has_wiki_contents": false, + "wiki_branch": "main", + "wiki_ssh_url": "ssh://1001300000@forge.fedoraproject.org/infra/docs.wiki.git", + "wiki_clone_url": "https://forge.fedoraproject.org/infra/docs.wiki.git", + "globally_editable_wiki": false, + "has_pull_requests": true, + "has_projects": true, + "has_releases": true, + "has_packages": true, + "has_actions": true, + "ignore_whitespace_conflicts": false, + "allow_merge_commits": false, + "allow_rebase": true, + "allow_rebase_explicit": false, + "allow_squash_merge": false, + "allow_fast_forward_only_merge": true, + "allow_rebase_update": true, + "default_delete_branch_after_merge": false, + "default_merge_style": "rebase", + "default_allow_maintainer_edit": false, + "default_update_style": "rebase", + "avatar_url": "", + "internal": false, + "mirror_interval": "", + "object_format_name": "sha1", + "mirror_updated": "0001-01-01T00:00:00Z", + "repo_transfer": null, + "topics": [] + }, + "pusher": { + "id": 352, + "login": "zlopez", + "login_name": "", + "source_id": 0, + "full_name": "Michal Konečný", + "email": "zlopez@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/b01ac19b53f5233acce19f7ec3a07ce5fd794ddb7a8f22a85def1bbe9a31f593", + "html_url": "https://forge.fedoraproject.org/zlopez", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T12:27:06Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "zlopez" + }, + "sender": { + "id": 352, + "login": "zlopez", + "login_name": "", + "source_id": 0, + "full_name": "Michal Konečný", + "email": "zlopez@noreply.forge.fedoraproject.org", + "avatar_url": "https://forge.fedoraproject.org/avatars/b01ac19b53f5233acce19f7ec3a07ce5fd794ddb7a8f22a85def1bbe9a31f593", + "html_url": "https://forge.fedoraproject.org/zlopez", + "language": "", + "is_admin": false, + "last_login": "0001-01-01T00:00:00Z", + "created": "2025-08-13T12:27:06Z", + "restricted": false, + "active": false, + "prohibit_login": false, + "location": "", + "pronouns": "", + "website": "", + "description": "", + "visibility": "public", + "followers_count": 0, + "following_count": 0, + "starred_repos_count": 0, + "username": "zlopez" + } + }, + "headers": { + "user-agent": "Go-http-client/1.1", + "authorization": "Basic 973bf765c2eb40ebada712bddfeef1ed", + "content-type": "application/json", + "x-forgejo-delivery": "1b207496-d58f-4bea-a04f-d1778592875d", + "x-forgejo-event": "push", + "x-forgejo-event-type": "push", + "x-forgejo-signature": "0e07c0971310f07afe600963286d76d771c9873caceb420fc25dff17601e0190", + "x-github-delivery": "1b207496-d58f-4bea-a04f-d1778592875d", + "x-github-event": "push", + "x-github-event-type": "push", + "x-gitea-delivery": "1b207496-d58f-4bea-a04f-d1778592875d", + "x-gitea-event": "push", + "x-gitea-event-type": "push", + "x-gitea-signature": "0e07c0971310f07afe600963286d76d771c9873caceb420fc25dff17601e0190", + "x-gogs-delivery": "1b207496-d58f-4bea-a04f-d1778592875d", + "x-gogs-event": "push", + "x-gogs-event-type": "push", + "x-gogs-signature": "0e07c0971310f07afe600963286d76d771c9873caceb420fc25dff17601e0190", + "x-hub-signature": "sha1=d6530c98f4d8840904633876af00ad358d29d9d3", + "x-hub-signature-256": "sha256=0e07c0971310f07afe600963286d76d771c9873caceb420fc25dff17601e0190", + "accept-encoding": "gzip", + "x-forwarded-scheme": "https", + "x-forwarded-proto": "https", + "x-fedora-requestid": "ahQEw5hMz-OHjPDTFgSVdQAAEAU", + "x-forwarded-for": "10.16.163.77", + "x-forwarded-host": "webhook.fedoraproject.org", + "x-forwarded-server": "webhook.fedoraproject.org", + "content-length": "6705", + "host": "webhook.fedoraproject.org", + "x-forwarded-port": "443", + "forwarded": "for=10.16.163.77;host=webhook.fedoraproject.org;proto=https" + }, + "agent": null, + "topic": "org.fedoraproject.prod.forgejo.push" +} diff --git a/tests/data/webhooks/forgejo/issue_comment.json b/tests/data/webhooks/forgejo/issue_comment.json deleted file mode 100644 index f3c945c18..000000000 --- a/tests/data/webhooks/forgejo/issue_comment.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "action": "created", - "issue": { - "id": 1118, - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/issues/1", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1", - "number": 1, - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@example.com", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "en-US", - "is_admin": false, - "last_login": "2025-08-18T17:54:40Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": true, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "original_author": "", - "original_author_id": 0, - "title": "new issue", - "body": "", - "ref": "", - "assets": [], - "labels": [], - "milestone": null, - "assignee": null, - "assignees": null, - "state": "open", - "is_locked": false, - "comments": 0, - "created_at": "2025-08-19T08:34:42Z", - "updated_at": "2025-08-19T08:36:14Z", - "closed_at": null, - "due_date": null, - "pull_request": null, - "repository": { - "id": 681, - "name": "test-repo-to-generate-events", - "owner": "packit", - "full_name": "packit/test-repo-to-generate-events" - }, - "pin_order": 0 - }, - "comment": { - "id": 3144, - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1#issuecomment-3144", - "pull_request_url": "", - "issue_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/issues/1", - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "original_author": "", - "original_author_id": 0, - "body": "issue comment", - "assets": [], - "created_at": "2025-08-19T08:36:14Z", - "updated_at": "2025-08-19T08:36:14Z" - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 27, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:33:58Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "is_pull": false -} diff --git a/tests/data/webhooks/forgejo/pr_comment.json b/tests/data/webhooks/forgejo/pr_comment.json deleted file mode 100644 index 1afcb99d9..000000000 --- a/tests/data/webhooks/forgejo/pr_comment.json +++ /dev/null @@ -1,581 +0,0 @@ -{ - "action": "created", - "issue": { - "id": 1119, - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/issues/2", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "number": 2, - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@example.com", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "en-US", - "is_admin": false, - "last_login": "2025-08-18T17:54:40Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": true, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "original_author": "", - "original_author_id": 0, - "title": "feature-branch-to-be-merged-via-pr", - "body": "", - "ref": "", - "assets": [], - "labels": [], - "milestone": null, - "assignee": null, - "assignees": null, - "state": "open", - "is_locked": false, - "comments": 0, - "created_at": "2025-08-19T08:44:27Z", - "updated_at": "2025-08-19T08:45:58Z", - "closed_at": null, - "due_date": null, - "pull_request": { - "merged": false, - "merged_at": null, - "draft": false, - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2" - }, - "repository": { - "id": 681, - "name": "test-repo-to-generate-events", - "owner": "packit", - "full_name": "packit/test-repo-to-generate-events" - }, - "pin_order": 0 - }, - "pull_request": { - "id": 505, - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "number": 2, - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@example.com", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "en-US", - "is_admin": false, - "last_login": "2025-08-18T17:54:40Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": true, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "title": "feature-branch-to-be-merged-via-pr", - "body": "", - "labels": [], - "milestone": null, - "assignee": null, - "assignees": null, - "requested_reviewers": null, - "requested_reviewers_teams": null, - "state": "open", - "draft": false, - "is_locked": false, - "comments": 0, - "review_comments": 0, - "additions": 0, - "deletions": 0, - "changed_files": 0, - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "diff_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.diff", - "patch_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.patch", - "mergeable": true, - "merged": false, - "merged_at": null, - "merge_commit_sha": null, - "merged_by": null, - "allow_maintainer_edit": false, - "base": { - "label": "main", - "ref": "main", - "sha": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "repo_id": 681, - "repo": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 1, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - } - }, - "head": { - "label": "feature-branch-to-be-merged-via-pr", - "ref": "feature-branch-to-be-merged-via-pr", - "sha": "37182f59ccaaa21584e7b580442fd33b60fe3f80", - "repo_id": 682, - "repo": { - "id": 682, - "owner": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "name": "test-repo-to-generate-events", - "full_name": "mfocko/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": true, - "template": false, - "parent": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 1, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/mfocko/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 0, - "watchers_count": 1, - "open_issues_count": 0, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:59:49Z", - "updated_at": "2025-08-19T08:43:17Z", - "archived_at": "1970-01-01T00:00:00Z", - "permissions": { - "admin": true, - "push": true, - "pull": true - }, - "has_issues": false, - "has_wiki": false, - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": false, - "has_releases": false, - "has_packages": false, - "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": true, - "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": null - } - }, - "merge_base": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "due_date": null, - "created_at": "2025-08-19T08:44:27Z", - "updated_at": "2025-08-19T08:45:58Z", - "closed_at": null, - "pin_order": 0 - }, - "comment": { - "id": 3146, - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2#issuecomment-3146", - "pull_request_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "issue_url": "", - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "original_author": "", - "original_author_id": 0, - "body": "PR comment", - "assets": [], - "created_at": "2025-08-19T08:45:58Z", - "updated_at": "2025-08-19T08:45:58Z" - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 1, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "is_pull": true -} diff --git a/tests/data/webhooks/forgejo/pr_opened.json b/tests/data/webhooks/forgejo/pr_opened.json deleted file mode 100644 index 32f6304f2..000000000 --- a/tests/data/webhooks/forgejo/pr_opened.json +++ /dev/null @@ -1,484 +0,0 @@ -{ - "action": "opened", - "number": 2, - "pull_request": { - "id": 505, - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "number": 2, - "user": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@example.com", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "en-US", - "is_admin": false, - "last_login": "2025-08-18T17:54:40Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": true, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "title": "feature-branch-to-be-merged-via-pr", - "body": "", - "labels": [], - "milestone": null, - "assignee": null, - "assignees": null, - "requested_reviewers": null, - "requested_reviewers_teams": null, - "state": "open", - "draft": false, - "is_locked": false, - "comments": 0, - "review_comments": 0, - "additions": 0, - "deletions": 0, - "changed_files": 0, - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2", - "diff_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.diff", - "patch_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/pulls/2.patch", - "mergeable": true, - "merged": false, - "merged_at": null, - "merge_commit_sha": null, - "merged_by": null, - "allow_maintainer_edit": false, - "base": { - "label": "main", - "ref": "main", - "sha": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "repo_id": 681, - "repo": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - } - }, - "head": { - "label": "feature-branch-to-be-merged-via-pr", - "ref": "feature-branch-to-be-merged-via-pr", - "sha": "37182f59ccaaa21584e7b580442fd33b60fe3f80", - "repo_id": 682, - "repo": { - "id": 682, - "owner": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "name": "test-repo-to-generate-events", - "full_name": "mfocko/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": true, - "template": false, - "parent": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 1, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/mfocko/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/mfocko/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/mfocko/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 0, - "watchers_count": 1, - "open_issues_count": 0, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:59:49Z", - "updated_at": "2025-08-19T08:43:17Z", - "archived_at": "1970-01-01T00:00:00Z", - "permissions": { - "admin": true, - "push": true, - "pull": true - }, - "has_issues": false, - "has_wiki": false, - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": false, - "has_releases": false, - "has_packages": false, - "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": true, - "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": null - } - }, - "merge_base": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "due_date": null, - "created_at": "2025-08-19T08:44:27Z", - "updated_at": "2025-08-19T08:44:34Z", - "closed_at": null, - "pin_order": 0 - }, - "requested_reviewer": null, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 28, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:37:25Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "commit_id": "", - "review": null -} diff --git a/tests/data/webhooks/forgejo/push_new_branch.json b/tests/data/webhooks/forgejo/push_new_branch.json deleted file mode 100644 index 43c223a3e..000000000 --- a/tests/data/webhooks/forgejo/push_new_branch.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "ref": "refs/heads/new-branch", - "before": "0000000000000000000000000000000000000000", - "after": "24f660b69e4608f63ddd55d5c5b459f348e5f272", - "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/fa9bbf46c6ae89b755716683814b03b6a2c82263...24f660b69e4608f63ddd55d5c5b459f348e5f272", - "commits": [ - { - "id": "24f660b69e4608f63ddd55d5c5b459f348e5f272", - "message": "huh\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/24f660b69e4608f63ddd55d5c5b459f348e5f272", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:36:37+02:00", - "added": [], - "removed": [], - "modified": [] - } - ], - "total_commits": 1, - "head_commit": { - "id": "24f660b69e4608f63ddd55d5c5b459f348e5f272", - "message": "huh\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/24f660b69e4608f63ddd55d5c5b459f348e5f272", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:36:37+02:00", - "added": [], - "removed": [], - "modified": [] - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 27, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 1, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:33:58Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "pusher": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - } -} diff --git a/tests/data/webhooks/forgejo/push_with_many_commits.json b/tests/data/webhooks/forgejo/push_with_many_commits.json deleted file mode 100644 index 02d8f0514..000000000 --- a/tests/data/webhooks/forgejo/push_with_many_commits.json +++ /dev/null @@ -1,277 +0,0 @@ -{ - "ref": "refs/heads/main", - "before": "c85008a0b44a60370e48a45a9f9d39da5b472e11", - "after": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/c85008a0b44a60370e48a45a9f9d39da5b472e11...fa9bbf46c6ae89b755716683814b03b6a2c82263", - "commits": [ - { - "id": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "message": "seventh of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/fa9bbf46c6ae89b755716683814b03b6a2c82263", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:23+02:00", - "added": [], - "removed": [], - "modified": [] - }, - { - "id": "da5184eb5c8a16247ce3025af1b72da8086c1337", - "message": "sixth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/da5184eb5c8a16247ce3025af1b72da8086c1337", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:19+02:00", - "added": [], - "removed": [], - "modified": [] - }, - { - "id": "b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", - "message": "fifth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:15+02:00", - "added": [], - "removed": [], - "modified": [] - }, - { - "id": "8d6033f1165c66acf8a4e2d0dffaf3ab10182a93", - "message": "fourth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/8d6033f1165c66acf8a4e2d0dffaf3ab10182a93", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:10+02:00", - "added": [], - "removed": [], - "modified": [] - }, - { - "id": "28c86b1224488c6fbf2b8018ebdee9b7251e804a", - "message": "third of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/28c86b1224488c6fbf2b8018ebdee9b7251e804a", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:05+02:00", - "added": [], - "removed": [], - "modified": [] - } - ], - "total_commits": 7, - "head_commit": { - "id": "fa9bbf46c6ae89b755716683814b03b6a2c82263", - "message": "seventh of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/fa9bbf46c6ae89b755716683814b03b6a2c82263", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:23+02:00", - "added": [], - "removed": [], - "modified": [] - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 23, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 0, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:29:32Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "pusher": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - } -} diff --git a/tests/data/webhooks/forgejo/push_with_one_commit.json b/tests/data/webhooks/forgejo/push_with_one_commit.json deleted file mode 100644 index 93aed4420..000000000 --- a/tests/data/webhooks/forgejo/push_with_one_commit.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "ref": "refs/heads/main", - "before": "b5827a36fbab61567da4376f7494a0e519d38a6e", - "after": "c85008a0b44a60370e48a45a9f9d39da5b472e11", - "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/b5827a36fbab61567da4376f7494a0e519d38a6e...c85008a0b44a60370e48a45a9f9d39da5b472e11", - "commits": [ - { - "id": "c85008a0b44a60370e48a45a9f9d39da5b472e11", - "message": "pushing one empty commit\n\nSigned-off-by: Matej Focko \u003cme@mfocko.xyz\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/c85008a0b44a60370e48a45a9f9d39da5b472e11", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:28:44+02:00", - "added": [], - "removed": [], - "modified": [] - } - ], - "total_commits": 1, - "head_commit": { - "id": "c85008a0b44a60370e48a45a9f9d39da5b472e11", - "message": "pushing one empty commit\n\nSigned-off-by: Matej Focko \u003cme@mfocko.xyz\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/c85008a0b44a60370e48a45a9f9d39da5b472e11", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:28:44+02:00", - "added": [], - "removed": [], - "modified": [] - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 23, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 0, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-18T17:59:07Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "pusher": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - } -} diff --git a/tests/data/webhooks/forgejo/tag_push.json b/tests/data/webhooks/forgejo/tag_push.json deleted file mode 100644 index b73447e9b..000000000 --- a/tests/data/webhooks/forgejo/tag_push.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "ref": "refs/tags/fifth", - "before": "0000000000000000000000000000000000000000", - "after": "9abc2644c3b9828db4bbe30c795b140c6c55089f", - "compare_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/compare/0000000000000000000000000000000000000000...9abc2644c3b9828db4bbe30c795b140c6c55089f", - "commits": [], - "total_commits": 0, - "head_commit": { - "id": "b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", - "message": "fifth of many commits\n\nSigned-off-by: Matej Focko \u003cmf@example.com\u003e\n", - "url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events/commit/b8a8746d7b91bcff18e9f59a9a1b440089fc2dd5", - "author": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "committer": { - "name": "Matej Focko", - "email": "mf@example.com", - "username": "" - }, - "verification": null, - "timestamp": "2025-08-19T10:31:15+02:00", - "added": [], - "removed": [], - "modified": [] - }, - "repository": { - "id": 681, - "owner": { - "id": 450, - "login": "packit", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "", - "avatar_url": "https://v10.next.forgejo.org/avatars/ccef19de5d28148945dcca5aa2249c00", - "html_url": "https://v10.next.forgejo.org/packit", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-01-29T09:25:44Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "packit" - }, - "name": "test-repo-to-generate-events", - "full_name": "packit/test-repo-to-generate-events", - "description": "", - "empty": false, - "private": false, - "fork": false, - "template": false, - "parent": null, - "mirror": false, - "size": 27, - "language": "", - "languages_url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events/languages", - "html_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events", - "url": "https://v10.next.forgejo.org/api/v1/repos/packit/test-repo-to-generate-events", - "link": "", - "ssh_url": "ssh://git@v10.next.forgejo.org:2100/packit/test-repo-to-generate-events.git", - "clone_url": "https://v10.next.forgejo.org/packit/test-repo-to-generate-events.git", - "original_url": "", - "website": "", - "stars_count": 0, - "forks_count": 1, - "watchers_count": 3, - "open_issues_count": 0, - "open_pr_counter": 0, - "release_counter": 0, - "default_branch": "main", - "archived": false, - "created_at": "2025-08-18T17:58:42Z", - "updated_at": "2025-08-19T08:32:16Z", - "archived_at": "1970-01-01T00:00:00Z", - "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": "main", - "globally_editable_wiki": false, - "has_pull_requests": true, - "has_projects": true, - "has_releases": true, - "has_packages": true, - "has_actions": true, - "ignore_whitespace_conflicts": false, - "allow_merge_commits": true, - "allow_rebase": true, - "allow_rebase_explicit": true, - "allow_squash_merge": true, - "allow_fast_forward_only_merge": true, - "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": null - }, - "pusher": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - }, - "sender": { - "id": 601, - "login": "mfocko", - "login_name": "", - "source_id": 0, - "full_name": "", - "email": "mfocko@noreply.v10.next.forgejo.org", - "avatar_url": "https://v10.next.forgejo.org/avatars/ee44221e4bd2b983751872d3cde92cf4", - "html_url": "https://v10.next.forgejo.org/mfocko", - "language": "", - "is_admin": false, - "last_login": "0001-01-01T00:00:00Z", - "created": "2025-02-12T13:52:32Z", - "restricted": false, - "active": false, - "prohibit_login": false, - "location": "", - "pronouns": "", - "website": "", - "description": "", - "visibility": "public", - "followers_count": 0, - "following_count": 0, - "starred_repos_count": 0, - "username": "mfocko" - } -} diff --git a/tests/unit/events/test_forgejo.py b/tests/unit/events/test_forgejo.py index 97973443b..a9bb14cf0 100644 --- a/tests/unit/events/test_forgejo.py +++ b/tests/unit/events/test_forgejo.py @@ -1,389 +1,60 @@ -# Copyright Contributors to the Packit project. -# SPDX-License-Identifier: MIT - import json - import pytest -from flexmock import flexmock -from ogr.services.forgejo import ForgejoProject -from packit_service.config import ServiceConfig -from packit_service.events.enums import ( - IssueCommentAction, - PullRequestAction, - PullRequestCommentAction, -) -from packit_service.events.forgejo import issue, pr, push -from packit_service.package_config_getter import PackageConfigGetter +from packit_service.events import forgejo +from packit_service.events.enums import PullRequestAction from packit_service.worker.parser import Parser from tests.spellbook import DATA_DIR -PATH_TO_FORGEJO_WEBHOOKS = DATA_DIR / "webhooks" / "forgejo" - - -@pytest.fixture() -def pull_request_opened(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "pr_opened.json") as outfile: - return json.load(outfile) - - -@pytest.fixture() -def pull_request_comment(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "pr_comment.json") as outfile: - return json.load(outfile) - - -@pytest.fixture() -def issue_comment(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "issue_comment.json") as outfile: - return json.load(outfile) - - -@pytest.fixture() -def push_new_branch(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "push_new_branch.json") as outfile: - return json.load(outfile) - - @pytest.fixture() -def tag_push(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "tag_push.json") as outfile: +def forgejo_push(): + with open(DATA_DIR / "fedmsg" / "forgejo_push.json") as outfile: return json.load(outfile) - @pytest.fixture() -def push_with_many_commit(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "push_with_many_commits.json") as outfile: +def forgejo_pr(): + with open(DATA_DIR / "fedmsg" / "forgejo_pr.json") as outfile: return json.load(outfile) - @pytest.fixture() -def push_with_one_commit(): - with open(PATH_TO_FORGEJO_WEBHOOKS / "push_with_one_commit.json") as outfile: +def forgejo_issue_comment(): + with open(DATA_DIR / "fedmsg" / "forgejo_issue_comment.json") as outfile: return json.load(outfile) - -def test_parse_forgejo_tag_push(tag_push): - mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(tag_push) - - assert isinstance(event_object, push.Commit) - assert event_object.repo_namespace == "packit" - assert event_object.repo_name == "test-repo-to-generate-events" - assert event_object.commit_sha == "9abc2644c3b9828db4bbe30c795b140c6c55089f" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.git_ref == "fifth" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert not event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=None, - reference="9abc2644c3b9828db4bbe30c795b140c6c55089f", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_pull_request(pull_request_opened): - mock_service = flexmock(get_project=lambda namespace, repo: flexmock()) - mock_project = flexmock( - full_repo_name="packit/test-repo-to-generate-events", service=mock_service - ) - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(pull_request_opened) - - assert isinstance(event_object, pr.Action) - assert event_object.action == PullRequestAction.opened - assert event_object.pr_id == 2 - assert event_object.base_repo_namespace == "mfocko" - assert event_object.base_repo_name == "test-repo-to-generate-events" - assert event_object.base_ref == "37182f59ccaaa21584e7b580442fd33b60fe3f80" - assert event_object.target_repo_namespace == "packit" - assert event_object.target_repo_name == "test-repo-to-generate-events" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.commit_sha == "37182f59ccaaa21584e7b580442fd33b60fe3f80" - assert event_object.actor == "mfocko" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=2, - reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_pull_request_comment(pull_request_comment): - mock_project = flexmock( - full_repo_name="packit/test-repo-to-generate-events", - get_pr=lambda pr_id: flexmock(head_commit="37182f59ccaaa21584e7b580442fd33b60fe3f80"), - service=flexmock(get_project=lambda namespace, repo: flexmock()), - ) - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(pull_request_comment) - - assert isinstance(event_object, pr.Comment) - assert event_object.action == PullRequestCommentAction.created - assert event_object.pr_id == 2 - assert event_object.base_repo_namespace == "mfocko" - assert event_object.base_repo_name == "test-repo-to-generate-events" - assert event_object.target_repo_namespace == "packit" - assert event_object.target_repo_name == "test-repo-to-generate-events" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.actor == "mfocko" - assert event_object.comment == "PR comment" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=2, - reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_issue_comment(issue_comment): - mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(issue_comment) - - assert isinstance(event_object, issue.Comment) - assert event_object.action == IssueCommentAction.created - assert event_object.issue_id == 1 - assert event_object.repo_namespace == "packit" - assert event_object.repo_name == "test-repo-to-generate-events" - assert event_object.target_repo == "packit/test-repo-to-generate-events" - assert event_object.base_ref == "main" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.actor == "mfocko" - assert event_object.comment == "issue comment" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert not event_object.base_project - - flexmock(event_object.project).should_receive("get_releases").and_return([]) - flexmock(ForgejoProject).should_receive("get_sha_from_tag").never() - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=None, - reference=None, - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - assert event_object.commit_sha is None - assert event_object.tag_name == "" - - -def test_parse_forgejo_push_many_commits(push_with_many_commit): - mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(push_with_many_commit) - - assert isinstance(event_object, push.Commit) - assert event_object.repo_namespace == "packit" - assert event_object.repo_name == "test-repo-to-generate-events" - assert event_object.commit_sha == "fa9bbf46c6ae89b755716683814b03b6a2c82263" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.git_ref == "main" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert not event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=None, - reference="fa9bbf46c6ae89b755716683814b03b6a2c82263", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_forgejo_push_new_branch(push_new_branch): - mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(push_new_branch) - - assert isinstance(event_object, push.Commit) - assert event_object.repo_namespace == "packit" - assert event_object.repo_name == "test-repo-to-generate-events" - assert event_object.commit_sha == "24f660b69e4608f63ddd55d5c5b459f348e5f272" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.git_ref == "new-branch" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert not event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=None, - reference="24f660b69e4608f63ddd55d5c5b459f348e5f272", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_forgejo_push_one_commit(push_with_one_commit): - mock_project = flexmock(full_repo_name="packit/test-repo-to-generate-events") - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - event_object = Parser.parse_event(push_with_one_commit) - - assert isinstance(event_object, push.Commit) - assert event_object.repo_namespace == "packit" - assert event_object.repo_name == "test-repo-to-generate-events" - assert event_object.commit_sha == "c85008a0b44a60370e48a45a9f9d39da5b472e11" - assert ( - event_object.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - assert event_object.git_ref == "main" - - assert event_object.project.full_repo_name == "packit/test-repo-to-generate-events" - assert not event_object.base_project - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=None, - reference="c85008a0b44a60370e48a45a9f9d39da5b472e11", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - assert event_object.packages_config - - -def test_parse_forgejo_pr_vs_issue_comment_discrimination(pull_request_comment, issue_comment): - """ - Test that the parser correctly discriminates between PR comments and issue comments. - In Forgejo, PRs are treated as special issues, so the parser needs to distinguish - between them based on the webhook payload structure. - """ - mock_project = flexmock( - full_repo_name="packit/test-repo-to-generate-events", - get_pr=lambda pr_id: flexmock(head_commit="37182f59ccaaa21584e7b580442fd33b60fe3f80"), - get_releases=list, - service=flexmock(get_project=lambda namespace, repo: flexmock()), - ) - flexmock(ServiceConfig).should_receive("get_project").and_return(mock_project) - - # Test PR comment parsing - pr_comment_event = Parser.parse_event(pull_request_comment) - - assert isinstance(pr_comment_event, pr.Comment) - assert pr_comment_event.action == PullRequestCommentAction.created - assert pr_comment_event.pr_id == 2 - assert pr_comment_event.comment == "PR comment" - assert pr_comment_event.actor == "mfocko" - - # Test issue comment parsing - issue_comment_event = Parser.parse_event(issue_comment) - - assert isinstance(issue_comment_event, issue.Comment) - assert issue_comment_event.action == IssueCommentAction.created - assert issue_comment_event.issue_id == 1 - assert issue_comment_event.comment == "issue comment" - assert issue_comment_event.actor == "mfocko" - - assert pr_comment_event.event_type() == "forgejo.pr.Comment" - assert issue_comment_event.event_type() == "forgejo.issue.Comment" - - assert pr_comment_event.project_url == issue_comment_event.project_url - assert ( - pr_comment_event.project_url - == "https://v10.next.forgejo.org/packit/test-repo-to-generate-events" - ) - - flexmock(ForgejoProject).should_receive("get_sha_from_tag").never() - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=pr_comment_event.base_project, - project=pr_comment_event.project, - pr_id=2, - reference="37182f59ccaaa21584e7b580442fd33b60fe3f80", - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo", - ).with_args( - base_project=issue_comment_event.base_project, - project=issue_comment_event.project, - pr_id=None, - reference=None, - fail_when_missing=False, - ).and_return( - flexmock(get_package_config_views=dict), - ).once() - - assert pr_comment_event.packages_config - assert issue_comment_event.packages_config +def test_parse_forgejo_push(forgejo_push): + event_object = Parser.parse_event(forgejo_push) + + assert isinstance(event_object, forgejo.push.Commit) + # the repo in the datagrepper payload is probably infra/docs or similar + payload = forgejo_push.get("body", {}) + assert event_object.repo_namespace == payload["repository"]["owner"]["login"] + assert event_object.repo_name == payload["repository"]["name"] + assert event_object.commit_sha == payload["after"] + assert event_object.commit_sha_before == payload["before"] + assert event_object.project_url == payload["repository"]["html_url"] + +def test_parse_forgejo_pr(forgejo_pr): + event_object = Parser.parse_event(forgejo_pr) + + if event_object is None: + # Datagrepper might have returned a PR action that is not "opened", "reopened", or "synchronize" + pytest.skip("Datagrepper returned an unsupported PR action for this test") + + assert isinstance(event_object, forgejo.pr.Action) + payload = forgejo_pr.get("body", {}) + assert event_object.action == PullRequestAction[payload["action"]] + assert event_object.pr_id == payload["pull_request"]["number"] + assert event_object.actor == payload["pull_request"]["user"]["login"] + +def test_parse_forgejo_issue_comment(forgejo_issue_comment): + event_object = Parser.parse_event(forgejo_issue_comment) + + payload = forgejo_issue_comment.get("body", {}) + if payload["issue"].get("pull_request") is not None: + assert isinstance(event_object, forgejo.pr.Comment) + assert event_object.pr_id == payload["issue"]["number"] + else: + assert isinstance(event_object, forgejo.issue.Comment) + assert event_object.issue_id == payload["issue"]["number"] + assert event_object.actor == payload["comment"]["user"]["login"] + assert event_object.comment == payload["comment"]["body"]