Skip to content

Commit

Permalink
BERTE-565 BERTE-566 handle status check when workflow is pending, remove
Browse files Browse the repository at this point in the history
workflow dispatch checks
  • Loading branch information
tcarmet authored and erwan-b committed Apr 28, 2022
1 parent 0777b80 commit 1b920f5
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 238 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- run: git config --global --add safe.directory /__w/bert-e/bert-e
- run: tox -e utests
- run: tox -e tests-api-mock
- run: tox -e coverage-report
Expand All @@ -79,6 +80,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- run: git config --global --add safe.directory /__w/bert-e/bert-e
- run: tox -e tests-noqueue

all-tests:
Expand All @@ -91,6 +93,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- run: git config --global --add safe.directory /__w/bert-e/bert-e
- run: tox -e tests

lint:
Expand All @@ -103,5 +106,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- run: git config --global --add safe.directory /__w/bert-e/bert-e
- run: tox -e flake8
- run: helm lint charts/bert-e
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Change Log
All notable changes to this project will be documented in this file.

## [3.6.9] - 2022-04-25
# Fixed
- Handle GitHub Actions status when workflow is pending.
- Don't check workflow triggerd by "workflow_dispatch" event

## [3.6.8] - 2021-11-09
# Fixed
- Allways get the latest check-runs link status
Expand Down
115 changes: 93 additions & 22 deletions bert_e/git_host/github/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,9 @@ def get_commit_status(self, ref):
combined = AggregatedStatus.get(self.client,
owner=self.owner,
repo=self.slug, ref=ref)

actions = AggregatedCheckRuns.get(self.client,
owner=self.owner,
repo=self.slug, ref=ref)
actions = AggregatedCheckSuites.get(client=self.client,
owner=self.owner,
repo=self.slug, ref=ref)
combined.status[actions.key] = actions

except HTTPError as err:
Expand All @@ -377,7 +376,8 @@ def get_build_status(self, revision: str, key: str) -> str:
return status.state
try:
return self.get_commit_status(revision).status.get(key, None).state
except AttributeError:
except AttributeError as e:
LOG.error(e)
return 'NOTSTARTED'

def get_build_url(self, revision: str, key: str) -> str:
Expand Down Expand Up @@ -508,17 +508,39 @@ def __str__(self) -> str:
return self.state


class AggregatedCheckRuns(base.AbstractGitHostObject,
base.AbstractBuildStatus):
class WorkflowRun(base.AbstractGitHostObject):
"""
Endpoint to have access about workflows runs
"""
GET_URL = "/repos/{owner}/{repo}/actions/runs/{id}"
CREATE_URL = "/repos/{owner}/{repo}/actions/runs"
SCHEMA = schema.WorkflowRun


class AggregatedWorkflowRuns(base.AbstractGitHostObject):
GET_URL = "/repos/{owner}/{repo}/actions/runs"
SCHEMA = schema.AggregateWorkflowRuns

@property
def total_count(self):
return self.data['total_count']

@property
def workflow_runs(self):
return self.data['workflow_runs']


class AggregatedCheckSuites(base.AbstractGitHostObject,
base.AbstractBuildStatus):
"""
The Endpoint to have access infos about github actions runs
"""
GET_URL = '/repos/{owner}/{repo}/commits/{ref}/check-runs'
SCHEMA = schema.AggregateCheckRuns
GET_URL = '/repos/{owner}/{repo}/commits/{ref}/check-suites'
SCHEMA = schema.AggregateCheckSuites

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._check_runs = [elem for elem in self.data['check_runs']]
self._check_suites = [elem for elem in self.data['check_suites']]

@property
def url(self):
Expand All @@ -528,30 +550,79 @@ def sort_f(check_run):
return datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ')
return datetime(year=1962, month=1, day=1)

self.data['check_runs'].sort(key=sort_f, reverse=True)
self.data['check_suites'].sort(key=sort_f, reverse=True)

