diff --git a/packit_service/worker/events/pagure.py b/packit_service/worker/events/pagure.py index 31decfa0a4..3edf6073da 100644 --- a/packit_service/worker/events/pagure.py +++ b/packit_service/worker/events/pagure.py @@ -90,11 +90,17 @@ def get_dict(self, default_dict: Optional[Dict] = None) -> dict: return result def get_base_project(self) -> GitProject: + if isinstance(self, PullRequestCommentPagureEvent): + # Do not force project to work with a fork + # we should have all the data to know if it is a fork or not + is_fork = False + else: + is_fork = True fork = self.project.service.get_project( namespace=self.base_repo_namespace, repo=self.base_repo_name, username=self.base_repo_owner, - is_fork=True, + is_fork=is_fork, ) logger.debug(f"Base project: {fork} owned by {self.base_repo_owner}") return fork diff --git a/packit_service/worker/handlers/distgit.py b/packit_service/worker/handlers/distgit.py index f94c48ca06..d2201cb112 100644 --- a/packit_service/worker/handlers/distgit.py +++ b/packit_service/worker/handlers/distgit.py @@ -41,6 +41,7 @@ ReleaseEvent, AbstractIssueCommentEvent, CheckRerunReleaseEvent, + PullRequestCommentPagureEvent, ) from packit_service.worker.handlers.abstract import ( JobHandler, @@ -381,7 +382,9 @@ def run(self) -> TaskResults: @configured_as(job_type=JobType.koji_build) +@run_for_comment(command="koji-build") @reacts_to(event=PushPagureEvent) +@reacts_to(event=PullRequestCommentPagureEvent) class DownstreamKojiBuildHandler(JobHandler): """ This handler can submit a build in Koji from a dist-git. @@ -461,6 +464,19 @@ def pre_check(self) -> bool: f"configuration: {self.job_config.allowed_committers}." ) return False + elif self.data.event_type in (PullRequestCommentPagureEvent.__name__,): + commenter = self.data.actor + project_url = self.data.event_dict["project_url"] + logger.debug( + f"Triggering downstream koji build through comment by: {commenter}" + ) + if commenter not in self.job_config.allowed_committers: + logger.info( + f"Comment event on PR identifier {self.data.pr_id} done by {commenter}" + f"not allowed to trigger koji builds for commits on project {project_url}.\n" + f"Configuration allowed committers: {self.job_config.allowed_committers}." + ) + # return False return True @@ -480,9 +496,14 @@ def run(self) -> TaskResults: self.job_config, downstream_local_project=self.local_project, ) + branch = ( + self.project.get_pr(self.data.pr_id).source_branch + if self.data.event_type in (PullRequestCommentPagureEvent.__name__,) + else self.dg_branch + ) try: packit_api.build( - dist_git_branch=self.dg_branch, + dist_git_branch=branch, scratch=self.job_config.scratch, nowait=True, from_upstream=False, @@ -512,12 +533,7 @@ def run(self) -> TaskResults: issue_repo = self.service_config.get_project( url=self.job_config.issue_repository ) - body = ( - f"Koji build on `{self.dg_branch}` branch failed:\n" - "```\n" - f"{ex}\n" - "```" - ) + body = f"Koji build on `{branch}` branch failed:\n" "```\n" f"{ex}\n" "```" PackageConfigGetter.create_issue_if_needed( project=issue_repo, title="Fedora Koji build failed to be triggered", diff --git a/packit_service/worker/jobs.py b/packit_service/worker/jobs.py index 4bffbf42d6..a9d21e9c30 100644 --- a/packit_service/worker/jobs.py +++ b/packit_service/worker/jobs.py @@ -12,7 +12,7 @@ import celery from ogr.exceptions import GithubAppNotInstalledError -from packit.config import JobConfig +from packit.config import JobConfig, JobType, JobConfigTriggerType from packit_service.config import ServiceConfig from packit_service.constants import ( TASK_ACCEPTED, @@ -406,13 +406,13 @@ def should_task_be_created_for_job_config_and_handler( Returns: Whether the task should be created. """ - if self.service_config.deployment not in job_config.packit_instances: - logger.debug( - f"Current deployment ({self.service_config.deployment}) " - f"does not match the job configuration ({job_config.packit_instances}). " - "The job will not be run." - ) - return False + # if self.service_config.deployment not in job_config.packit_instances: + # logger.debug( + # f"Current deployment ({self.service_config.deployment}) " + # f"does not match the job configuration ({job_config.packit_instances}). " + # "The job will not be run." + # ) + # return False handler = handler_kls( package_config=self.event.package_config, @@ -483,6 +483,18 @@ def get_jobs_matching_event(self) -> List[JobConfig]: ): jobs_matching_trigger.append(job) + if not jobs_matching_trigger and isinstance( + self.event, PullRequestCommentPagureEvent + ): + if ( + job.type == JobType.koji_build + and job.trigger == JobConfigTriggerType.commit + and self.event.job_config_trigger_type + == JobConfigTriggerType.pull_request + ): + "A koji_build can be retriggered by a Pagure comment in a PR" + jobs_matching_trigger.append(job) + return jobs_matching_trigger def get_handlers_for_comment_and_rerun_event(self) -> Set[Type[JobHandler]]: diff --git a/packit_service/worker/parser.py b/packit_service/worker/parser.py index 26b8e592ce..f975dc04ca 100644 --- a/packit_service/worker/parser.py +++ b/packit_service/worker/parser.py @@ -93,6 +93,7 @@ def parse_event( PushGitlabEvent, PipelineGitlabEvent, PullRequestFlagPagureEvent, + PullRequestCommentPagureEvent, PushPagureEvent, CheckRerunCommitEvent, CheckRerunPullRequestEvent, @@ -136,6 +137,7 @@ def parse_event( Parser.parse_gitlab_push_event, Parser.parse_pipeline_event, Parser.parse_pagure_pr_flag_event, + Parser.parse_pagure_pull_request_comment_event, ), ): if response: @@ -1249,6 +1251,47 @@ def parse_pagure_pr_flag_event(event) -> Optional[PullRequestFlagPagureEvent]: project_namespace=project_namespace, ) + @staticmethod + def parse_pagure_pull_request_comment_event( + event, + ) -> Optional[PullRequestCommentPagureEvent]: + if ".pagure.pull-request.comment." not in (topic := event.get("topic", "")): + return None + logger.info(f"Pagure PR comment event, topic: {topic}") + + action = PullRequestCommentAction.created.value + pr_id = event["pullrequest"]["id"] + base_repo_namespace = event["pullrequest"]["project"]["namespace"] + base_repo_name = event["pullrequest"]["project"]["name"] + base_repo_owner = event["pullrequest"]["repo_from"]["user"]["name"] + target_repo = event["pullrequest"]["repo_from"]["name"] + https_url = event["pullrequest"]["project"]["full_url"] + pagure_login = event["agent"] + commit_sha = event["pullrequest"]["commit_stop"] + + if "added" in event["topic"]: + comment = event["pullrequest"]["comments"][-1]["comment"] + comment_id = event["pullrequest"]["comments"][-1]["id"] + else: + raise ValueError( + f"Unknown comment location in response for {event['topic']}" + ) + + return PullRequestCommentPagureEvent( + action=PullRequestCommentAction[action], + pr_id=pr_id, + base_repo_namespace=base_repo_namespace, + base_repo_name=base_repo_name, + base_repo_owner=base_repo_owner, + base_ref=None, + target_repo=target_repo, + project_url=https_url, + commit_sha=commit_sha, + user_login=pagure_login, + comment=comment, + comment_id=comment_id, + ) + # TODO: Currently not used, merge in Parser or remove # https://github.com/packit/deployment/issues/225 diff --git a/tests/data/fedmsg/pagure_pr_comment.json b/tests/data/fedmsg/pagure_pr_comment.json new file mode 100644 index 0000000000..d845a0d132 --- /dev/null +++ b/tests/data/fedmsg/pagure_pr_comment.json @@ -0,0 +1,127 @@ +{ + "agent": "mmassari", + "pullrequest": { + "assignee": null, + "branch": "test-koji-downstream", + "branch_from": "test-koji-downstream-2", + "cached_merge_status": "FFORWARD", + "closed_at": null, + "closed_by": null, + "comments": [ + { + "comment": "/packit koji-build", + "commit": null, + "date_created": "1657783448", + "edited_on": null, + "editor": null, + "filename": null, + "id": 110401, + "line": null, + "notification": false, + "parent": null, + "reactions": {}, + "tree": null, + "user": { + "full_url": "https://src.fedoraproject.org/user/mmassari", + "fullname": "Maja Massarini", + "name": "mmassari", + "url_path": "user/mmassari" + } + } + ], + "commit_start": "beaf90bcecc51968a46663f8d6f092bfdc92e682", + "commit_stop": "beaf90bcecc51968a46663f8d6f092bfdc92e682", + "date_created": "1657783415", + "full_url": "https://src.fedoraproject.org/rpms/python-teamcity-messages/pull-request/36", + "id": 36, + "initial_comment": null, + "last_updated": "1657783448", + "project": { + "access_groups": { + "admin": [], + "collaborator": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": ["limb"], + "collaborator": [], + "commit": [], + "owner": ["mmassari"], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1643654065", + "date_modified": "1650542166", + "description": "The python-teamcity-messages package\\n", + "full_url": "https://src.fedoraproject.org/rpms/python-teamcity-messages", + "fullname": "rpms/python-teamcity-messages", + "id": 54766, + "milestones": {}, + "name": "python-teamcity-messages", + "namespace": "rpms", + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "rpms/python-teamcity-messages", + "user": { + "full_url": "https://src.fedoraproject.org/user/mmassari", + "fullname": "Maja Massarini", + "name": "mmassari", + "url_path": "user/mmassari" + } + }, + "remote_git": null, + "repo_from": { + "access_groups": { + "admin": [], + "collaborator": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": ["limb"], + "collaborator": [], + "commit": [], + "owner": ["mmassari"], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1643654065", + "date_modified": "1650542166", + "description": "The python-teamcity-messages package\\n", + "full_url": "https://src.fedoraproject.org/rpms/python-teamcity-messages", + "fullname": "rpms/python-teamcity-messages", + "id": 54766, + "milestones": {}, + "name": "python-teamcity-messages", + "namespace": "rpms", + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "rpms/python-teamcity-messages", + "user": { + "full_url": "https://src.fedoraproject.org/user/mmassari", + "fullname": "Maja Massarini", + "name": "mmassari", + "url_path": "user/mmassari" + } + }, + "status": "Open", + "tags": [], + "threshold_reached": null, + "title": "Not usefull commit", + "uid": "d8b1dd625c674cb9ad8010985bd98351", + "updated_on": "1657783448", + "user": { + "full_url": "https://src.fedoraproject.org/user/mmassari", + "fullname": "Maja Massarini", + "name": "mmassari", + "url_path": "user/mmassari" + } + }, + "topic": "org.fedoraproject.prod.pagure.pull-request.comment.added", + "timestamp": 1657776351.055628 +} diff --git a/tests/unit/test_events.py b/tests/unit/test_events.py index c592146e18..062ac9d6ba 100644 --- a/tests/unit/test_events.py +++ b/tests/unit/test_events.py @@ -192,6 +192,11 @@ def pagure_pr_flag_updated(self): with open(DATA_DIR / "fedmsg" / "pagure_pr_flag_updated.json") as outfile: return json.load(outfile) + @pytest.fixture() + def pagure_pr_comment_added(self): + with open(DATA_DIR / "fedmsg" / "pagure_pr_comment.json") as outfile: + return json.load(outfile) + @pytest.fixture() def distgit_commit(self): with open(DATA_DIR / "fedmsg" / "distgit_commit.json") as outfile: @@ -772,6 +777,47 @@ def test_parse_pagure_flag(self, pagure_pr_flag_updated): assert event_object.project_name == "packit" assert event_object.project_namespace == "rpms" + def test_parse_pagure_pull_request_comment(self, pagure_pr_comment_added): + event_object = Parser.parse_event(pagure_pr_comment_added) + + assert isinstance(event_object, PullRequestCommentPagureEvent) + assert event_object.pr_id == 36 + assert event_object.base_repo_namespace == "rpms" + assert event_object.base_repo_name == "python-teamcity-messages" + assert event_object.base_repo_owner == "mmassari" + assert event_object.base_ref is None + assert event_object.target_repo == "python-teamcity-messages" + assert event_object.commit_sha == "beaf90bcecc51968a46663f8d6f092bfdc92e682" + assert event_object.user_login == "mmassari" + assert event_object.comment == "/packit koji-build" + assert ( + event_object.project_url + == "https://src.fedoraproject.org/rpms/python-teamcity-messages" + ) + + assert isinstance(event_object.project, PagureProject) + assert event_object.project.full_repo_name == "rpms/python-teamcity-messages" + assert isinstance(event_object.base_project, PagureProject) + assert ( + event_object.base_project.full_repo_name == "rpms/python-teamcity-messages" + ) + + flexmock(PackageConfigGetter).should_receive( + "get_package_config_from_repo" + ).with_args( + base_project=event_object.base_project, + project=event_object.project, + pr_id=36, + reference="beaf90bcecc51968a46663f8d6f092bfdc92e682", + fail_when_missing=False, + ).and_return( + flexmock() + ).once() + flexmock(PagureProject).should_receive("get_web_url").and_return( + "https://src.fedoraproject.org/rpms/python-teamcity-messages" + ) + assert event_object.package_config + @pytest.mark.parametrize("identifier", [None, "foo"]) def test_parse_testing_farm_notification( self, testing_farm_notification, testing_farm_results, identifier @@ -1616,49 +1662,6 @@ def test_update_pull_request_event(self, pagure_pr_update): ) assert event_object.package_config - def test_pull_request_comment_event(self, pagure_pr_comment_added): - centos_event_parser = CentosEventParser() - event_object = centos_event_parser.parse_event(pagure_pr_comment_added) - - assert isinstance(event_object, PullRequestCommentPagureEvent) - assert event_object.pr_id == 16 - assert event_object.base_repo_namespace == "source-git" - assert event_object.base_repo_name == "packit-hello-world" - assert event_object.base_repo_owner == "sakalosj" - assert event_object.base_ref is None - assert event_object.target_repo == "packit-hello-world" - assert event_object.commit_sha == "dfe787d04101728c6ddc213d3f4bf39c969f194c" - assert event_object.user_login == "sakalosj" - assert event_object.comment == "/packit copr-build" - assert ( - event_object.project_url - == "https://git.stg.centos.org/source-git/packit-hello-world" - ) - - assert isinstance(event_object.project, PagureProject) - assert event_object.project.full_repo_name == "source-git/packit-hello-world" - assert isinstance(event_object.base_project, PagureProject) - assert ( - event_object.base_project.full_repo_name - == "fork/sakalosj/source-git/packit-hello-world" - ) - - flexmock(PackageConfigGetter).should_receive( - "get_package_config_from_repo" - ).with_args( - base_project=event_object.base_project, - project=event_object.project, - pr_id=16, - reference="dfe787d04101728c6ddc213d3f4bf39c969f194c", - fail_when_missing=False, - ).and_return( - flexmock() - ).once() - flexmock(PagureProject).should_receive("get_web_url").and_return( - "https://git.stg.centos.org/source-git/packit-hello-world" - ) - assert event_object.package_config - def test_parse_copr_build_event_start( self, copr_build_results_start, copr_build_centos_pr ):