698ef63e67
Co-authored-by: ayattara <alassane.yattara@savoirfairelinux.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Write generated Markdown within GitHub Actions' step-summary size limit."""
|
|
|
|
import argparse
|
|
import re
|
|
from pathlib import Path
|
|
|
|
|
|
FAILURE_IDENTITY = re.compile(r"<li>🔴<code>([^<]*)</code></li>")
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--input", type=Path, required=True)
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
parser.add_argument("--diagnostics-label", required=True)
|
|
parser.add_argument("--diagnostics-url", required=True)
|
|
parser.add_argument("--max-bytes", type=int, default=983_040)
|
|
return parser.parse_args()
|
|
|
|
|
|
def bounded_summary(
|
|
source: bytes,
|
|
*,
|
|
diagnostics_label: str,
|
|
diagnostics_url: str,
|
|
max_bytes: int,
|
|
) -> bytes:
|
|
source_text = source.decode("utf-8")
|
|
if len(source) <= max_bytes:
|
|
return source
|
|
|
|
notice = (
|
|
"> [!WARNING]\n"
|
|
"> This step summary was truncated to stay below GitHub Actions' "
|
|
"1 MiB limit. Full diagnostics are available in the "
|
|
f"[{diagnostics_label}]({diagnostics_url}) artifact.\n\n"
|
|
).encode("utf-8")
|
|
if len(notice) > max_bytes:
|
|
raise ValueError("max bytes is too small for the truncation notice")
|
|
|
|
prefix_budget = max_bytes - len(notice)
|
|
failure_identities = FAILURE_IDENTITY.findall(source_text)
|
|
identity_section = b""
|
|
if failure_identities:
|
|
identity_section = (
|
|
"## Failed test identities\n\n"
|
|
+ "\n".join(f"- `{identity}`" for identity in failure_identities)
|
|
+ "\n\n"
|
|
).encode("utf-8")
|
|
identity_section = (
|
|
identity_section[: max(0, prefix_budget)]
|
|
.decode("utf-8", errors="ignore")
|
|
.encode("utf-8")
|
|
)
|
|
|
|
prefix_budget -= len(identity_section)
|
|
# The full source is valid UTF-8, so ignoring errors can only discard a
|
|
# partial code point at the byte boundary.
|
|
prefix = source[:prefix_budget].decode("utf-8", errors="ignore").encode("utf-8")
|
|
return notice + identity_section + prefix
|
|
|
|
|
|
def main() -> int:
|
|
args = parse_args()
|
|
output = bounded_summary(
|
|
args.input.read_bytes(),
|
|
diagnostics_label=args.diagnostics_label,
|
|
diagnostics_url=args.diagnostics_url,
|
|
max_bytes=args.max_bytes,
|
|
)
|
|
args.output.write_bytes(output)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|