Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
30e7805
CHORE: Add paired profiler benchmarks and PR regression reports
bewithgaurav Sep 10, 2026
665e659
FIX: Repair hosted profiler setup and CI wait budgets
bewithgaurav Sep 11, 2026
b505deb
FIX: Complete profiler CI samples and isolate incomplete reports
bewithgaurav Sep 15, 2026
019b75e
FIX: Repair profiler CI against latest main
bewithgaurav Sep 15, 2026
f5779f4
FIX: Stabilize profiler CI reporting and macOS tests
bewithgaurav Sep 16, 2026
5ed1792
FIX: Authenticate profiler reporting inputs
bewithgaurav Sep 16, 2026
8c8e3dd
REFACTOR: Organize PR performance reporting
bewithgaurav Sep 16, 2026
00da039
FIX: Finalize and bound performance reports
bewithgaurav Sep 16, 2026
e2997e0
FIX: Isolate performance artifact timeouts
bewithgaurav Sep 16, 2026
04c62ba
FIX: Harden profiler CI orchestration
Copilot Sep 17, 2026
14a3677
Merge branch 'main' into bewithgaurav/profiler-ci
bewithgaurav Sep 17, 2026
43b2669
REFACTOR: Deepen profiler report assessment
bewithgaurav Sep 17, 2026
234b7f0
Merge remote-tracking branch 'origin/main' into bewithgaurav/profiler-ci
bewithgaurav Sep 17, 2026
a2dde75
FIX: Complete profiler CI review hardening
bewithgaurav Sep 17, 2026
31f34cb
FIX: Close profiler CI validation gaps
bewithgaurav Sep 17, 2026
c1b9ab8
FIX: Harden profiler artifact finalization
bewithgaurav Sep 17, 2026
dd7a951
FIX: Scope profiler CI to pull requests
bewithgaurav Sep 17, 2026
650c31e
FIX: Finalize profiler CI readiness
bewithgaurav Sep 17, 2026
f565b1b
FIX: Bound profiler CI to current PR runs
Copilot Sep 17, 2026
0a96092
FIX: Select Windows profiler tasks by reason
Copilot Sep 17, 2026
1b44b27
FIX: Normalize interrupted profiler responses
Copilot Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/scripts/extract_coverage_artifact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Copy one expected coverage report from a ZIP without extracting archive paths."""

import argparse
from pathlib import Path, PurePosixPath
import stat
import zipfile

MAX_ARCHIVE_FILES = 10_000
MAX_ARCHIVE_BYTES = 256 * 1024 * 1024
MAX_REPORT_BYTES = 64 * 1024 * 1024


def select(archive, kind):
members = archive.infolist()
if (
len(members) > MAX_ARCHIVE_FILES
or sum(member.file_size for member in members) > MAX_ARCHIVE_BYTES
):
raise ValueError("Coverage artifact exceeds size limits")

candidates = []
for member in members:
path = PurePosixPath(member.filename)
if (
member.is_dir()
or stat.S_ISDIR(member.external_attr >> 16)
or path.is_absolute()
or ".." in path.parts
or "\\" in member.filename
or member.flag_bits & 1
or stat.S_ISLNK(member.external_attr >> 16)
or member.file_size > MAX_REPORT_BYTES
):
continue
if kind == "html" and path.name == "index.html" and "Code Coverage Report" in str(path):
candidates.append((0, member))
elif kind == "xml" and path.suffix.lower() == ".xml":
name = path.name.lower()
if str(path).endswith("unified-coverage/coverage.xml"):
priority = 0
elif name == "coverage.xml":
priority = 1
elif "coverage" in name:
priority = 2
else:
continue
candidates.append((priority, member))

if not candidates:
raise ValueError(f"No coverage {kind} report found")
priority = min(item[0] for item in candidates)
selected = [member for rank, member in candidates if rank == priority]
return selected


def copy_report(archive_path, output, kind):
if Path(archive_path).stat().st_size > MAX_ARCHIVE_BYTES:
raise ValueError("Coverage archive exceeds size limit")
with zipfile.ZipFile(archive_path) as archive:
selected = select(archive, kind)
Comment thread
bewithgaurav marked this conversation as resolved.
data = archive.read(selected[0])
if any(archive.read(member) != data for member in selected[1:]):
raise ValueError(f"Conflicting coverage {kind} reports")
Path(output).write_bytes(data)


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("kind", choices=("html", "xml"))
parser.add_argument("archive", type=Path)
parser.add_argument("output", type=Path)
args = parser.parse_args()
copy_report(args.archive, args.output, args.kind)


if __name__ == "__main__":
main()
Loading
Loading