Skip to content

Commit 05b39af

Browse files
author
John Andersen
committed
policy engine: parse notices
Signed-off-by: John Andersen <[email protected]>
1 parent 97ebf7d commit 05b39af

File tree

1 file changed

+88
-27
lines changed

1 file changed

+88
-27
lines changed

scitt_emulator/policy_engine.py

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
sender:
145145
login: pdxjohnny
146146
webhook_workflow: |
147+
name: 'Webhook Workflow Name'
147148
on:
148149
push:
149150
branches:
@@ -154,7 +155,7 @@
154155
runs-on: ubuntu-latest
155156
steps:
156157
- run: |
157-
echo Hi
158+
echo ::error path=test.py::Hi
158159
```
159160
160161
```bash
@@ -213,6 +214,7 @@
213214
"""
214215
import os
215216
import io
217+
import re
216218
import sys
217219
import json
218220
import time
@@ -473,11 +475,12 @@ class GitHubWebhookEventSender(BaseModel):
473475
474476
jobs:
475477
test:
478+
name: "My Job"
476479
runs-on: self-hosted
477480
steps:
478-
- uses: actions/checkout@v4
479481
- run: |
480-
echo Hello World
482+
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
483+
echo "::error file=app.js,line=1,col=5,endColumn=7::Missing semicolon"
481484
"""
482485
)
483486

@@ -1019,6 +1022,52 @@ def step_io_update_stack_output_and_env_github_actions(context, request, step):
10191022
stack["env"].update(context_env_updates)
10201023

10211024

1025+
def step_parse_annotations_github_actions_line(context, step, line):
1026+
line = line.strip().strip("::")
1027+
annotation_level, message = line.split("::", maxsplit=1)
1028+
details = {
1029+
"message": message,
1030+
"raw_details": line,
1031+
}
1032+
if " " in annotation_level:
1033+
annotation_level, details_string = annotation_level.split(" ", maxsplit=1)
1034+
details.update(urllib.parse.parse_qsl(details_string.replace(",", "&")))
1035+
details["annotation_level"] = annotation_level
1036+
details_items = list(details.items())
1037+
for key, value in details_items:
1038+
del details[key]
1039+
key = re.sub(r'(?<!^)(?=[A-Z])', '_', key).lower()
1040+
details[key] = value
1041+
return GitHubCheckSuiteAnnotation.model_validate(details)
1042+
1043+
1044+
def step_parse_annotations_github_actions(context, step, step_annotations_string):
1045+
# TODO Groups
1046+
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines
1047+
return [
1048+
step_parse_annotations_github_actions_line(
1049+
context,
1050+
step,
1051+
line,
1052+
)
1053+
for line in step_annotations_string.split("\n")
1054+
if line.startswith("::")
1055+
]
1056+
1057+
1058+
def step_io_update_stack_annotations_github_actions(context, request, step):
1059+
stack = request.context["stack"][-1]
1060+
for annotation in itertools.chain(
1061+
step_parse_annotations_github_actions(
1062+
context,
1063+
step,
1064+
pathlib.Path(stack["console_output"]).read_text(),
1065+
)
1066+
):
1067+
stack["annotations"].setdefault(annotation.annotation_level, [])
1068+
stack["annotations"][annotation.annotation_level].append(annotation)
1069+
1070+
10221071
def execute_step_uses(context, request, step):
10231072
stack = request.context["stack"][-1]
10241073

@@ -1060,6 +1109,11 @@ def execute_step_uses(context, request, step):
10601109
request,
10611110
step,
10621111
)
1112+
step_io_update_stack_annotations_github_actions(
1113+
context,
1114+
request,
1115+
step,
1116+
)
10631117
try:
10641118
completed_proc.check_returncode()
10651119
except Exception as error:
@@ -1151,6 +1205,11 @@ def execute_step_run(context, request, step):
11511205
request,
11521206
step,
11531207
)
1208+
step_io_update_stack_annotations_github_actions(
1209+
context,
1210+
request,
1211+
step,
1212+
)
11541213

