diff --git a/auto_merger/api.py b/auto_merger/api.py index fcafdda..d549e96 100644 --- a/auto_merger/api.py +++ b/auto_merger/api.py @@ -54,7 +54,7 @@ def merger(print_results, merger_labels, approvals, pr_lifetime, send_email) -> if ret_value != 0: return ret_value if print_results: - auto_merger.print_approval_pull_request() + auto_merger.print_pull_request_to_merge() if not auto_merger.send_results(send_email): return 1 return ret_value \ No newline at end of file diff --git a/auto_merger/cli/merger.py b/auto_merger/cli/merger.py index a7b6cca..5d817cb 100644 --- a/auto_merger/cli/merger.py +++ b/auto_merger/cli/merger.py @@ -38,7 +38,7 @@ @click.option("--approvals", default=2, type=int, help="Specify number of approvals to automatically merge PR. Default 2") -@click.option("--pr-lifetime", int=1, help="Specify a smallest time for which PR should opened") +@click.option("--pr-lifetime", default=1, type=int, help="Specify a smallest time for which PR should opened") @pass_global_config def merger(ctx, print_results, merger_labels, approvals, pr_lifetime, send_email): logger.debug(ctx.debug) diff --git a/auto_merger/merger.py b/auto_merger/merger.py index 381b382..cb1c7d3 100644 --- a/auto_merger/merger.py +++ b/auto_merger/merger.py @@ -44,13 +44,11 @@ class AutoMerger: def __init__(self, github_labels, approvals: int = 2, pr_lifetime: int = 1): self.logger = setup_logger("AutoMerger") - self.github_labels = list(github_labels) + self.approval_labels = list(github_labels) self.approvals = approvals - self.logger.debug(f"GitHub Labels: {self.github_labels}") + self.logger.debug(f"GitHub Labels: {self.approval_labels}") self.logger.debug(f"Approvals Labels: {self.approvals}") - self.blocked_pr = {} self.pr_to_merge = {} - self.blocked_body = [] self.approval_body = [] self.repo_data: List = [] @@ -91,22 +89,6 @@ def is_authenticated(self): return False return True - def add_blocked_pr(self, pr: {}): - present = False - for stored_pr in self.blocked_pr[self.container_name]: - if int(stored_pr["number"]) == int(pr["number"]): - present = True - if present: - return - self.blocked_pr[self.container_name].append({ - "number": pr["number"], - "pr_dict": { - "title": pr["title"], - "labels": pr["labels"] - } - }) - self.logger.debug(f"PR {pr['number']} added to blocked") - def add_approved_pr(self, pr: {}): self.pr_to_merge[self.container_name].append({ "number": pr["number"], @@ -117,22 +99,11 @@ def add_approved_pr(self, pr: {}): }) self.logger.debug(f"PR {pr['number']} added to approved") - def check_blocked_labels(self): - for pr in self.repo_data: - self.logger.debug(f"Check blocked: {pr}") - if "labels" not in pr: - continue - for label in pr["labels"]: - if label["name"] not in self.blocking_labels: - continue - self.logger.debug(f"Add '{pr['number']}' to blocked PRs.") - self.add_blocked_pr(pr) - def check_labels_to_merge(self, pr): if "labels" not in pr: return True for label in pr["labels"]: - if label["name"] in self.blocking_labels: + if label["name"] in self.approval_labels: return False self.logger.debug(f"Add '{pr['number']}' to approved PRs.") return True @@ -213,17 +184,10 @@ def check_all_containers(self) -> int: self.logger.error(f"This is not correct repo {self.container_name}.") self.clean_dirs() continue - if self.container_name not in self.blocked_pr: - self.blocked_pr[self.container_name] = [] if self.container_name not in self.pr_to_merge: self.pr_to_merge[self.container_name] = [] try: self.get_gh_pr_list() - self.check_blocked_labels() - if len(self.blocked_pr[self.container_name]) != 0: - self.logger.info( - f"This pull request can not be merged {self.pr_to_merge}" - ) self.check_pr_to_merge() except subprocess.CalledProcessError: self.clean_dirs() @@ -232,52 +196,31 @@ def check_all_containers(self) -> int: self.clean_dirs() return 0 - def get_blocked_labels(self, pr_dict) -> List [str]: - labels = [] - for lbl in pr_dict["labels"]: - labels.append(lbl["name"]) - return labels - - def print_blocked_pull_request(self): - # Do not print anything in case we do not have PR. - if not [x for x in self.blocked_pr if self.blocked_pr[x]]: - return 0 - self.blocked_body.append( - f"Pull requests that are blocked by labels [{', '.join(self.blocking_labels)}]

" - ) - - for container, pull_requests in self.blocked_pr.items(): - if not pull_requests: - continue - self.blocked_body.append(f"{container}:") - self.blocked_body.append("") - for pr in pull_requests: - blocked_labels = self.get_blocked_labels(pr["pr_dict"]) - self.blocked_body.append( - f"" - f"" - ) - self.blocked_body.append("
Pull request URLTitleMissing labels
https://github.com/sclorg/{container}/pull/{pr['number']}{pr['pr_dict']['title']}

