-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
envoy.ci.report
: Add package (#2292)
Signed-off-by: Ryan Northey <[email protected]>
- Loading branch information
Showing
27 changed files
with
2,604 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
toolshed_package("envoy.ci.report") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
envoy.ci.report | ||
========================== | ||
|
||
Release publishing tool used in Envoy proxy's CI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
toolshed_library( | ||
"envoy.ci.report", | ||
dependencies=[ | ||
"//deps:reqs#abstracts", | ||
"//deps:reqs#aio.api.github", | ||
"//deps:reqs#aio.core", | ||
"//deps:reqs#aio.run.runner", | ||
], | ||
sources=[ | ||
"__init__.py", | ||
"ci.py", | ||
"cmd.py", | ||
"exceptions.py", | ||
"interface.py", | ||
"runner.py", | ||
"abstract/__init__.py", | ||
"abstract/filters.py", | ||
"abstract/format.py", | ||
"abstract/runner.py", | ||
"abstract/runs.py", | ||
], | ||
tags=["abstract-types"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
from . import abstract, exceptions, interface | ||
from .ci import CIRuns | ||
from .runner import ( | ||
CreationTimeFilter, JSONFormat, MarkdownFormat, | ||
ReportRunner, StatusFilter) | ||
from .cmd import cmd, main | ||
|
||
|
||
__all__ = ( | ||
"abstract", | ||
"CIRuns", | ||
"cmd", | ||
"CreationTimeFilter", | ||
"exceptions", | ||
"interface", | ||
"JSONFormat", | ||
"main", | ||
"MarkdownFormat", | ||
"ReportRunner", | ||
"StatusFilter") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# | ||
from .filters import ACreationTimeFilter, AStatusFilter, AWorkflowFilter | ||
from .format import AFormat, AJSONFormat, AMarkdownFormat | ||
from .runner import AReportRunner | ||
from .runs import ACIRuns | ||
|
||
|
||
__all__ = [ | ||
"ACIRuns", | ||
"ACreationTimeFilter", | ||
"AFormat", | ||
"AJSONFormat", | ||
"AMarkdownFormat", | ||
"AReportRunner", | ||
"AStatusFilter", | ||
"AWorkflowFilter", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
|
||
import argparse | ||
from datetime import datetime, timedelta | ||
from functools import cached_property | ||
|
||
import abstracts | ||
|
||
from envoy.ci.report import interface | ||
|
||
|
||
class AWorkflowFilter(metaclass=abstracts.Abstraction): | ||
|
||
def __init__(self, args: argparse.Namespace) -> None: | ||
self.args = args | ||
|
||
def __str__(self) -> str: | ||
return self.filter_string | ||
|
||
@property | ||
@abstracts.interfacemethod | ||
def filter_string(self) -> str: | ||
raise NotImplementedError | ||
|
||
|
||
@abstracts.implementer(interface.IWorkflowFilter) | ||
class AStatusFilter(AWorkflowFilter): | ||
|
||
@property | ||
def filter_string(self) -> str: | ||
if self.args.status == "all": | ||
return "" | ||
return self.args.status | ||
|
||
|
||
@abstracts.implementer(interface.IWorkflowFilter) | ||
class ACreationTimeFilter(AWorkflowFilter): | ||
|
||
@property | ||
def filter_string(self) -> str: | ||
if self.time_start_string and self.time_end_string: | ||
return f"{self.time_start_string}..{self.time_end_string}" | ||
elif self.time_start_string: | ||
return f">{self.time_start_string}" | ||
return "" | ||
|
||
@cached_property | ||
def now(self) -> datetime: | ||
return datetime.utcnow() | ||
|
||
@cached_property | ||
def start_day(self) -> datetime: | ||
return self.now.replace( | ||
hour=0, | ||
minute=0, | ||
second=0, | ||
microsecond=0) | ||
|
||
@cached_property | ||
def start_hour(self) -> datetime: | ||
return self.now.replace( | ||
minute=0, | ||
second=0, | ||
microsecond=0) | ||
|
||
@cached_property | ||
def start_week(self) -> datetime: | ||
return ( | ||
self.now | ||
- timedelta(days=self.now.weekday())).replace( | ||
hour=0, | ||
minute=0, | ||
second=0, | ||
microsecond=0) | ||
|
||
@cached_property | ||
def time_end(self) -> datetime | None: | ||
match self.args.previous: | ||
case "day": | ||
return self.start_day | ||
case "week": | ||
return self.start_week | ||
case "hour": | ||
return self.start_hour | ||
case _: | ||
return None | ||
|
||
@property | ||
def time_end_string(self) -> str: | ||
return ( | ||
self.time_end.strftime("%Y-%m-%dT%H:%M:%SZ") | ||
if self.time_end | ||
else "") | ||
|
||
@cached_property | ||
def time_start(self) -> datetime: | ||
match (self.args.current, self.args.previous): | ||
case ("day", _): | ||
return self.start_day | ||
case ("week", _): | ||
return self.start_week | ||
case ("hour", _): | ||
return self.start_hour | ||
case (_, "day"): | ||
return self.start_day - timedelta(days=1) | ||
case (_, "week"): | ||
return self.start_week - timedelta(weeks=1) | ||
case (_, "hour"): | ||
return self.start_hour - timedelta(hours=1) | ||
case _: | ||
# default max is 1 week | ||
# TODO: allow start/end times to be set directly | ||
return self.now - timedelta(hours=(24 * 7)) | ||
|
||
@property | ||
def time_start_string(self) -> str: | ||
return ( | ||
self.time_start.strftime("%Y-%m-%dT%H:%M:%SZ") | ||
if self.time_start | ||
else "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
|
||
import json | ||
from datetime import datetime | ||
|
||
import abstracts | ||
|
||
from envoy.ci.report import interface | ||
|
||
|
||
class AFormat(metaclass=abstracts.Abstraction): | ||
|
||
def __call__(self, data: dict) -> None: | ||
self.out(data) | ||
|
||
@abstracts.interfacemethod | ||
def out(self, data: dict) -> None: | ||
raise NotImplementedError | ||
|
||
|
||
@abstracts.implementer(interface.IFormat) | ||
class AJSONFormat(AFormat): | ||
|
||
def out(self, data: dict) -> None: | ||
print(json.dumps(data)) | ||
|
||
|
||
@abstracts.implementer(interface.IFormat) | ||
class AMarkdownFormat(AFormat): | ||
|
||
def out(self, data: dict) -> None: | ||
for commit, events in data.items(): | ||
self._handle_commit(commit, events) | ||
|
||
def _handle_commit(self, commit: str, events: list[dict]) -> None: | ||
outcome = ( | ||
"failed" | ||
if any(event["workflow"]["conclusion"] == "failure" | ||
for event | ||
in events) | ||
else "succeeded") | ||
target_branch = events[0]["request"]["target-branch"] | ||
commit_url = f"https://github.com/envoyproxy/envoy/commit/{commit}" | ||
print(f"[{target_branch}@{commit[:7]}]({commit_url}): {outcome}") | ||
for event in events: | ||
self._handle_event(event) | ||
|
||
def _handle_event(self, event: dict) -> None: | ||
event_type = event["event"] | ||
request_started = datetime.utcfromtimestamp( | ||
int(event["request"]["started"])).isoformat() | ||
workflow_name = event["workflow"]["name"] | ||
conclusion = event["workflow"]["conclusion"] | ||
workflow_id = event["workflow_id"] | ||
request_id = event["request_id"] | ||
workflow_url = ( | ||
"https://github.com/envoyproxy/envoy/" | ||
f"actions/runs/{workflow_id}") | ||
request_url = ( | ||
"https://github.com/envoyproxy/envoy/" | ||
f"actions/runs/{request_id}") | ||
print( | ||
f" -> [[{event_type}@{request_started}]({request_url})]: " | ||
f"[{workflow_name} ({conclusion})]({workflow_url})") |
Oops, something went wrong.