11551214
try:
11561215
completed_proc.check_returncode()
@@ -1230,6 +1289,9 @@ def celery_run_workflow_context_stack_push(context, request, stack):
12301289
def celery_run_workflow_context_stack_pop(context, request):
12311290
# TODO Deal with ordering of lines by time, logging module?
12321291
popped_stack = request.context["stack"].pop()
1292+
for annotation in itertools.chain(*popped_stack["annotations"].values()):
1293+
request.context["annotations"].setdefault(annotation.annotation_level, [])
1294+
request.context["annotations"][annotation.annotation_level].append(annotation)
12331295
request.context["console_output"].append(
12341296
[
12351297
popped_stack["stack_path"],
@@ -1283,6 +1345,8 @@ async def celery_run_workflow_context_init(
12831345
request.context["stack"] = []
12841346
if force_init or "console_output" not in request.context:
12851347
request.context["console_output"] = []
1348+
if force_init or "annotations" not in request.context:
1349+
request.context["annotations"] = {}
12861350
if force_init or "_init" not in request.context:
12871351
request.context["_init"] = True
12881352
for extra_init in context.extra_inits:
@@ -1717,11 +1781,11 @@ async def async_celery_run_workflow(context, request):
17171781
job_error = Exception(job_error)
17181782
raise job_error
17191783

1720-
17211784
detail = PolicyEngineComplete(
17221785
id="",
17231786
exit_status=PolicyEngineCompleteExitStatuses.SUCCESS,
17241787
outputs={},
1788+
annotations=request.context["annotations"],
17251789
)
17261790
request_status = PolicyEngineStatus(
17271791
status=PolicyEngineStatuses.COMPLETE,
@@ -2168,13 +2232,13 @@ async def test_read_main(
21682232

21692233

21702234
class GitHubCheckSuiteAnnotation(BaseModel):
2171-
path: str
2172-
annotation_level: str
2173-
title: str
2174-
message: str
2175-
raw_details: str
2176-
start_line: int
2177-
end_line: int
2235+
path: str = ""
2236+
annotation_level: str = ""
2237+
title: str = ""
2238+
message: str = ""
2239+
raw_details: str = ""
2240+
start_line: int = 0
2241+
end_line: int = 0
21782242

21792243

21802244
async def async_workflow_run_github_app_gidgethub(
@@ -2247,17 +2311,6 @@ async def async_workflow_run_github_app_gidgethub(
22472311
warning_count = 0
22482312
notice_count = 0
22492313
annotations = []
2250-
annotations.append(
2251-
GitHubCheckSuiteAnnotation(
2252-
path="somepath",
2253-
annotation_level="warning",
2254-
title="",
2255-
message="",
2256-
raw_details="",
2257-
start_line=0,
2258-
end_line=0,
2259-
)
2260-
)
22612314

22622315
if hasattr(context.state, "github_app"):
22632316
# GitHub App, use check-runs API
@@ -2274,12 +2327,19 @@ async def async_workflow_run_github_app_gidgethub(
22742327
.strftime("%Y-%m-%dT%H:%M:%SZ"),
22752328
"output": {
22762329
"title": request.workflow.name,
2277-
"summary": "There are {failure_count} failures, {warning_count} warnings, and {notice_count} notices.",
2330+
"summary": f"There are {failure_count} failures, {warning_count} warnings, and {notice_count} notices.",
22782331
"text": "",
2279-
"annotations": [
2280-
json.loads(annotation.model_dump_json())
2281-
for annotation in annotations
2282-
],
2332+
"annotations": list(
2333+
itertools.chain(
2334+
[
2335+
[
2336+
json.loads(annotation.model_dump_json())
2337+
for annotations in annotations[annotation_level]
2338+
]
2339+
for annotation_level in annotations
2340+
]
2341+
)
2342+
),
22832343
"images": [
22842344
{
22852345
"alt": "Super bananas",
@@ -2311,6 +2371,7 @@ async def async_workflow_run_github_app_gidgethub(
23112371
id="",
23122372
exit_status=PolicyEngineCompleteExitStatuses.SUCCESS,
23132373
outputs={},
2374+
annotations=request.context["annotations"],
23142375
)
23152376
request_status = PolicyEngineStatus(
23162377
status=PolicyEngineStatuses.COMPLETE,

0 commit comments

Comments
 (0)