Skip to content

Commit

Permalink
Github Action Annotations (Gamemode4Dev#972)
Browse files Browse the repository at this point in the history
* Adds a logger handler to create github action annotations on build logs
  • Loading branch information
SpecialBuilder32 authored Feb 26, 2024
1 parent 44963ae commit bcc44a0
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
3 changes: 2 additions & 1 deletion beet-release.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
pipeline:
- gm4.plugins.list_modules
- gm4.plugins.annotations
- gm4.plugins.manifest.create
- gm4.plugins.manifest.update_patch
- gm4.plugins.output.clear_release
- gm4.plugins.manifest.write_meta
- broadcast: 'gm4_*'
extend: 'beet.yaml'
require:
- gm4.plugins.annotations.add_module_dir_to_diagnostics
- gm4.plugins.output.release
- gm4.plugins.player_heads
- gm4_guidebook.generate_guidebooks.load_page_data
Expand Down
65 changes: 65 additions & 0 deletions gm4/plugins/annotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from beet import Context
import logging
import re
from functools import partial
from pathlib import Path

def beet_default(ctx: Context):
"""Sets up a logging handler to repeat build log entries with the github action annotation format"""
root_logger = logging.getLogger(None) # get root logger

handler = logging.StreamHandler()
handler.setFormatter(AnnotationFormatter())

def filter(record: logging.LogRecord):
if record.name == "time":
return False # disable annotations for time - is spammy in debug mode
return True

handler.addFilter(filter)

root_logger.handlers.clear() # clear the handler set by beet CLI toolchain
root_logger.addHandler(handler)

LEVEL_CONVERSION = {
logging.DEBUG: "debug",
logging.INFO: "notice",
logging.WARNING: "warning",
logging.ERROR: "error",
logging.CRITICAL: "error"
}

class AnnotationFormatter(logging.Formatter):

def format(self, record: logging.LogRecord) -> str:
expl = record.getMessage().replace("\n", "%0A")
# use urlencoded newline

level = LEVEL_CONVERSION.get(record.levelno, logging.INFO)

filename = None
line = None
col = None
match = re.match(r"(.+):(\d+):(\d+)", getattr(record, "annotate", ""))
if match:
filename, line, col = match.groups()
return f"::{level} file={filename},line={line},col={col},title={record.name}::{expl}"

return f"::{level} title={record.name}::{expl}"



def add_module_dir_to_diagnostics(ctx: Context):
"""Sets up a logging record filter that prepends the proper module folder to mecha diagnostics"""
local_filter = partial(add_mecha_subproject_dir, subproject_dir=ctx.directory.stem)
mc_logger = logging.getLogger("mecha")
mc_logger.addFilter(local_filter)

yield
mc_logger.removeFilter(local_filter) # clear the filter once done (after mecha)


def add_mecha_subproject_dir(record: logging.LogRecord, subproject_dir: str|Path = ""):
if d:=getattr(record, "annotate"):
record.annotate = f"{subproject_dir}/{d}" # modify record in place
return True

0 comments on commit bcc44a0

Please sign in to comment.