Skip to content

Commit

Permalink
Retrigger downstream koji builds
Browse files Browse the repository at this point in the history
Through Pagure comments on PR
  • Loading branch information
majamassarini committed Jul 25, 2022
1 parent 55ac1f6 commit 5bb916f
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 62 deletions.
8 changes: 4 additions & 4 deletions packit_service/worker/events/pagure.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ def get_dict(self, default_dict: Optional[Dict] = None) -> dict:
return result

def get_base_project(self) -> GitProject:
fork = self.project.service.get_project(
project = 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=False,
)
logger.debug(f"Base project: {fork} owned by {self.base_repo_owner}")
return fork
logger.debug(f"Base project: {project} owned by {self.base_repo_owner}")
return project


class PullRequestPagureEvent(AddPullRequestDbTrigger, AbstractPagureEvent):
Expand Down
65 changes: 53 additions & 12 deletions packit_service/worker/handlers/distgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from datetime import datetime
from typing import Optional, Dict

from fasjson_client import Client
from fasjson_client.errors import APIError
from ogr.abstract import PullRequest, PRStatus

from packit.api import PackitAPI
Expand All @@ -23,6 +25,7 @@
from packit_service.config import PackageConfigGetter, ProjectToSync
from packit_service.constants import (
CONTACTS_URL,
FASJSON_URL,
FILE_DOWNLOAD_FAILURE,
MSG_RETRIGGER,
)
Expand All @@ -39,6 +42,7 @@
ReleaseEvent,
AbstractIssueCommentEvent,
CheckRerunReleaseEvent,
PullRequestCommentPagureEvent,
)
from packit_service.worker.handlers.abstract import (
JobHandler,
Expand Down Expand Up @@ -380,7 +384,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(RetriableJobHandler):
"""
This handler can submit a build in Koji from a dist-git.
Expand All @@ -404,6 +410,7 @@ def __init__(
)
self.dg_branch = event.get("git_ref")
self._pull_request: Optional[PullRequest] = None
self._packit_api = None

@property
def pull_request(self):
Expand All @@ -421,10 +428,38 @@ def pull_request(self):
self._pull_request = prs[0]
return self._pull_request

@property
def packit_api(self):
if not self._packit_api:
self._packit_api = PackitAPI(
self.service_config,
self.job_config,
downstream_local_project=self.local_project,
)
return self._packit_api

def get_pr_author(self):
"""Get the login of the author of the PR (if there is any corresponding PR)."""
return self.pull_request.author if self.pull_request else None

def is_packager(self, user):
"""Check that the given FAS user
is a packager
Args:
user (str) FAS user account name
Returns:
true if a packager false otherwise
"""
self.packit_api.init_kerberos_ticket()
client = Client(FASJSON_URL)
try:
groups = client.list_user_groups(username=user)
except APIError:
logger.debug(f"Unable to get groups for user {user}.")
return False
return "packager" in [group["groupname"] for group in groups.result]

def pre_check(self) -> bool:
if self.data.event_type in (PushPagureEvent.__name__,):
if self.data.git_ref not in (
Expand Down Expand Up @@ -460,6 +495,17 @@ 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
logger.debug(
f"Triggering downstream koji build through comment by: {commenter}"
)
if not self.is_packager(commenter):
logger.info(
f"koji-build retrigger comment event on PR identifier {self.data.pr_id} "
f"done by {commenter} which is not a packager."
)
return False

return True

Expand All @@ -474,14 +520,14 @@ def run(self) -> TaskResults:
if self.service_config.repository_cache
else None,
)
packit_api = PackitAPI(
self.service_config,
self.job_config,
downstream_local_project=self.local_project,
branch = (
self.project.get_pr(self.data.pr_id).target_branch
if self.data.event_type in (PullRequestCommentPagureEvent.__name__,)
else self.dg_branch
)
try:
packit_api.build(
dist_git_branch=self.dg_branch,
self.packit_api.build(
dist_git_branch=branch,
scratch=self.job_config.scratch,
nowait=True,
from_upstream=False,
Expand Down Expand Up @@ -509,12 +555,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",
Expand Down
26 changes: 25 additions & 1 deletion packit_service/worker/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -469,6 +469,27 @@ def is_project_public_or_enabled_private(self) -> bool:

return True

def check_explicit_matching(self):
"""Force explicit event/jobs matching for triggers
Returns:
list of jobs
"""
matching_jobs = []
if isinstance(self.event, PullRequestCommentPagureEvent):
for job in self.event.package_config.jobs:
if (
job.type == JobType.koji_build
and job.trigger == JobConfigTriggerType.commit
and self.event.job_config_trigger_type
== JobConfigTriggerType.pull_request
):
# A koji_build job with comment trigger
# can be re-triggered by a Pagure comment in a PR
matching_jobs.append(job)

return matching_jobs

def get_jobs_matching_event(self) -> List[JobConfig]:
"""
Get list of non-duplicated all jobs that matches with event's trigger.
Expand All @@ -481,6 +502,9 @@ def get_jobs_matching_event(self) -> List[JobConfig]:
):
jobs_matching_trigger.append(job)

if not jobs_matching_trigger:
jobs_matching_trigger.extend(self.check_explicit_matching())

return jobs_matching_trigger

def get_handlers_for_comment_and_rerun_event(self) -> Set[Type[JobHandler]]:
Expand Down
43 changes: 43 additions & 0 deletions packit_service/worker/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def parse_event(
PushGitlabEvent,
PipelineGitlabEvent,
PullRequestFlagPagureEvent,
PullRequestCommentPagureEvent,
PushPagureEvent,
CheckRerunCommitEvent,
CheckRerunPullRequestEvent,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
127 changes: 127 additions & 0 deletions tests/data/fedmsg/pagure_pr_comment.json
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit 5bb916f

Please sign in to comment.