-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retrigger bodhi update via dist-git PR comment #1654
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -6,16 +6,19 @@ | |||
""" | ||||
import logging | ||||
from typing import Optional | ||||
from dataclasses import dataclass | ||||
|
||||
from celery import Task | ||||
from fedora.client import AuthError | ||||
from koji import ClientSession | ||||
|
||||
from packit.constants import DEFAULT_BODHI_NOTE | ||||
from packit.constants import DEFAULT_BODHI_NOTE, KOJI_BASEURL | ||||
|
||||
from packit.exceptions import PackitException | ||||
|
||||
from packit.api import PackitAPI | ||||
from packit.config.aliases import get_branches | ||||
from packit.distgit import DistGit | ||||
|
||||
from packit.config import JobConfig, JobType, PackageConfig | ||||
from packit.local_project import LocalProject | ||||
|
@@ -26,19 +29,31 @@ | |||
KojiBuildState, | ||||
RETRY_INTERVAL_IN_MINUTES_WHEN_USER_ACTION_IS_NEEDED, | ||||
) | ||||
from packit_service.worker.events import PullRequestCommentPagureEvent | ||||
from packit_service.worker.events.koji import KojiBuildEvent | ||||
from packit_service.worker.handlers.abstract import ( | ||||
TaskName, | ||||
configured_as, | ||||
reacts_to, | ||||
RetriableJobHandler, | ||||
run_for_comment, | ||||
) | ||||
from packit_service.worker.result import TaskResults | ||||
|
||||
logger = logging.getLogger(__name__) | ||||
|
||||
|
||||
@dataclass | ||||
class KojiBuildEventWrapper: | ||||
build_id: int | ||||
state: KojiBuildState | ||||
dist_git_branch: str | ||||
nvr: str | ||||
|
||||
|
||||
@configured_as(job_type=JobType.bodhi_update) | ||||
@run_for_comment(command="create-update") | ||||
@reacts_to(event=PullRequestCommentPagureEvent) | ||||
@reacts_to(event=KojiBuildEvent) | ||||
class CreateBodhiUpdateHandler(RetriableJobHandler): | ||||
""" | ||||
|
@@ -63,15 +78,92 @@ def __init__( | |||
) | ||||
|
||||
# lazy properties | ||||
self._koji_build_event: Optional[KojiBuildEvent] = None | ||||
self._koji_build_event_data: Optional[KojiBuildEventWrapper] = None | ||||
self._packit_api: Optional[PackitAPI] = None | ||||
self._local_project: Optional[LocalProject] = None | ||||
|
||||
def _build_from_event_dict(self) -> KojiBuildEventWrapper: | ||||
koji_build_event = KojiBuildEvent.from_event_dict(self.data.event_dict) | ||||
return KojiBuildEventWrapper( | ||||
build_id=koji_build_event.build_id, | ||||
state=koji_build_event.state, | ||||
dist_git_branch=koji_build_event.git_ref, | ||||
nvr=koji_build_event.nvr, | ||||
) | ||||
|
||||
def _build_from_koji_api(self) -> KojiBuildEventWrapper: | ||||
dist_git_branch = self.project.get_pr(self.data.pr_id).target_branch | ||||
nvr = DistGit.get_latest_build_in_tag( | ||||
downstream_package_name=self.project.repo, dist_git_branch=dist_git_branch | ||||
) | ||||
|
||||
session = ClientSession(baseurl=KOJI_BASEURL) | ||||
build = session.getBuild(buildInfo=nvr) | ||||
return KojiBuildEventWrapper( | ||||
build_id=build["build_id"], | ||||
state=KojiBuildState.from_number(build["state"]), | ||||
dist_git_branch=dist_git_branch, | ||||
nvr=nvr, | ||||
) | ||||
|
||||
def _build_koji_event_data(self) -> KojiBuildEventWrapper: | ||||
if self.data.event_type == PullRequestCommentPagureEvent.__name__: | ||||
return self._build_from_koji_api() | ||||
|
||||
return self._build_from_event_dict() | ||||
|
||||
@property | ||||
def koji_build_event(self): | ||||
if not self._koji_build_event: | ||||
self._koji_build_event = KojiBuildEvent.from_event_dict( | ||||
self.data.event_dict | ||||
def koji_build_event_data(self) -> Optional[KojiBuildEventWrapper]: | ||||
if self._koji_build_event_data is None: | ||||
self._koji_build_event_data = self._build_koji_event_data() | ||||
|
||||
return self._koji_build_event_data | ||||
|
||||
@property | ||||
def packit_api(self) -> Optional[PackitAPI]: | ||||
if self._packit_api is None: | ||||
self._packit_api = PackitAPI( | ||||
self.service_config, | ||||
self.job_config, | ||||
downstream_local_project=self.local_project, | ||||
) | ||||
|
||||
return self._packit_api | ||||
|
||||
@property | ||||
def local_project(self) -> LocalProject: | ||||
if self._local_project is None: | ||||
self._local_project = LocalProject( | ||||
git_project=self.project, | ||||
working_dir=self.service_config.command_handler_work_dir, | ||||
cache=RepositoryCache( | ||||
cache_path=self.service_config.repository_cache, | ||||
add_new=self.service_config.add_repositories_to_repository_cache, | ||||
) | ||||
if self.service_config.repository_cache | ||||
else None, | ||||
) | ||||
|
||||
return self._local_project | ||||
|
||||
def _write_access_to_dist_git_repo_is_not_needed_or_satisfied(self) -> bool: | ||||
if self.data.event_type != PullRequestCommentPagureEvent.__name__: | ||||
# not needed | ||||
return True | ||||
|
||||
user = self.data.actor | ||||
logger.debug( | ||||
f"Bodhi update will be re-triggered via dist-git PR comment by user {user}." | ||||
) | ||||
|
||||
if not self.project.has_write_access(user=user): | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we just discussed with Franta and Tomas that here we should check both whether the user is a packager and has write access to the repo, so here we need to call the
|
||||
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: {user}." | ||||
) | ||||
return self._koji_build_event | ||||
return False | ||||
|
||||
return True | ||||
|
||||
def pre_check(self) -> bool: | ||||
""" | ||||
|
@@ -80,15 +172,15 @@ def pre_check(self) -> bool: | |||
By default, we use `fedora-stable` alias. | ||||
(Rawhide updates are already created automatically.) | ||||
""" | ||||
if self.koji_build_event.state != KojiBuildState.complete: | ||||
if self.koji_build_event_data.state != KojiBuildState.complete: | ||||
logger.debug( | ||||
f"Skipping build '{self.koji_build_event.build_id}' " | ||||
f"on '{self.koji_build_event.git_ref}'. " | ||||
f"Skipping build '{self.koji_build_event_data.build_id}' " | ||||
f"on '{self.koji_build_event_data.dist_git_branch}'. " | ||||
f"Build not finished yet." | ||||
) | ||||
return False | ||||
|
||||
if self.koji_build_event.git_ref not in ( | ||||
if self.koji_build_event_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 | ||||
|
@@ -99,68 +191,58 @@ def pre_check(self) -> bool: | |||
f"Bodhi update configured only for '{configured_branches}'." | ||||
) | ||||
return False | ||||
return True | ||||
|
||||
def run(self) -> TaskResults: | ||||
self.local_project = LocalProject( | ||||
git_project=self.project, | ||||
working_dir=self.service_config.command_handler_work_dir, | ||||
cache=RepositoryCache( | ||||
cache_path=self.service_config.repository_cache, | ||||
add_new=self.service_config.add_repositories_to_repository_cache, | ||||
) | ||||
if self.service_config.repository_cache | ||||
else None, | ||||
return self._write_access_to_dist_git_repo_is_not_needed_or_satisfied() | ||||
|
||||
def _error_message_for_auth_error(self, packit_exception: PackitException) -> str: | ||||
body = ( | ||||
f"Bodhi update creation failed for `{self.koji_build_event_data.nvr}` " | ||||
f"because of the missing permissions.\n\n" | ||||
f"Please, give {self.service_config.fas_user} user `commit` rights in the " | ||||
f"[dist-git settings]({self.data.project_url}/adduser).\n\n" | ||||
) | ||||
packit_api = PackitAPI( | ||||
self.service_config, | ||||
self.job_config, | ||||
downstream_local_project=self.local_project, | ||||
|
||||
body += ( | ||||
f"*Try {self.celery_task.retries + 1}/" | ||||
f"{self.celery_task.get_retry_limit() + 1}" | ||||
) | ||||
|
||||
# Notify user on each task run and set a more generous retry interval | ||||
# to let the user fix this issue in the meantime. | ||||
if not self.celery_task.is_last_try(): | ||||
body += ( | ||||
f": Task will be retried in " | ||||
f"{RETRY_INTERVAL_IN_MINUTES_WHEN_USER_ACTION_IS_NEEDED} minutes.*" | ||||
) | ||||
self.celery_task.retry( | ||||
delay=RETRY_INTERVAL_IN_MINUTES_WHEN_USER_ACTION_IS_NEEDED * 60, | ||||
ex=packit_exception, | ||||
) | ||||
else: | ||||
body += "*" | ||||
|
||||
return body | ||||
|
||||
def run(self) -> TaskResults: | ||||
try: | ||||
packit_api.create_update( | ||||
dist_git_branch=self.koji_build_event.git_ref, | ||||
self.packit_api.create_update( | ||||
dist_git_branch=self.koji_build_event_data.dist_git_branch, | ||||
update_type="enhancement", | ||||
update_notes=DEFAULT_BODHI_NOTE, | ||||
koji_builds=[ | ||||
self.koji_build_event.nvr # it accepts NVRs, not build IDs | ||||
self.koji_build_event_data.nvr # it accepts NVRs, not build IDs | ||||
], | ||||
) | ||||
except PackitException as ex: | ||||
logger.debug(f"Bodhi update failed to be created: {ex}") | ||||
|
||||
if isinstance(ex.__cause__, AuthError): | ||||
body = ( | ||||
f"Bodhi update creation failed for `{self.koji_build_event.nvr}` " | ||||
f"because of the missing permissions.\n\n" | ||||
f"Please, give {self.service_config.fas_user} user `commit` rights in the " | ||||
f"[dist-git settings]({self.data.project_url}/adduser).\n\n" | ||||
) | ||||
|
||||
body += ( | ||||
f"*Try {self.celery_task.retries + 1}/" | ||||
f"{self.celery_task.get_retry_limit() + 1}" | ||||
) | ||||
|
||||
# Notify user on each task run and set a more generous retry interval | ||||
# to let the user fix this issue in the meantime. | ||||
if not self.celery_task.is_last_try(): | ||||
body += ( | ||||
f": Task will be retried in " | ||||
f"{RETRY_INTERVAL_IN_MINUTES_WHEN_USER_ACTION_IS_NEEDED} minutes.*" | ||||
) | ||||
self.celery_task.retry( | ||||
delay=RETRY_INTERVAL_IN_MINUTES_WHEN_USER_ACTION_IS_NEEDED * 60, | ||||
ex=ex, | ||||
) | ||||
else: | ||||
body += "*" | ||||
|
||||
body = self._error_message_for_auth_error(packit_exception=ex) | ||||
notify = True | ||||
known_error = True | ||||
else: | ||||
body = ( | ||||
f"Bodhi update creation failed for `{self.koji_build_event.nvr}`:\n" | ||||
f"Bodhi update creation failed for `{self.koji_build_event_data.nvr}`:\n" | ||||
"```\n" | ||||
f"{ex}\n" | ||||
"```" | ||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we could refactor the packit
get_latest_build_in_tag
method to return the whole build dictionary and not only nvr here and then we would not need to call the Koji API here the second time