diff --git a/webhook_server_container/app.py b/webhook_server_container/app.py index 56c875ab..b836b3b2 100644 --- a/webhook_server_container/app.py +++ b/webhook_server_container/app.py @@ -35,11 +35,6 @@ async def process_webhook(request: Request) -> Dict[str, Any]: LOGGER.error(f"Error get JSON from request: {ex}") return process_failed_msg - try: - api: ProcessGithubWehook = ProcessGithubWehook(hook_data=hook_data, headers=request.headers) - api.process() - return {"status": requests.codes.ok, "message": "process success", "log_prefix": log_prefix} - - except Exception as ex: - LOGGER.error(f"Failed to process hook: {ex}") - return process_failed_msg + api: ProcessGithubWehook = ProcessGithubWehook(hook_data=hook_data, headers=request.headers) + api.process() + return {"status": requests.codes.ok, "message": "process success", "log_prefix": log_prefix} diff --git a/webhook_server_container/libs/github_api.py b/webhook_server_container/libs/github_api.py index 30105b59..52606cfa 100644 --- a/webhook_server_container/libs/github_api.py +++ b/webhook_server_container/libs/github_api.py @@ -60,7 +60,6 @@ PRE_COMMIT_STR, OTHER_MAIN_BRANCH, ) -from pyhelper_utils.general import ignore_exceptions from webhook_server_container.utils.github_repository_settings import ( get_repository_github_app_api, ) @@ -289,8 +288,11 @@ def prepare_log_prefix(self, pull_request: Optional[PullRequest] = None) -> str: ) def hash_token(self, message: str) -> str: - hashed_message = message.replace(self.token, "*****") - return hashed_message + if self.token: + hashed_message = message.replace(self.token, "*****") + return hashed_message + + return message def app_logger_info(self, message: str) -> None: hashed_message = self.hash_token(message=message) @@ -439,7 +441,6 @@ def skip_if_pull_request_already_merged(self) -> bool: return False - @ignore_exceptions(logger=LOGGER) def _remove_label(self, label: str) -> bool: if self.label_exists_in_pull_request(label=label): LOGGER.info(f"{self.log_prefix} Removing label {label}") @@ -449,7 +450,6 @@ def _remove_label(self, label: str) -> bool: LOGGER.warning(f"{self.log_prefix} Label {label} not found and cannot be removed") return False - @ignore_exceptions(logger=LOGGER) def _add_label(self, label: str) -> None: label = label.strip() if len(label) > 49: @@ -504,7 +504,6 @@ def _generate_issue_title(self) -> str: def _generate_issue_body(self) -> str: return f"[Auto generated]\nNumber: [#{self.pull_request.number}]" - @ignore_exceptions(logger=LOGGER) def is_branch_exists(self, branch: str) -> Branch: return self.repository.get_branch(branch) @@ -665,119 +664,93 @@ def label_by_user_comment(self, user_request: str, remove: bool, reviewed_user: label_func = self._remove_label if remove else self._add_label label_func(label=user_request) - @ignore_exceptions(logger=LOGGER) def set_verify_check_queued(self) -> None: return self.set_check_run_status(check_run=VERIFIED_LABEL_STR, status=QUEUED_STR) - @ignore_exceptions(logger=LOGGER) def set_verify_check_success(self) -> None: return self.set_check_run_status(check_run=VERIFIED_LABEL_STR, conclusion=SUCCESS_STR) - @ignore_exceptions(logger=LOGGER) def set_run_tox_check_queued(self) -> None: if not self.tox_enabled: return return self.set_check_run_status(check_run=TOX_STR, status=QUEUED_STR) - @ignore_exceptions(logger=LOGGER) def set_run_tox_check_in_progress(self) -> None: return self.set_check_run_status(check_run=TOX_STR, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_run_tox_check_failure(self, output: str) -> None: + def set_run_tox_check_failure(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=TOX_STR, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_run_tox_check_success(self, output: str) -> None: + def set_run_tox_check_success(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=TOX_STR, conclusion=SUCCESS_STR, output=output) - @ignore_exceptions(logger=LOGGER) def set_run_pre_commit_check_queued(self) -> None: if not self.pre_commit: return return self.set_check_run_status(check_run=PRE_COMMIT_STR, status=QUEUED_STR) - @ignore_exceptions(logger=LOGGER) def set_run_pre_commit_check_in_progress(self) -> None: return self.set_check_run_status(check_run=PRE_COMMIT_STR, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_run_pre_commit_check_failure(self, output: str = "") -> None: + def set_run_pre_commit_check_failure(self, output: Optional[Dict[str, Any]] = None) -> None: return self.set_check_run_status(check_run=PRE_COMMIT_STR, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_run_pre_commit_check_success(self, output: str = "") -> None: + def set_run_pre_commit_check_success(self, output: Optional[Dict[str, Any]] = None) -> None: return self.set_check_run_status(check_run=PRE_COMMIT_STR, conclusion=SUCCESS_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_merge_check_queued(self, output: str = "") -> None: + def set_merge_check_queued(self, output: Optional[Dict[str, Any]] = None) -> None: return self.set_check_run_status(check_run=CAN_BE_MERGED_STR, status=QUEUED_STR, output=output) - @ignore_exceptions(logger=LOGGER) def set_merge_check_in_progress(self) -> None: return self.set_check_run_status(check_run=CAN_BE_MERGED_STR, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) def set_merge_check_success(self) -> None: return self.set_check_run_status(check_run=CAN_BE_MERGED_STR, conclusion=SUCCESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_merge_check_failure(self, output: str) -> None: + def set_merge_check_failure(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=CAN_BE_MERGED_STR, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) def set_container_build_queued(self) -> None: if not self.build_and_push_container: return return self.set_check_run_status(check_run=BUILD_CONTAINER_STR, status=QUEUED_STR) - @ignore_exceptions(logger=LOGGER) def set_container_build_in_progress(self) -> None: return self.set_check_run_status(check_run=BUILD_CONTAINER_STR, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_container_build_success(self, output: str) -> None: + def set_container_build_success(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=BUILD_CONTAINER_STR, conclusion=SUCCESS_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_container_build_failure(self, output: str) -> None: + def set_container_build_failure(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=BUILD_CONTAINER_STR, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) def set_python_module_install_queued(self) -> None: if not self.pypi: return return self.set_check_run_status(check_run=PYTHON_MODULE_INSTALL_STR, status=QUEUED_STR) - @ignore_exceptions(logger=LOGGER) def set_python_module_install_in_progress(self) -> None: return self.set_check_run_status(check_run=PYTHON_MODULE_INSTALL_STR, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_python_module_install_success(self, output: str) -> None: + def set_python_module_install_success(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=PYTHON_MODULE_INSTALL_STR, conclusion=SUCCESS_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_python_module_install_failure(self, output: str) -> None: + def set_python_module_install_failure(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=PYTHON_MODULE_INSTALL_STR, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) def set_cherry_pick_in_progress(self) -> None: return self.set_check_run_status(check_run=CHERRY_PICKED_LABEL_PREFIX, status=IN_PROGRESS_STR) - @ignore_exceptions(logger=LOGGER) - def set_cherry_pick_success(self, output: str) -> None: + def set_cherry_pick_success(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=CHERRY_PICKED_LABEL_PREFIX, conclusion=SUCCESS_STR, output=output) - @ignore_exceptions(logger=LOGGER) - def set_cherry_pick_failure(self, output: str) -> None: + def set_cherry_pick_failure(self, output: Dict[str, Any]) -> None: return self.set_check_run_status(check_run=CHERRY_PICKED_LABEL_PREFIX, conclusion=FAILURE_STR, output=output) - @ignore_exceptions(logger=LOGGER) def create_issue_for_new_pull_request(self) -> None: if self.parent_committer in self.auto_verified_and_merged_users: LOGGER.info( @@ -793,7 +766,6 @@ def create_issue_for_new_pull_request(self) -> None: assignee=self.pull_request.user.login, ) - @ignore_exceptions(logger=LOGGER) def close_issue_for_merged_or_closed_pr(self, hook_action: str) -> None: for issue in self.repository.get_issues(): if issue.body == self._generate_issue_body(): @@ -804,7 +776,6 @@ def close_issue_for_merged_or_closed_pr(self, hook_action: str) -> None: issue.edit(state="closed") break - @ignore_exceptions(logger=LOGGER) def delete_remote_tag_for_merged_or_closed_pr(self) -> None: if not self.build_and_push_container: LOGGER.info(f"{self.log_prefix} repository do not have container configured") @@ -899,14 +870,19 @@ def process_pull_request_webhook_data(self) -> None: LOGGER.error(f"{self.log_prefix} Jira connection not found") else: - LOGGER.info(f"{self.log_prefix} Creating Jira story") - jira_story_key = jira_conn.create_story( - title=self.issue_title, - body=self.pull_request.html_url, - epic_key=self.jira_epic, - assignee=self.jira_assignee, - ) - self._add_label(label=f"{JIRA_STR}:{jira_story_key}") + if self.jira_epic and self.jira_assignee: + LOGGER.info(f"{self.log_prefix} Creating Jira story") + jira_story_key = jira_conn.create_story( + title=self.issue_title, + body=self.pull_request.html_url, + epic_key=self.jira_epic, + assignee=self.jira_assignee, + ) + self._add_label(label=f"{JIRA_STR}:{jira_story_key}") + else: + LOGGER.warning( + f"{self.log_prefix} Jira epic or assignee is not set. Skipping Jira story creation" + ) if hook_action == "synchronize": for _label in self.pull_request.labels: @@ -927,13 +903,17 @@ def process_pull_request_webhook_data(self) -> None: else: if _story_key := self.get_story_key_with_jira_connection(): - LOGGER.info(f"{self.log_prefix} Creating sub-task for Jira story {_story_key}") - jira_conn.create_closed_subtask( - title=f"{self.issue_title}: New commit from {self.last_committer}", - parent_key=_story_key, - assignee=self.jira_assignee, - body=f"PR: {self.pull_request.title}, new commit pushed by {self.last_committer}", - ) + if not self.jira_assignee: + LOGGER.warning(f"{self.log_prefix} Jira assignee is not set. Skipping sub-task creation") + + else: + LOGGER.info(f"{self.log_prefix} Creating sub-task for Jira story {_story_key}") + jira_conn.create_closed_subtask( + title=f"{self.issue_title}: New commit from {self.last_committer}", + parent_key=_story_key, + assignee=self.jira_assignee, + body=f"PR: {self.pull_request.title}, new commit pushed by {self.last_committer}", + ) if hook_action == "closed": self.close_issue_for_merged_or_closed_pr(hook_action=hook_action) @@ -1058,8 +1038,8 @@ def manage_reviewed_by_label(self, review_state: str, action: str, reviewed_user f"Processing label for review from {reviewed_user}. " f"review_state: {review_state}, action: {action}" ) - label_prefix = None - label_to_remove = None + label_prefix: str = "" + label_to_remove: str = "" if reviewed_user in self.approvers: approved_lgtm_label = APPROVED_BY_LABEL_PREFIX @@ -1115,7 +1095,7 @@ def _run_tox(self) -> None: self.set_run_tox_check_in_progress() rc, out, err = self._run_in_container(command=cmd) - output = { + output: Dict[str, Any] = { "title": "Tox", "summary": "", "text": self.get_check_run_text(err=err, out=out), @@ -1137,7 +1117,7 @@ def _run_pre_commit(self) -> None: self.set_run_pre_commit_check_in_progress() rc, out, err = self._run_in_container(command=cmd) - output = { + output: Dict[str, Any] = { "title": "Pre-Commit", "summary": "", "text": self.get_check_run_text(err=err, out=out), @@ -1300,7 +1280,6 @@ def user_commands(self, command: str, reviewed_user: str, issue_comment_id: int) issue_comment_id=issue_comment_id, ) - @ignore_exceptions(logger=LOGGER) def cherry_pick(self, target_branch: str, reviewed_user: str = "") -> None: requested_by = reviewed_user or "by target-branch label" LOGGER.info(f"{self.log_prefix} Cherry-pick requested by user: {requested_by}") @@ -1360,7 +1339,6 @@ def cherry_pick(self, target_branch: str, reviewed_user: str = "") -> None: "```" ) - @ignore_exceptions(logger=LOGGER) def label_by_pull_requests_merge_state_after_merged(self) -> None: """ Labels pull requests based on their mergeable state. @@ -1552,7 +1530,6 @@ def _container_repository_and_tag(self, is_merged: bool = False, tag: str = "") LOGGER.error(f"{self.log_prefix} container tag not found") return f"{self.container_repository}:webhook-server-tag-not-found" - @ignore_exceptions(logger=LOGGER) def _run_build_container( self, set_check: bool = True, @@ -1742,9 +1719,9 @@ def set_check_run_status( check_run: str, status: str = "", conclusion: str = "", - output: str = "", + output: Optional[Dict[str, str]] = None, ) -> None: - kwargs: Dict[str, str] = {"name": check_run, "head_sha": self.last_commit.sha} + kwargs: Dict[str, Any] = {"name": check_run, "head_sha": self.last_commit.sha} if status: kwargs["status"] = status @@ -1832,7 +1809,6 @@ def get_check_run_text(err: str, out: str) -> str: else: return f"```\n{err}\n\n{out}\n```" - @ignore_exceptions(logger=LOGGER) def get_jira_conn(self) -> JiraApi: return JiraApi( server=self.jira_server, @@ -1872,7 +1848,6 @@ def get_story_key_with_jira_connection(self) -> str: return "" return _story_key - @ignore_exceptions(logger=LOGGER, return_on_error=[]) def get_branch_required_status_checks(self) -> List[str]: if self.repository.private: LOGGER.info( diff --git a/webhook_server_container/libs/jira_api.py b/webhook_server_container/libs/jira_api.py index efc46bb8..de2ef155 100644 --- a/webhook_server_container/libs/jira_api.py +++ b/webhook_server_container/libs/jira_api.py @@ -1,7 +1,6 @@ import os from typing import Any, Dict, List from jira import Issue, JIRA -from pyhelper_utils.general import ignore_exceptions from simple_logger.logger import get_logger @@ -21,7 +20,6 @@ def __init__(self, server: str, project: str, token: str): self.conn.my_permissions() self.fields: Dict[str, Any] = {"project": {"key": self.project}} - @ignore_exceptions(logger=LOGGER) def create_story(self, title: str, body: str, epic_key: str, assignee: str) -> str: self.fields.update({ "summary": title, @@ -36,7 +34,6 @@ def create_story(self, title: str, body: str, epic_key: str, assignee: str) -> s _issue: Issue = self.conn.create_issue(fields=self.fields) return _issue.key - @ignore_exceptions(logger=LOGGER) def create_closed_subtask(self, title: str, body: str, parent_key: str, assignee: str) -> None: self.fields.update({ "summary": title, @@ -48,7 +45,6 @@ def create_closed_subtask(self, title: str, body: str, parent_key: str, assignee _issue: Issue = self.conn.create_issue(fields=self.fields) self.close_issue(key=_issue.key) - @ignore_exceptions(logger=LOGGER) def close_issue(self, key: str, comment: str = "") -> None: self.conn.transition_issue( issue=key, diff --git a/webhook_server_container/utils/github_repository_settings.py b/webhook_server_container/utils/github_repository_settings.py index 96fbd59b..96b26e2a 100644 --- a/webhook_server_container/utils/github_repository_settings.py +++ b/webhook_server_container/utils/github_repository_settings.py @@ -24,7 +24,6 @@ STATIC_LABELS_DICT, TOX_STR, ) -from pyhelper_utils.general import ignore_exceptions from webhook_server_container.utils.helpers import ( get_api_with_highest_rate_limit, get_future_results, @@ -38,12 +37,10 @@ ) -@ignore_exceptions(logger=LOGGER) def get_branch_sampler(repo: Repository, branch_name: str) -> Branch: return repo.get_branch(branch=branch_name) -@ignore_exceptions(logger=LOGGER) def set_branch_protection( branch: Branch, repository: Repository, @@ -68,7 +65,6 @@ def set_branch_protection( return True -@ignore_exceptions(logger=LOGGER) def set_repository_settings(repository: Repository) -> None: LOGGER.info(f"Set repository {repository.name} settings") repository.edit(delete_branch_on_merge=True, allow_auto_merge=True, allow_update_branch=True) @@ -302,7 +298,6 @@ def set_repository_check_runs_to_queued( return True, f"{repository}: Set check run status to {QUEUED_STR} is done", LOGGER.info -@ignore_exceptions(logger=LOGGER) def get_repository_github_app_api(config_: Config, repository_name: str) -> Optional[Github]: LOGGER.info("Getting repositories GitHub app API") with open(os.path.join(config_.data_dir, "webhook-server.private-key.pem")) as fd: diff --git a/webhook_server_container/utils/helpers.py b/webhook_server_container/utils/helpers.py index 12c17fed..47a1a3e3 100644 --- a/webhook_server_container/utils/helpers.py +++ b/webhook_server_container/utils/helpers.py @@ -5,7 +5,6 @@ import subprocess from concurrent.futures import Future, as_completed from typing import Any, Dict, List, Optional, Tuple -from pyhelper_utils.general import ignore_exceptions from colorama import Fore from github import Github from github.RateLimit import RateLimit @@ -31,7 +30,6 @@ def extract_key_from_dict(key: Any, _dict: Dict[Any, Any]) -> Any: yield result -@ignore_exceptions(logger=LOGGER) def get_github_repo_api(github_api: Github, repository: int | str) -> Repository: return github_api.get_repo(repository) @@ -114,7 +112,6 @@ def get_apis_and_tokes_from_config(config: Config, repository_name: str = "") -> return apis_and_tokens -@ignore_exceptions(logger=LOGGER) def get_api_with_highest_rate_limit(config: Config, repository_name: str = "") -> Tuple[Github | None, str | None]: """ Get API with the highest rate limit diff --git a/webhook_server_container/utils/webhook.py b/webhook_server_container/utils/webhook.py index 34dd816a..1fdf9703 100644 --- a/webhook_server_container/utils/webhook.py +++ b/webhook_server_container/utils/webhook.py @@ -12,13 +12,11 @@ get_future_results, get_github_repo_api, ) -from pyhelper_utils.general import ignore_exceptions LOGGER = get_logger(name="webhook", filename=os.environ.get("WEBHOOK_SERVER_LOG_FILE")) -@ignore_exceptions(logger=LOGGER) def process_github_webhook(data: Dict[str, Any], github_api: Github, webhook_ip: str) -> Tuple[bool, str, Callable]: repository: str = data["name"] repo = get_github_repo_api(github_api=github_api, repository=repository)