mirror of
https://github.com/ArduPilot/ardupilot.git
synced 2026-10-06 19:00:27 +08:00
Tools: build_tests: name the commits and emit the table as json
The table says which commit it was built from and which it was compared against, and --json-output writes the same as data for the workflow that comments it on a pull request. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Barker
co-authored by
Claude Opus 5
parent
98b155533c
commit
08d11f1ca8
@@ -1,13 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
# AP_FLAKE8_CLEAN
|
||||
"""
|
||||
Aggregate per-board size diff JSON files (produced by size_diff_to_json.py)
|
||||
Aggregate per-board size diff JSON files (produced by pretty_diff_size.py)
|
||||
into a single Markdown summary table written to stdout.
|
||||
|
||||
Typical usage (from a GitHub Actions step):
|
||||
|
||||
python3 Tools/scripts/build_tests/global_size_summary.py \\
|
||||
--input-dir size-diffs/ >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
--json-output writes the same information as data:
|
||||
|
||||
{"base_commit": "<sha>",
|
||||
"failed_boards": ["<board>"],
|
||||
"rows": [{"board": "<board>",
|
||||
"binaries": {"<column>": {"delta": <int>, "identical": <bool>}}}]}
|
||||
|
||||
That file, not the Markdown, is what test_size_comment.yml gets: this script
|
||||
runs from the pull request's tree, so it validates every field above and renders
|
||||
its own table. The head commit is absent on purpose; it takes that from the
|
||||
event payload.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -31,6 +43,11 @@ COLUMNS = [
|
||||
|
||||
parser = ArgumentParser(description="Generate global size summary table.")
|
||||
parser.add_argument("--input-dir", required=True, help="Directory with per-board JSON files")
|
||||
parser.add_argument("--commit", default="", help="Commit hash the table was built from")
|
||||
parser.add_argument("--base-commit", default="", help="Commit hash the sizes are compared against")
|
||||
parser.add_argument("--failed-boards", default="",
|
||||
help="Boards whose job did not succeed, whitespace separated")
|
||||
parser.add_argument("--json-output", help="Also write the table as JSON to this path")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -56,7 +73,8 @@ def fmt_delta(entry):
|
||||
return str(delta)
|
||||
|
||||
|
||||
rows = []
|
||||
rows = [] # rendered cells, for the Markdown table
|
||||
data_rows = [] # the same boards as data, for --json-output
|
||||
for fname in sorted(os.listdir(args.input_dir)):
|
||||
if not fname.endswith(".json"):
|
||||
continue
|
||||
@@ -70,11 +88,24 @@ for fname in sorted(os.listdir(args.input_dir)):
|
||||
|
||||
board = data.get("board", os.path.splitext(fname)[0])
|
||||
binaries = data.get("binaries", {})
|
||||
row = [board] + [fmt_delta(binaries.get(col)) for col in COLUMNS]
|
||||
if not isinstance(binaries, dict):
|
||||
binaries = {}
|
||||
# a code span: a name of 7 or more hex characters would render as a link
|
||||
# to that commit instead
|
||||
row = ["`%s`" % board] + [fmt_delta(binaries.get(col)) for col in COLUMNS]
|
||||
rows.append(row)
|
||||
# known columns only, so the json has the shape the workflow validates
|
||||
data_rows.append({"board": board,
|
||||
"binaries": {col: binaries[col] for col in COLUMNS if col in binaries}})
|
||||
|
||||
if not rows:
|
||||
print("No size diff data found.", file=sys.stderr)
|
||||
# still hand the json over, or the last run's comment stands as current
|
||||
if args.json_output:
|
||||
with open(args.json_output, "w") as f:
|
||||
json.dump({"base_commit": args.base_commit,
|
||||
"failed_boards": sorted(set(args.failed_boards.split())),
|
||||
"rows": []}, f, indent=2)
|
||||
sys.exit(0)
|
||||
|
||||
header = ["Board"] + COLUMNS
|
||||
@@ -84,11 +115,37 @@ sep = [":---"] + [":---:" for _ in COLUMNS]
|
||||
lines = [
|
||||
"## Global Size Summary (Total Flash delta in bytes)",
|
||||
"",
|
||||
]
|
||||
# bare, so GitHub turns them into links to the commits. The pull request side
|
||||
# is built from its head rebased onto the base, not from the head as pushed.
|
||||
if args.commit and args.base_commit:
|
||||
lines += ["Built from %s rebased onto %s" % (args.commit, args.base_commit), ""]
|
||||
elif args.commit:
|
||||
lines += ["Built from %s" % args.commit, ""]
|
||||
elif args.base_commit:
|
||||
lines += ["Compared against %s" % args.base_commit, ""]
|
||||
lines += [
|
||||
"| " + " | ".join(header) + " |",
|
||||
"| " + " | ".join(sep) + " |",
|
||||
]
|
||||
for row in rows:
|
||||
lines.append("| " + " | ".join(str(c) for c in row) + " |")
|
||||
lines.append("")
|
||||
failed = sorted(set(args.failed_boards.split()))
|
||||
if failed:
|
||||
# a job that failed after uploading its sizes still has a row, so only the
|
||||
# boards without one are called out as missing
|
||||
boards = {row["board"] for row in data_rows}
|
||||
absent = [board for board in failed if board not in boards]
|
||||
note = "Jobs that did not succeed: %s" % ", ".join("`%s`" % b for b in failed)
|
||||
if absent:
|
||||
note += " (no sizes for %s)" % ", ".join("`%s`" % b for b in absent)
|
||||
lines += [note + ".", ""]
|
||||
|
||||
if args.json_output:
|
||||
with open(args.json_output, "w") as f:
|
||||
json.dump({"base_commit": args.base_commit,
|
||||
"failed_boards": failed,
|
||||
"rows": data_rows}, f, indent=2)
|
||||
|
||||
print("\n".join(lines))
|
||||
|
||||
Reference in New Issue
Block a user