{' '.join(blocked_labels)}



") - print('\n'.join(self.blocked_body)) - def print_approval_pull_request(self): + def print_pull_request_to_merge(self): # Do not print anything in case we do not have PR. if not [x for x in self.pr_to_merge if self.pr_to_merge[x]]: return 0 - self.approval_body.append(f"Pull requests that can be merged or missing {self.approvals} approvals") - self.approval_body.append("") + to_approval: bool = False + pr_body: List = [] for container, pr in self.pr_to_merge.items(): if not pr: continue - if int(pr["approvals"]) >= self.approvals: - result_pr = f"CAN BE MERGED" - else: - result_pr = f"Missing {self.approvals-int(pr['approvals'])} APPROVAL" - self.approval_body.append( + if int(pr["approvals"]) < self.approvals: + continue + to_approval = True + result_pr = f"CAN BE MERGED" + pr_body.append( f"" f"" ) - self.approval_body.append("
Pull request URLTitleApproval status
https://github.com/sclorg/{container}/pull/{pr['number']}{pr['pr_dict']['title']}

{result_pr}


") + if to_approval: + self.approval_body.append(f"Pull requests that can be merged.") + self.approval_body.append("") + self.approval_body.extend(pr_body) + self.approval_body.append("
Pull request URLTitleApproval status

") + else: + self.approval_body.append("There are not pull requests to be merged.") print('\n'.join(self.approval_body)) def send_results(self, recipients): @@ -286,7 +229,7 @@ def send_results(self, recipients): return 1 sender_class = EmailSender(recipient_email=list(recipients)) subject_msg = "Pull request statuses for organization https://gibhub.com/sclorg" - sender_class.send_email(subject_msg, self.blocked_body + self.approval_body) + sender_class.send_email(subject_msg, self.approval_body) def run(): diff --git a/tests/test_correct_repo.py b/tests/test_correct_repo.py index 1c7f411..9b5c630 100644 --- a/tests/test_correct_repo.py +++ b/tests/test_correct_repo.py @@ -2,20 +2,20 @@ from flexmock import flexmock -from auto_merger.merger import AutoMerger +from auto_merger.pr_checker import PRStatusChecker def test_get_gh_pr_correct_repo(get_repo_name): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return(get_repo_name) - auto_merger = AutoMerger(github_labels=[], blocking_labels=["pr/missing-review"]) + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return(get_repo_name) + auto_merger = PRStatusChecker(github_labels=[], blocking_labels=["pr/missing-review"]) auto_merger.container_name = "s2i-nodejs-container" assert auto_merger.is_correct_repo() def test_get_gh_pr_wrong_repo(get_repo_wrong_name): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return( get_repo_wrong_name ) - auto_merger = AutoMerger(github_labels=[], blocking_labels=["pr/missing-review"]) + auto_merger = PRStatusChecker(github_labels=[], blocking_labels=["pr/missing-review"]) auto_merger.container_name = "s2i-nodejs-container" assert not auto_merger.is_correct_repo() diff --git a/tests/test_pr_status.py b/tests/test_pr_status.py index 4b50617..53ca9c8 100644 --- a/tests/test_pr_status.py +++ b/tests/test_pr_status.py @@ -2,24 +2,24 @@ from flexmock import flexmock -from auto_merger.merger import AutoMerger +from auto_merger.pr_checker import PRStatusChecker def test_get_gh_pr_list(get_pr_missing_ci): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return( get_pr_missing_ci ) - auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) + auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) auto_merger.container_name = "s2i-nodejs-container" auto_merger.get_gh_pr_list() assert auto_merger.repo_data def test_get_gh_two_pr_labels_missing(get_two_pr_missing_labels): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return( get_two_pr_missing_labels ) - auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) + auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) auto_merger.container_name = "s2i-nodejs-container" auto_merger.get_gh_pr_list() assert auto_merger.repo_data @@ -27,10 +27,10 @@ def test_get_gh_two_pr_labels_missing(get_two_pr_missing_labels): def test_get_gh_pr_missing_ci(get_pr_missing_ci): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return( + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return( get_pr_missing_ci ) - auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) + auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) auto_merger.container_name = "s2i-nodejs-container" auto_merger.get_gh_pr_list() assert auto_merger.repo_data @@ -38,8 +38,8 @@ def test_get_gh_pr_missing_ci(get_pr_missing_ci): def test_get_no_pr_for_merge(): - flexmock(AutoMerger).should_receive("get_gh_json_output").and_return([]) - auto_merger = AutoMerger(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) + flexmock(PRStatusChecker).should_receive("get_gh_json_output").and_return([]) + auto_merger = PRStatusChecker(github_labels=["READY-to-MERGE"], blocking_labels=["pr/missing-review", 'pr/failing-ci']) auto_merger.container_name = "s2i-nodejs-container" auto_merger.get_gh_pr_list() assert not auto_merger.repo_data