failed_c = [elem for elem in self.data['check_runs']
failed_c = [elem for elem in self.data['check_suites']
if elem['conclusion'] != 'success']
if len(failed_c):
return failed_c[0]['html_url']
elif len(failed_c) and len(self.data['check_runs']):
return self.data['check_runs'][0]['html_url']
elif len(failed_c) and len(self.data['check_suites']):
return self.data['check_suites'][0]['html_url']
return ''

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 list(
map(lambda elem: elem['check_suite_id'], workflow_runs)
)

def _get_aggregate_workflow_dispatched(self):
ref = self._check_suites[0]['head_sha']
repo = self._check_suites[0]['repository']['name']
owner = self._check_suites[0]['repository']['owner']['login']

return AggregatedWorkflowRuns.get(
client=self.client,
owner=owner, repo=repo, ref=ref,
params={
'event': 'workflow_dispatch',
'branch': self._check_suites[0]['head_branch']
})

def remove_unwanted_workflows(self):
"""
Remove two things:
- check-suites not triggerd by github-actions
- check-suites workflow triggerd by a `workflow_dispatch` event
"""
if self._check_suites.__len__() == 0:
return

response = self._get_aggregate_workflow_dispatched()
dispatched = self._get_check_suite_ids(response.workflow_runs)
while len(dispatched) < response.total_count:
response = self._get_aggregate_workflow_dispatched()
dispatched += self._get_check_suite_ids(response.workflow_runs)

self._check_suites = list(filter(
lambda elem: elem['id'] not in dispatched,
self._check_suites
))

self._check_suites = list(filter(
lambda elem: elem['app']['slug'] == 'github-actions',
self._check_suites
))

@property
def state(self):
self.remove_unwanted_workflows()
all_complete = all(
elem['status'] == 'completed' for elem in self._check_runs
elem['status'] == 'completed' for elem in self._check_suites
)
all_success = all(
elem['conclusion'] == 'success' or elem['conclusion'] == 'skipped'
for elem in self._check_runs
elem['conclusion'] == 'success'
for elem in self._check_suites
)
if self._check_runs.__len__() == 0:
if self._check_suites.__len__() == 0 or self.is_pending():
return 'NOTSTARTED'
elif self._check_runs.__len__() > 0 and not all_complete:
elif self._check_suites.__len__() > 0 and not all_complete:
return 'INPROGRESS'
elif self._check_runs.__len__() > 0 and all_complete and all_success:
elif self._check_suites.__len__() > 0 and all_complete and all_success:
return 'SUCCESSFUL'
else:
return 'FAILED'
Expand All @@ -566,8 +637,8 @@ def key(self) -> str:

@property
def commit(self):
if self._check_runs.__len__() > 0:
return self._check_runs[0]["head_sha"]
if self._check_suites.__len__() > 0:
return self._check_suites[0]["head_sha"]
else:
return None

Expand Down
23 changes: 23 additions & 0 deletions bert_e/git_host/github/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,22 @@ class Branch(Schema):
repo = fields.Nested(Repo)


class App(Schema):
id = fields.Int()
slug = fields.Str()
owner = fields.Nested(User)
name = fields.Str()
description = fields.Str()


class CheckSuite(Schema):
id = fields.Integer()
head_sha = fields.Str()
head_branch = fields.Str()
status = fields.Str()
conclusion = fields.Str(allow_none=True)
repository = fields.Nested(Repo)
app = fields.Nested(App)


class AggregateCheckSuites(Schema):
Expand All @@ -98,6 +109,18 @@ class CheckRun(Schema):
html_url = fields.Url()


class WorkflowRun(Schema):
id = fields.Integer()
head_sha = fields.Str()
head_branch = fields.Str()
status = fields.Str()


class AggregateWorkflowRuns(Schema):
total_count = fields.Integer()
workflow_runs = fields.Nested(WorkflowRun, many=True)


class AggregateCheckRuns(Schema):
total_count = fields.Integer()
check_runs = fields.Nested(CheckRun, many=True)
Expand Down
99 changes: 0 additions & 99 deletions eve/main.yml

This file was deleted.

Loading

0 comments on commit 1b920f5

Please sign in to comment.