Skip to content

Commit

Permalink
Merge pull request #1796 from majamassarini/fix/packit-service/1536
Browse files Browse the repository at this point in the history
Retrigger koji and bodhi services by issue comment

Fixes #1536 #1747
Merge before packit/packit.dev#567

RELEASE NOTES BEGIN
Users can now re-trigger a Bodhi update or a Koji build writing comments like /packit create-update and /packit koji-update in a issue (opened by Packit in the repository issue if anything goes wrong during the propose-downstream)
RELEASE NOTES END

Reviewed-by: Tomas Tomecek <[email protected]>
Reviewed-by: Laura Barcziová <None>
Reviewed-by: Maja Massarini <None>
  • Loading branch information
softwarefactory-project-zuul[bot] authored Jan 17, 2023
2 parents 89af191 + 901f33f commit 2c5e73d
Show file tree
Hide file tree
Showing 31 changed files with 1,934 additions and 160 deletions.
6 changes: 3 additions & 3 deletions packit_service/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,17 +279,17 @@ def create_issue_if_needed(
) -> Optional[Issue]:
# TODO: Improve filtering
issues = project.get_issue_list()
title = f"[packit] {title}"
packit_title = f"[packit] {title}"

for issue in issues:
if title in issue.title:
if packit_title in issue.title or title in issue.title:
if comment_to_existing:
issue.comment(body=comment_to_existing)
logger.debug(f"Issue #{issue.id} updated: {issue.url}")
return None

# TODO: store in DB
issue = project.create_issue(title=title, body=message)
issue = project.create_issue(title=packit_title, body=message)
logger.debug(f"Issue #{issue.id} created: {issue.url}")
return issue

Expand Down
11 changes: 11 additions & 0 deletions packit_service/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
TESTING_FARM_INSTALLABILITY_TEST_URL = "https://gitlab.com/testing-farm/tests"
TESTING_FARM_INSTALLABILITY_TEST_REF = "main"

MSG_DOWNSTREAM_JOB_ERROR_HEADER = (
"Packit failed on creating {object} in dist-git "
"({dist_git_url}):\n\n"
"| dist-git branch | error |\n"
"| --------------- | ----- |\n"
)

MSG_GET_IN_TOUCH = (
f"\n\n---\n\n*Get in [touch with us]({CONTACTS_URL}) if you need some help.*"
)

