diff --git a/CHANGELOG b/CHANGELOG index 776f02a1..0a035e19 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,12 @@ # Change Log All notable changes to this project will be documented in this file. +## [3.6.13] - 2022-05-12 +# Added +- Support check-suites event on GitHub Actions +# Fixed +- Changing url returned on status page for queue build on GitHub Actions + ## [3.6.12] - 2022-05-04 # Fixed - Fix Key error when retrieve html_url for checksuites diff --git a/bert_e/git_host/github/__init__.py b/bert_e/git_host/github/__init__.py index 3a2d687c..dd62fd30 100644 --- a/bert_e/git_host/github/__init__.py +++ b/bert_e/git_host/github/__init__.py @@ -13,7 +13,6 @@ # limitations under the License. import json import logging -from datetime import datetime from collections import defaultdict, namedtuple from requests import HTTPError @@ -529,6 +528,10 @@ def total_count(self): def workflow_runs(self): return self.data['workflow_runs'] + @property + def check_suite_ids(self): + return [wf['check_suite_id'] for wf in self.workflow_runs] + class AggregatedCheckSuites(base.AbstractGitHostObject, base.AbstractBuildStatus): @@ -544,48 +547,33 @@ def __init__(self, *args, **kwargs): @property def url(self): - self.remove_unwanted_workflows() - - def sort_f(check_suite): - date = check_suite.get('created_at') - return date if date else datetime(year=1962, month=1, day=1) - - self._check_suites.sort(key=sort_f, reverse=True) - - failed_c = [elem for elem in self._check_suites - if elem['conclusion'] != 'success'] - if len(failed_c): - return failed_c[0]['html_url'] - elif len(failed_c) and len(self._check_suites): - return self._check_suites[0]['html_url'] - return '' + return f"https://github.com/{self.full_repo}/commit/{self.commit}" def is_pending(self): return len([ elem for elem in self._check_suites if elem['status'] == 'pending' ]) > 0 - def _get_check_suite_ids(self, workflow_runs): - return dict(map(lambda elem: ( - elem['check_suite_id'], - {'html_url': elem['html_url'], 'event': elem['event']} - ), workflow_runs) - ) - def _get_aggregate_workflow_dispatched(self, page): - ref = self._check_suites[0]['head_sha'] - repo = self._check_suites[0]['repository']['name'] - owner = self._check_suites[0]['repository']['owner']['login'] + """Return a list of check-suite IDs for workflow_dispatch runs""" - return AggregatedWorkflowRuns.get( + response = AggregatedWorkflowRuns.get( client=self.client, - owner=owner, repo=repo, ref=ref, + owner=self.owner, repo=self.repo, ref=self.commit, params={ - 'branch': self._check_suites[0]['head_branch'], + 'branch': self.branch, 'page': page, + 'event': 'workflow_dispatch', 'per_page': 100 }) + workflow_dispatches = response.check_suite_ids + while len(workflow_dispatches) < response.total_count: + page += 1 + workflow_dispatches.update( + self._get_aggregate_workflow_dispatched(page)) + return workflow_dispatches + def remove_unwanted_workflows(self): """ Remove two things: @@ -596,20 +584,7 @@ def remove_unwanted_workflows(self): return page = 1 - response = self._get_aggregate_workflow_dispatched(page) - dispatched = self._get_check_suite_ids(response.workflow_runs) - - while len(dispatched.keys()) < response.total_count: - page += 1 - response = self._get_aggregate_workflow_dispatched(page) - dispatched.update( - self._get_check_suite_ids(response.workflow_runs) - ) - - workflow_dispatches = [ - key for key, value in dispatched.items() - if value['event'] == 'workflow_dispatch' - ] + workflow_dispatches = self._get_aggregate_workflow_dispatched(page) self._check_suites = list(filter( lambda elem: elem['id'] not in workflow_dispatches, @@ -621,12 +596,6 @@ def remove_unwanted_workflows(self): self._check_suites )) - self._check_suites = list(map(lambda elem: { - **elem, - 'html_url': - dispatched.get(elem['id'], {'html_url': ''})['html_url'] - }, self._check_suites)) - @property def state(self): self.remove_unwanted_workflows() @@ -655,11 +624,34 @@ def key(self) -> str: return 'github_actions' @property - def commit(self): + def commit(self) -> str or None: if self._check_suites.__len__() > 0: return self._check_suites[0]["head_sha"] - else: - return None + return None + + @property + def branch(self) -> str or None: + if self._check_suites.__len__() > 0: + return self._check_suites[0]["head_branch"] + return None + + @property + def full_repo(self) -> str or None: + if self._check_suites.__len__() > 0: + return self._check_suites[0]['repository']['full_name'] + return None + + @property + def repo(self) -> str or None: + if self._check_suites.__len__() > 0: + return self._check_suites[0]['repository']['name'] + return None + + @property + def owner(self) -> str or None: + if self._check_suites.__len__() > 0: + return self._check_suites[0]['repository']['owner']['login'] + return None class PullRequest(base.AbstractGitHostObject, base.AbstractPullRequest): @@ -963,6 +955,18 @@ def status(self) -> Status: ) +class CheckSuiteEvent(base.AbstractGitHostObject): + SCHEMA = schema.CheckRunEvent + + @property + def commit(self) -> str: + return self.data['check_suite']['head_sha'] + + @property + def action(self) -> str: + return self.data['action'] + + class CheckRunEvent(base.AbstractGitHostObject): SCHEMA = schema.CheckRunEvent diff --git a/bert_e/server/webhook.py b/bert_e/server/webhook.py index d9de6fd2..bdf08524 100644 --- a/bert_e/server/webhook.py +++ b/bert_e/server/webhook.py @@ -113,6 +113,11 @@ def handle_github_check_run_event(bert_e, json_data): return CommitJob(bert_e=bert_e, commit=event.commit) +def handle_github_check_suite_event(bert_e, json_data): + event = github.CheckSuiteEvent(bert_e=bert_e.client, **json_data) + return CommitJob(bert_e=bert_e, commit=event.commit) + + @blueprint.route('/bitbucket', methods=['POST']) @requires_basic_auth def parse_bitbucket_webhook(): @@ -182,6 +187,8 @@ def parse_github_webhook(): job = handle_github_status_event(current_app.bert_e, json_data) elif event == 'check_run': job = handle_github_check_run_event(current_app.bert_e, json_data) + elif event == 'check_suite': + job = handle_github_check_run_event(current_app.bert_e, json_data) if job is None: LOG.debug('Ignoring event.')