From f4441ac6884d77f93ce1ae27b296ce6b45b2cb0e Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 12:29:15 +0100 Subject: [PATCH 01/17] add `bot: status` command --- eessi_bot_event_handler.py | 30 ++++++++++++++++++++ tasks/build.py | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index e750f5e5..c265e5fd 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -476,6 +476,36 @@ def handle_bot_command_show_config(self, event_info, bot_command): issue_comment = self.handle_pull_request_opened_event(event_info, pr) return f"\n - added comment {issue_comment.html_url} to show configuration" + def handle_bot_command_status(self, event_info, bot_command): + """ + Handles bot command 'status' by running the handler for events of + type pull_request with the action opened. + + Args: + event_info (dict): event received by event_handler + bot_command (EESSIBotCommand): command to be handled + + Returns: + (string): table which collects the status of each target + """ + self.log("processing bot command 'status'") + gh = github.get_instance() + repo_name = event_info['raw_request_body']['repository']['full_name'] + pr_number = event_info['raw_request_body']['issue']['number'] + status_table = request_bot_build_issue_comments(repo_name, pr_number) + + comment = f"This is the status of all the `bot: build` commands:" + comment += f"\n|arch|result|date|status|url|" + comment += f"\n|----|------|----|------|---|" + for x in range(0,len(status_table['date'])): + comment += f"\n|{status_table['arch'][x]}|{status_table['result'][x]}|{status_table['date'][x]}|{status_table['status'][x]}|{status_table['url'][x]}|" + + self.log(f"PR opened: comment '{comment}'") + repo = gh.get_repo(repo_name) + pull_request = repo.get_pull(pr_number) + issue_comment = pull_request.create_issue_comment(comment) + return issue_comment + def start(self, app, port=3000): """ Logs startup information to shell and log file and starts the app using diff --git a/tasks/build.py b/tasks/build.py index e3f0bc8c..3a1374dd 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -760,3 +760,59 @@ def check_build_permission(pr, event_info): else: log(f"{fn}(): GH account '{build_labeler}' is authorized to build") return True + +def request_bot_build_issue_comments(repo_name, pr_number): + status_table = {'arch': [], 'date': [], 'status': [], 'url': [], 'result': []} + cfg = config.read_config() + + # for loop because github has max 100 items per request. + # if the pr has more than 100 comments we need to use per_page + # argument at the moment the for loop is for a max of 400 comments could bump this up + for x in range(1,5): + curl_cmd = f'curl -L https://api.github.com/repos/{repo_name}/issues/{pr_number}/comments?per_page=100&page={x}' + curl_output, curl_error, curl_exit_code = run_cmd(curl_cmd, "fetch all comments") + + comments = json.loads(curl_output) + + for comment in comments: #iterate through the comments to find the one where the status of the build was in + if config.read_config()["submitted_job_comments"]['initial_comment'][:20] in comment['body']: + + #get archictecture from comment['body'] + first_line = comment['body'][:comment['body'].find('/n')] + arch_map = get_architecture_targets(cfg) + for arch in arch_map.keys(): + target_arch = '/'.join(arch.split('/')[1:]) + if target_arch in first_line: + status_table['arch'].append(target_arch) + + #get date, status, url and result from the markdown table + comment_table = comment['body'][comment['body'].find('|'):comment['body'].rfind('|')+1] + + # Convert markdown table to a dictionary + lines = comment_table.split('\n') + ret = [] + keys = [] + for i,l in enumerate(lines): + if i==0: + keys=[_i.strip() for _i in l.split('|')] + elif i==1: continue + else: + ret.append({keys[_i]:v.strip() for _i,v in enumerate(l.split('|')) if _i>0 and _i Date: Thu, 25 Jan 2024 12:47:08 +0100 Subject: [PATCH 02/17] add command --- eessi_bot_event_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index c265e5fd..1acf7408 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -25,7 +25,7 @@ # Local application imports (anything from EESSI/eessi-bot-software-layer) from connections import github import tasks.build as build -from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, submit_build_jobs +from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, submit_build_jobs, request_bot_build_issue_comments import tasks.deploy as deploy from tasks.deploy import deploy_built_artefacts from tools import config @@ -416,7 +416,7 @@ def handle_bot_command_help(self, event_info, bot_command): help_msg += "\n - Commands must be sent with a **new** comment (edits of existing comments are ignored)." help_msg += "\n - A comment may contain multiple commands, one per line." help_msg += "\n - Every command begins at the start of a line and has the syntax `bot: COMMAND [ARGUMENTS]*`" - help_msg += "\n - Currently supported COMMANDs are: `help`, `build`, `show_config`" + help_msg += "\n - Currently supported COMMANDs are: `help`, `build`, `show_config`, `status`" help_msg += "\n" help_msg += "\n For more information, see https://www.eessi.io/docs/bot" return help_msg From d504f1c598abd0912b6093d5f714ca2b6dd1c150 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 13:07:07 +0100 Subject: [PATCH 03/17] clean-upp style --- eessi_bot_event_handler.py | 12 ++++++++---- tasks/build.py | 25 +++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 1acf7408..631494b0 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -25,7 +25,7 @@ # Local application imports (anything from EESSI/eessi-bot-software-layer) from connections import github import tasks.build as build -from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, submit_build_jobs, request_bot_build_issue_comments +from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, \ submit_build_jobs, request_bot_build_issue_comments import tasks.deploy as deploy from tasks.deploy import deploy_built_artefacts from tools import config @@ -493,12 +493,16 @@ def handle_bot_command_status(self, event_info, bot_command): repo_name = event_info['raw_request_body']['repository']['full_name'] pr_number = event_info['raw_request_body']['issue']['number'] status_table = request_bot_build_issue_comments(repo_name, pr_number) - + comment = f"This is the status of all the `bot: build` commands:" comment += f"\n|arch|result|date|status|url|" comment += f"\n|----|------|----|------|---|" - for x in range(0,len(status_table['date'])): - comment += f"\n|{status_table['arch'][x]}|{status_table['result'][x]}|{status_table['date'][x]}|{status_table['status'][x]}|{status_table['url'][x]}|" + for x in range(0, len(status_table['date'])): + comment += f"\n|{status_table['arch'][x]}|" + comment += f"{status_table['result'][x]}|" + comment += f"{status_table['date'][x]}|" + comment += f"{status_table['status'][x]}|" + comment += f"{status_table['url'][x]}|" self.log(f"PR opened: comment '{comment}'") repo = gh.get_repo(repo_name) diff --git a/tasks/build.py b/tasks/build.py index 3a1374dd..1f6ba1f5 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -771,13 +771,13 @@ def request_bot_build_issue_comments(repo_name, pr_number): for x in range(1,5): curl_cmd = f'curl -L https://api.github.com/repos/{repo_name}/issues/{pr_number}/comments?per_page=100&page={x}' curl_output, curl_error, curl_exit_code = run_cmd(curl_cmd, "fetch all comments") - + comments = json.loads(curl_output) - - for comment in comments: #iterate through the comments to find the one where the status of the build was in + + for comment in comments: # iterate through the comments to find the one where the status of the build was in if config.read_config()["submitted_job_comments"]['initial_comment'][:20] in comment['body']: - #get archictecture from comment['body'] + # get archictecture from comment['body'] first_line = comment['body'][:comment['body'].find('/n')] arch_map = get_architecture_targets(cfg) for arch in arch_map.keys(): @@ -785,21 +785,22 @@ def request_bot_build_issue_comments(repo_name, pr_number): if target_arch in first_line: status_table['arch'].append(target_arch) - #get date, status, url and result from the markdown table + # get date, status, url and result from the markdown table comment_table = comment['body'][comment['body'].find('|'):comment['body'].rfind('|')+1] # Convert markdown table to a dictionary lines = comment_table.split('\n') ret = [] keys = [] - for i,l in enumerate(lines): - if i==0: - keys=[_i.strip() for _i in l.split('|')] - elif i==1: continue + for i, l in enumerate(lines): + if i == 0: + keys = [_i.strip() for _i in l.split('|')] + elif i == 1: + continue else: - ret.append({keys[_i]:v.strip() for _i,v in enumerate(l.split('|')) if _i>0 and _i 0 and _i Date: Thu, 25 Jan 2024 13:47:08 +0100 Subject: [PATCH 04/17] clean-upp style --- eessi_bot_event_handler.py | 3 ++- tasks/build.py | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 631494b0..8854bc4e 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -25,7 +25,8 @@ # Local application imports (anything from EESSI/eessi-bot-software-layer) from connections import github import tasks.build as build -from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, \ submit_build_jobs, request_bot_build_issue_comments +from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, \ + submit_build_jobs, request_bot_build_issue_comments import tasks.deploy as deploy from tasks.deploy import deploy_built_artefacts from tools import config diff --git a/tasks/build.py b/tasks/build.py index 1f6ba1f5..48c15a40 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -761,14 +761,15 @@ def check_build_permission(pr, event_info): log(f"{fn}(): GH account '{build_labeler}' is authorized to build") return True + def request_bot_build_issue_comments(repo_name, pr_number): status_table = {'arch': [], 'date': [], 'status': [], 'url': [], 'result': []} cfg = config.read_config() - - # for loop because github has max 100 items per request. - # if the pr has more than 100 comments we need to use per_page + + # for loop because github has max 100 items per request. + # if the pr has more than 100 comments we need to use per_page # argument at the moment the for loop is for a max of 400 comments could bump this up - for x in range(1,5): + for x in range(1, 5): curl_cmd = f'curl -L https://api.github.com/repos/{repo_name}/issues/{pr_number}/comments?per_page=100&page={x}' curl_output, curl_error, curl_exit_code = run_cmd(curl_cmd, "fetch all comments") @@ -790,15 +791,18 @@ def request_bot_build_issue_comments(repo_name, pr_number): # Convert markdown table to a dictionary lines = comment_table.split('\n') - ret = [] + values = [] keys = [] - for i, l in enumerate(lines): + for i, row in enumerate(lines): if i == 0: - keys = [_i.strip() for _i in l.split('|')] - elif i == 1: + for key in row.split('|'): + keys.append(key.strip()) + elif i == 1: continue else: - ret.append({keys[_i]: v.strip() for _i, v in enumerate(l.split('|')) if _i > 0 and _i 0 and j < len(keys) - 1: + values.append({keys[j]: value.strip()}) # add date, status, url to status_table if for row in ret: From bff7da70ac66276bea7913910509265ce78c7250 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 13:53:16 +0100 Subject: [PATCH 05/17] clean-upp style --- tasks/build.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tasks/build.py b/tasks/build.py index 48c15a40..5ee36d27 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -775,7 +775,8 @@ def request_bot_build_issue_comments(repo_name, pr_number): comments = json.loads(curl_output) - for comment in comments: # iterate through the comments to find the one where the status of the build was in + for comment in comments: + # iterate through the comments to find the one where the status of the build was in if config.read_config()["submitted_job_comments"]['initial_comment'][:20] in comment['body']: # get archictecture from comment['body'] @@ -800,24 +801,24 @@ def request_bot_build_issue_comments(repo_name, pr_number): elif i == 1: continue else: - for j, value in enumerate(l.split('|')): + for j, value in enumerate(row.split('|')): if j > 0 and j < len(keys) - 1: values.append({keys[j]: value.strip()}) # add date, status, url to status_table if - for row in ret: - if row['job status'] == 'finished': - status_table['date'].append(row['date']) - status_table['status'].append(row['job status']) + for value in values: + if value['job status'] == 'finished': + status_table['date'].append(value['date']) + status_table['status'].append(value['job status']) status_table['url'].append(comment['html_url']) - if 'FAILURE' in row['comment']: + if 'FAILURE' in value['comment']: status_table['result'].append(':cry: FAILURE') - elif 'SUCCES' in row['comment']: + elif 'SUCCES' in value['comment']: status_table['result'].append(':grin: SUCCESS') - elif 'UNKNOWN' in row['comment']: + elif 'UNKNOWN' in value['comment']: status_table['result'].append(':shrug: UNKNOWN') else: - status_table['result'].append(row['comment']) + status_table['result'].append(value['comment']) if len(comments) != 100: break return status_table From d04bea1f919777d93719e82c20205e497eb3eb8f Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 13:56:59 +0100 Subject: [PATCH 06/17] clean-upp style --- tasks/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/build.py b/tasks/build.py index 5ee36d27..fdf45ac8 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -765,7 +765,7 @@ def check_build_permission(pr, event_info): def request_bot_build_issue_comments(repo_name, pr_number): status_table = {'arch': [], 'date': [], 'status': [], 'url': [], 'result': []} cfg = config.read_config() - + # for loop because github has max 100 items per request. # if the pr has more than 100 comments we need to use per_page # argument at the moment the for loop is for a max of 400 comments could bump this up From 5e0440356d0bf1ad9a90e53a475e103add5dad6b Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:03:20 +0100 Subject: [PATCH 07/17] clean-upp --- eessi_bot_event_handler.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 8854bc4e..3991d86a 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -495,15 +495,16 @@ def handle_bot_command_status(self, event_info, bot_command): pr_number = event_info['raw_request_body']['issue']['number'] status_table = request_bot_build_issue_comments(repo_name, pr_number) - comment = f"This is the status of all the `bot: build` commands:" - comment += f"\n|arch|result|date|status|url|" - comment += f"\n|----|------|----|------|---|" + comment_status = '' + comment_status += f"\nThis is the status of all the `bot: build` commands:" + comment_status += f"\n|arch|result|date|status|url|" + comment_status += f"\n|----|------|----|------|---|" for x in range(0, len(status_table['date'])): - comment += f"\n|{status_table['arch'][x]}|" - comment += f"{status_table['result'][x]}|" - comment += f"{status_table['date'][x]}|" - comment += f"{status_table['status'][x]}|" - comment += f"{status_table['url'][x]}|" + comment_status += f"\n|{status_table['arch'][x]}|" + comment_status += f"{status_table['result'][x]}|" + comment_status += f"{status_table['date'][x]}|" + comment_status += f"{status_table['status'][x]}|" + comment_status += f"{status_table['url'][x]}|" self.log(f"PR opened: comment '{comment}'") repo = gh.get_repo(repo_name) From d5d1c4ef611ee719c4d34eb04a0a634c57c3e68d Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:04:45 +0100 Subject: [PATCH 08/17] clean-upp --- eessi_bot_event_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 3991d86a..17dbbe7f 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -509,7 +509,7 @@ def handle_bot_command_status(self, event_info, bot_command): self.log(f"PR opened: comment '{comment}'") repo = gh.get_repo(repo_name) pull_request = repo.get_pull(pr_number) - issue_comment = pull_request.create_issue_comment(comment) + issue_comment = pull_request.create_issue_comment(comment_status) return issue_comment def start(self, app, port=3000): From d3749f752e6839641d297fa3ce8f51daeff65ee8 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:05:24 +0100 Subject: [PATCH 09/17] clean-upp --- eessi_bot_event_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 17dbbe7f..2b6516a0 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -506,7 +506,7 @@ def handle_bot_command_status(self, event_info, bot_command): comment_status += f"{status_table['status'][x]}|" comment_status += f"{status_table['url'][x]}|" - self.log(f"PR opened: comment '{comment}'") + self.log(f"PR opened: comment '{comment_status}'") repo = gh.get_repo(repo_name) pull_request = repo.get_pull(pr_number) issue_comment = pull_request.create_issue_comment(comment_status) From 1946131e6363e83ca891daea4ff043847f47bf51 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:14:33 +0100 Subject: [PATCH 10/17] clean-up comment_status --- eessi_bot_event_handler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index 2b6516a0..f13cabbe 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -496,9 +496,9 @@ def handle_bot_command_status(self, event_info, bot_command): status_table = request_bot_build_issue_comments(repo_name, pr_number) comment_status = '' - comment_status += f"\nThis is the status of all the `bot: build` commands:" - comment_status += f"\n|arch|result|date|status|url|" - comment_status += f"\n|----|------|----|------|---|" + comment_status += "\nThis is the status of all the `bot: build` commands:" + comment_status += "\n|arch|result|date|status|url|" + comment_status += "\n|----|------|----|------|---|" for x in range(0, len(status_table['date'])): comment_status += f"\n|{status_table['arch'][x]}|" comment_status += f"{status_table['result'][x]}|" From 718c8d5507d1d6f6f941ca1d9b49d869787ddccd Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:49:38 +0100 Subject: [PATCH 11/17] fix markdown to dict code --- tasks/build.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tasks/build.py b/tasks/build.py index fdf45ac8..341b40a6 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -792,9 +792,10 @@ def request_bot_build_issue_comments(repo_name, pr_number): # Convert markdown table to a dictionary lines = comment_table.split('\n') - values = [] + rows = [] keys = [] for i, row in enumerate(lines): + values = {} if i == 0: for key in row.split('|'): keys.append(key.strip()) @@ -803,22 +804,23 @@ def request_bot_build_issue_comments(repo_name, pr_number): else: for j, value in enumerate(row.split('|')): if j > 0 and j < len(keys) - 1: - values.append({keys[j]: value.strip()}) + values[keys[j]] = value.strip()}) + rows.append(values) # add date, status, url to status_table if - for value in values: - if value['job status'] == 'finished': - status_table['date'].append(value['date']) - status_table['status'].append(value['job status']) + for row in rows: + if row['job status'] == 'finished': + status_table['date'].append(row['date']) + status_table['status'].append(row['job status']) status_table['url'].append(comment['html_url']) - if 'FAILURE' in value['comment']: + if 'FAILURE' in row['comment']: status_table['result'].append(':cry: FAILURE') - elif 'SUCCES' in value['comment']: + elif 'SUCCES' in row['comment']: status_table['result'].append(':grin: SUCCESS') - elif 'UNKNOWN' in value['comment']: + elif 'UNKNOWN' in row['comment']: status_table['result'].append(':shrug: UNKNOWN') else: - status_table['result'].append(value['comment']) + status_table['result'].append(row['comment']) if len(comments) != 100: break return status_table From 85fc1611243fc1074f33b3c966661feb6f8b0a73 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 14:50:22 +0100 Subject: [PATCH 12/17] fix markdown to dict code --- tasks/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/build.py b/tasks/build.py index 341b40a6..818e62d0 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -804,7 +804,7 @@ def request_bot_build_issue_comments(repo_name, pr_number): else: for j, value in enumerate(row.split('|')): if j > 0 and j < len(keys) - 1: - values[keys[j]] = value.strip()}) + values[keys[j]] = value.strip() rows.append(values) # add date, status, url to status_table if From 27cb368a6878ed37cfd585e69572ec281299c673 Mon Sep 17 00:00:00 2001 From: Lara Ramona Peeters <49882639+laraPPr@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:55:11 +0100 Subject: [PATCH 13/17] Update eessi_bot_event_handler.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Thomas Röblitz --- eessi_bot_event_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index f13cabbe..688a83b7 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -26,7 +26,7 @@ from connections import github import tasks.build as build from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, \ - submit_build_jobs, request_bot_build_issue_comments + request_bot_build_issue_comments, submit_build_jobs import tasks.deploy as deploy from tasks.deploy import deploy_built_artefacts from tools import config From 6fda60aa748ba36fa7c439ce659b385d79502e38 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 16:50:27 +0100 Subject: [PATCH 14/17] resolve requested changes from https://github.com/EESSI/eessi-bot-software-layer/pull/237#pullrequestreview-1843653006 --- eessi_bot_event_handler.py | 11 ++++++----- tasks/build.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/eessi_bot_event_handler.py b/eessi_bot_event_handler.py index f13cabbe..106af283 100644 --- a/eessi_bot_event_handler.py +++ b/eessi_bot_event_handler.py @@ -26,7 +26,7 @@ from connections import github import tasks.build as build from tasks.build import check_build_permission, get_architecture_targets, get_repo_cfg, \ - submit_build_jobs, request_bot_build_issue_comments + srequest_bot_build_issue_comment, submit_build_jobs import tasks.deploy as deploy from tasks.deploy import deploy_built_artefacts from tools import config @@ -479,15 +479,16 @@ def handle_bot_command_show_config(self, event_info, bot_command): def handle_bot_command_status(self, event_info, bot_command): """ - Handles bot command 'status' by running the handler for events of - type pull_request with the action opened. + Handles bot command 'status' by querying the github API + for the comments in a pr. Args: event_info (dict): event received by event_handler bot_command (EESSIBotCommand): command to be handled Returns: - (string): table which collects the status of each target + github.IssueComment.IssueComment (note, github refers to + PyGithub, not the github from the internal connections module) """ self.log("processing bot command 'status'") gh = github.get_instance() @@ -506,7 +507,7 @@ def handle_bot_command_status(self, event_info, bot_command): comment_status += f"{status_table['status'][x]}|" comment_status += f"{status_table['url'][x]}|" - self.log(f"PR opened: comment '{comment_status}'") + self.log(f"Overview of finished builds: comment '{comment_status}'") repo = gh.get_repo(repo_name) pull_request = repo.get_pull(pr_number) issue_comment = pull_request.create_issue_comment(comment_status) diff --git a/tasks/build.py b/tasks/build.py index 818e62d0..8bd5e3f8 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -763,6 +763,17 @@ def check_build_permission(pr, event_info): def request_bot_build_issue_comments(repo_name, pr_number): + """ + Query the github API for the issue_comments in a pr. + + Archs: + repo_name (string): name of the repository (format USER_OR_ORGANISATION/REPOSITORY) + pr_number (int): number og the pr + + Returns: + status_table (dict): dictionary with 'arch', 'date', 'status', 'url' and 'result' + for all the finished builds; + """ status_table = {'arch': [], 'date': [], 'status': [], 'url': [], 'result': []} cfg = config.read_config() @@ -780,7 +791,7 @@ def request_bot_build_issue_comments(repo_name, pr_number): if config.read_config()["submitted_job_comments"]['initial_comment'][:20] in comment['body']: # get archictecture from comment['body'] - first_line = comment['body'][:comment['body'].find('/n')] + first_line = comment['body'].split('\n')[0] arch_map = get_architecture_targets(cfg) for arch in arch_map.keys(): target_arch = '/'.join(arch.split('/')[1:]) @@ -815,7 +826,7 @@ def request_bot_build_issue_comments(repo_name, pr_number): status_table['url'].append(comment['html_url']) if 'FAILURE' in row['comment']: status_table['result'].append(':cry: FAILURE') - elif 'SUCCES' in row['comment']: + elif 'SUCCESS' in value['comment']: status_table['result'].append(':grin: SUCCESS') elif 'UNKNOWN' in row['comment']: status_table['result'].append(':shrug: UNKNOWN') From 4bc9e3325502abef45c2425659b32485b48eb070 Mon Sep 17 00:00:00 2001 From: vsc46128 vscuser Date: Thu, 25 Jan 2024 16:56:08 +0100 Subject: [PATCH 15/17] clean up docstring in tasks/build.py --- tasks/build.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/build.py b/tasks/build.py index 8bd5e3f8..1ce8e956 100644 --- a/tasks/build.py +++ b/tasks/build.py @@ -764,9 +764,9 @@ def check_build_permission(pr, event_info): def request_bot_build_issue_comments(repo_name, pr_number): """ - Query the github API for the issue_comments in a pr. - - Archs: + Query the github API for the issue_comments in a pr. + + Archs: repo_name (string): name of the repository (format USER_OR_ORGANISATION/REPOSITORY) pr_number (int): number og the pr From f16d10af9a091fb0660d1b3ab6b9db3aa3befcb3 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Mon, 29 Jan 2024 14:53:10 +0100 Subject: [PATCH 16/17] renew GH access token ahead of time to prevent Bad credentials crashes --- connections/github.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/connections/github.py b/connections/github.py index 2204fe89..3037c0fe 100644 --- a/connections/github.py +++ b/connections/github.py @@ -11,7 +11,7 @@ # # Standard library imports -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone import time # Third party imports (anything installed into the local Python environment) @@ -99,8 +99,6 @@ def get_instance(): Instance of Github """ global _gh, _token - # TODO Possibly renew token already if expiry date is soon, not only - # after it has expired. # Check if PyGithub version is < 1.56 if hasattr(github, 'GithubRetry'): @@ -110,7 +108,10 @@ def get_instance(): # Pygithub 1.x time_now = datetime.utcnow() - if not _gh or (_token and time_now > _token.expires_at): + # Renew token already if expiry date is less then 30 min away. + refresh_time = timedelta(minutes=30) + + if not _gh or (_token and time_now > (_token.expires_at - refresh_time)): _gh = connect() return _gh From 0db1e2b40e393eab0225a7321b4f02b4946ab692 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Mon, 29 Jan 2024 20:25:35 +0100 Subject: [PATCH 17/17] release notes for v0.3.0 --- RELEASE_NOTES | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1707f3a5..b8d09e8c 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,6 +1,19 @@ This file contains a description of the major changes to the EESSI build-and-deploy bot. For more detailed information, please see the git log. +v0.3.0 (30 January 2024) +-------------------------- + +This is a minor release of the EESSI build-and-deploy bot. + +Bug fixes: +* refreshes the token to access GitHub well before it expires (#238) + +Improvements: +* adds a new bot command 'status' which provides an overview (table) of all + finished builds (#237) + + v0.2.0 (26 November 2023) --------------------------