MSG_RETRIGGER = (
"You can retrigger the {job} by adding a comment (`{packit_comment_command_prefix} {command}`) "
"into this {place}."
Expand Down
147 changes: 115 additions & 32 deletions packit_service/worker/checker/bodhi.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

from packit.config.aliases import get_branches

from packit_service.constants import KojiBuildState
from packit_service.constants import KojiBuildState, MSG_GET_IN_TOUCH

from packit_service.worker.checker.abstract import ActorChecker, Checker
from packit_service.worker.checker.abstract import (
ActorChecker,
Checker,
)
from packit_service.worker.handlers.mixin import (
GetKojiBuildData,
GetKojiBuildDataFromKojiBuildEventMixin,
Expand All @@ -18,6 +21,14 @@
ConfigFromEventMixin,
PackitAPIWithDownstreamMixin,
)
from packit_service.worker.events import (
PullRequestCommentPagureEvent,
IssueCommentEvent,
IssueCommentGitlabEvent,
)

from packit_service.worker.events.koji import KojiBuildEvent
from packit_service.worker.reporting import report_in_issue_repository

logger = logging.getLogger(__name__)

Expand All @@ -29,25 +40,32 @@ def pre_check(self) -> bool:
By default, we use `fedora-stable` alias.
(Rawhide updates are already created automatically.)
"""
if self.state != KojiBuildState.complete:
logger.debug(
f"Skipping build '{self.build_id}' "
f"on '{self.dist_git_branch}'. "
f"Build not finished yet."
)
return False

if self.dist_git_branch not in (
configured_branches := get_branches(
*(self.job_config.dist_git_branches or {"fedora-stable"}),
default_dg_branch="rawhide", # Koji calls it rawhide, not main
)
if self.data.event_type in (
PullRequestCommentPagureEvent.__name__,
KojiBuildEvent.__name__,
):
logger.info(
f"Skipping build on '{self.dist_git_branch}'. "
f"Bodhi update configured only for '{configured_branches}'."
)
return False
for koji_build_data in self:
if koji_build_data.state != KojiBuildState.complete:
logger.debug(
f"Skipping build '{koji_build_data.build_id}' "
f"on '{koji_build_data.dist_git_branch}'. "
f"Build not finished yet."
)
return False

if koji_build_data.dist_git_branch not in (
configured_branches := get_branches(
*(self.job_config.dist_git_branches or {"fedora-stable"}),
default_dg_branch="rawhide", # Koji calls it rawhide, not main
)
):
logger.info(
f"Skipping build on '{koji_build_data.dist_git_branch}'. "
f"Bodhi update configured only for '{configured_branches}'."
)
return False

return True


Expand All @@ -65,27 +83,92 @@ class IsKojiBuildCompleteAndBranchConfiguredCheckService(
...


class HasAuthorWriteAccess(ActorChecker, ConfigFromEventMixin):
class HasIssueCommenterRetriggeringPermissions(ActorChecker, ConfigFromEventMixin):
"""To be able to retrigger a Bodhi update the issue commenter should
have write permission on the project.
"""

def _pre_check(self) -> bool:
if not self.project.has_write_access(user=self.actor):
logger.info(
f"Re-triggering Bodhi update via dist-git comment in PR#{self.data.pr_id}"
f" and project {self.project.repo} is not allowed for the user: {self.actor}."
has_write_access = self.project.has_write_access(user=self.actor)
if self.data.event_type in (
IssueCommentEvent.__name__,
IssueCommentGitlabEvent.__name__,
):
logger.debug(
f"Re-triggering Bodhi update through comment in "
f"repo {self.project_url} and issue {self.data.issue_id} "
f"by {self.actor}."
)
return False
if not has_write_access:
msg = (
f"Re-triggering Bodhi update through comment in "
f"repo **{self.project_url}** and issue **{self.data.issue_id}** "
f"is not allowed for the user *{self.actor}* "
f"which has not write permissions on the project."
)
logger.info(msg)
issue = self.project.get_issue(self.data.issue_id)
report_in_issue_repository(
issue_repository=self.job_config.issue_repository,
service_config=self.service_config,
title=issue.title,
message=msg + MSG_GET_IN_TOUCH,
comment_to_existing=msg,
)
return False

return True
if self.data.event_type in (PullRequestCommentPagureEvent.__name__,):

logger.debug(
f"Re-triggering Bodhi update via dist-git comment in "
f"repo {self.project_url} and #PR {self.data.pr_id} "
f"by {self.actor}."
)
if not has_write_access:
msg = (
f"Re-triggering Bodhi update via dist-git comment in "
f"**PR#{self.data.pr_id}** and project **{self.project.repo}** "
f"is not allowed for the user *{self.actor}* "
f"which has not write permissions on the project."
)
logger.info(msg)
title = "Re-triggering Bodhi update through comment in issue failed"
report_in_issue_repository(
issue_repository=self.job_config.issue_repository,
service_config=self.service_config,
title=title,
message=msg + MSG_GET_IN_TOUCH,
comment_to_existing=msg,
)
return False

return True

return True


class IsAuthorAPackager(ActorChecker, PackitAPIWithDownstreamMixin):
def _pre_check(self) -> bool:

if not self.is_packager(user=self.actor):
logger.info(
f"Re-triggering Bodhi update via dist-git comment in PR#{self.data.pr_id}"
f" and project {self.project.repo} is not allowed, user {self.actor} "
"is not a packager."
)
return False
if self.data.event_type in (PullRequestCommentPagureEvent.__name__,):
if not self.is_packager(user=self.actor):
title = (
"Re-triggering Bodhi update through dist-git comment in PR failed"
)
msg = (
f"Re-triggering Bodhi update via dist-git comment in **PR#{self.data.pr_id}**"
f" and project **{self.project_url}** is not allowed, user *{self.actor}* "
"is not a packager."
)
logger.info(msg)
report_in_issue_repository(
issue_repository=self.job_config.issue_repository,
service_config=self.service_config,
title=title,
message=msg + MSG_GET_IN_TOUCH,
comment_to_existing=msg,
)
return False

return True
62 changes: 59 additions & 3 deletions packit_service/worker/checker/distgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

from packit.config.aliases import get_branches

from packit_service.worker.checker.abstract import Checker
from packit_service.constants import MSG_GET_IN_TOUCH

from packit_service.worker.checker.abstract import Checker, ActorChecker
from packit_service.worker.events import (
PushPagureEvent,
IssueCommentEvent,
IssueCommentGitlabEvent,
)
from packit_service.worker.events.pagure import PullRequestCommentPagureEvent
from packit_service.worker.handlers.mixin import GetProjectToSyncMixin
Expand Down Expand Up @@ -61,15 +65,67 @@ def pre_check(self) -> bool:
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} "
msg = (
f"koji-build retriggering through comment "
f"on PR identifier {self.data.pr_id} "
f"and project {self.data.project_url} "
f"done by {commenter} which is not a packager."
)
logger.info(msg)
report_in_issue_repository(
issue_repository=self.job_config.issue_repository,
service_config=self.service_config,
title=(
"Re-triggering downstream koji build "
"through comment in dist-git PR failed"
),
message=msg + MSG_GET_IN_TOUCH,
comment_to_existing=msg,
)
return False

return True


class HasIssueCommenterRetriggeringPermissions(ActorChecker):
"""To be able to retrigger a koji-build the issue commenter should
have write permission on the project.
"""

def _pre_check(self) -> bool:
if self.data.event_type in (
IssueCommentEvent.__name__,
IssueCommentGitlabEvent.__name__,
):
logger.debug(
f"Re-triggering downstream koji-build through comment in "
f"repo {self.project.repo} and issue {self.data.issue_id} "
f"by {self.actor}."
)
if not self.project.has_write_access(user=self.actor):
msg = (
f"Re-triggering downstream koji-build through comment in "
f"repo **{self.project_url}** and issue **{self.data.issue_id}** "
f"is not allowed for the user *{self.actor}* "
f"which has not write permissions on the project."
)
logger.info(msg)
issue = self.project.get_issue(self.data.issue_id)
report_in_issue_repository(
issue_repository=self.job_config.issue_repository,
service_config=self.service_config,
title=issue.title,
message=msg + MSG_GET_IN_TOUCH,
comment_to_existing=msg,
)

return False

return True

return True


class IsProjectOk(Checker, GetProjectToSyncMixin):
def pre_check(self) -> bool:
return self.project_to_sync is not None
Expand Down
4 changes: 4 additions & 0 deletions packit_service/worker/events/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def __init__(
comment_id: int,
tag_name: str = "",
comment_object: Optional[Comment] = None,
dist_git_project_url=None,
) -> None:
super().__init__(
project_url=project_url,
Expand All @@ -141,6 +142,9 @@ def __init__(
self.repo_namespace = repo_namespace
self.repo_name = repo_name

# issue description link to dist-git
self.dist_git_project_url = dist_git_project_url

# Lazy properties
self._tag_name = tag_name
self._commit_sha: Optional[str] = None
Expand Down
2 changes: 2 additions & 0 deletions packit_service/worker/events/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def __init__(
str
] = "master", # default is master when working with issues
comment_object: Optional[Comment] = None,
dist_git_project_url=None,
) -> None:
super().__init__(
issue_id=issue_id,
Expand All @@ -189,6 +190,7 @@ def __init__(
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
Expand Down
2 changes: 2 additions & 0 deletions packit_service/worker/events/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def __init__(
comment_id: int,
tag_name: str = "",
comment_object: Optional[Comment] = None,
dist_git_project_url=None,
):
super().__init__(
issue_id=issue_id,
Expand All @@ -167,6 +168,7 @@ def __init__(
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
Expand Down
6 changes: 4 additions & 2 deletions packit_service/worker/handlers/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from packit_service.worker.checker.abstract import Checker

from packit_service.worker.mixin import (
ConfigFromEventMixin,
Config,
PackitAPIWithDownstreamMixin,
)

Expand Down Expand Up @@ -205,19 +205,21 @@ class TaskName(str, enum.Enum):
upstream_koji_build = "task.run_koji_build_handler"
upstream_koji_build_report = "task.run_koji_build_report_handler"
downstream_koji_build = "task.run_downstream_koji_build_handler"
retrigger_downstream_koji_build = "task.run_retrigger_downstream_koji_build_handler"
downstream_koji_build_report = "task.run_downstream_koji_build_report_handler"
# Fedora notification is ok for now
# downstream_koji_build_report = "task.run_downstream_koji_build_report_handler"
sync_from_downstream = "task.run_sync_from_downstream_handler"
bodhi_update = "task.bodhi_update"
retrigger_bodhi_update = "task.retrigger_bodhi_update"
issue_comment_retrigger_bodhi_update = "task.issue_comment_retrigger_bodhi_update"
github_fas_verification = "task.github_fas_verification"
vm_image_build = "task.run_vm_image_build_handler"
vm_image_build_result = "task.run_vm_image_build_result_handler"
pull_from_upstream = "pull_from_upstream"


class Handler(ConfigFromEventMixin, PackitAPIWithDownstreamMixin):
class Handler(PackitAPIWithDownstreamMixin, Config):
def run(self) -> TaskResults:
raise NotImplementedError("This should have been implemented.")

Expand Down
Loading

0 comments on commit 2c5e73d

Please sign in to comment.