Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions tools/verify-aot-autoinstrumentation-goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import sys
from pathlib import Path

from verify_helpers import remove_publish_outputs


ROOT = Path(__file__).resolve().parents[1]

Expand Down Expand Up @@ -125,6 +127,11 @@ def main() -> None:
action="store_true",
help='Run only the container-backed "real * demo" verifiers.',
)
parser.add_argument(
"--keep-publish",
action="store_true",
help="Keep artifacts/publish after a successful run (default: removed — pure verification byproduct, multiple GB over the full demo matrix).",
)
args = parser.parse_args()

if args.list:
Expand All @@ -150,6 +157,11 @@ def main() -> None:
if completed.returncode != 0:
raise SystemExit(f"{name} failed with exit code {completed.returncode}")

# Only reached when every selected verifier passed; failures SystemExit above and
# keep artifacts/publish around for inspection.
if not args.keep_publish:
print(remove_publish_outputs())

if commands == COMMANDS:
print("aot-autoinstrumentation-goal-ok")
else:
Expand Down
8 changes: 8 additions & 0 deletions tools/verify-aot-publish-gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import subprocess
from pathlib import Path

from verify_helpers import remove_publish_outputs

ROOT = Path(__file__).resolve().parents[1]
DEMOS_DIR = ROOT / "demos"
GENERATOR_PROJECT = (ROOT / "src" / "Qyl.OpenTelemetry.AutoInstrumentation.SourceGenerators"
Expand Down Expand Up @@ -186,6 +188,9 @@ def main() -> None:
parser.add_argument("--strict-promotion", action="store_true",
help="treat a promotion (vendor demo gone warning-clean) as a gate failure")
parser.add_argument("--list", action="store_true", help="print the classification and exit")
parser.add_argument("--keep-publish", action="store_true",
help="keep artifacts/publish after a passing gate (default: removed — "
"pure verification byproduct, multiple GB over the full matrix)")
args = parser.parse_args()

if args.list:
Expand Down Expand Up @@ -239,7 +244,10 @@ def main() -> None:
fh.write(f"\n**{failures} failure(s), {promotions} promotion(s)** over {len(rows)} demo(s).\n")

if failures:
# Keep artifacts/publish on failure so the offending binaries stay inspectable.
raise SystemExit(f"aot-publish-gate FAILED: {failures} failure(s), {promotions} promotion(s)")
if not args.keep_publish:
print(remove_publish_outputs())
print(f"aot-publish-gate-ok ({len(rows)} demos, {promotions} promotion notice(s))")


Expand Down
27 changes: 27 additions & 0 deletions tools/verify_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import os
import shutil
import subprocess
from pathlib import Path

Expand All @@ -9,6 +10,32 @@
PROPS_PATH = ROOT / "Directory.Build.props"


def remove_publish_outputs() -> str:
"""Delete artifacts/publish and return a one-line summary of what was freed.

The AOT demos must publish into the repo's standard artifacts/ layout (redirecting
via --artifacts-path breaks the prebuilt-Analyzer path contract — see
verify-aot-publish-gate.py publish()), so every demo run regrows ~50-150 MB there
and a full matrix leaves multiple GB behind. The publish tree is a pure verification
byproduct — each verifier executes the binary and asserts within the same run — so
successful gates drop it; failed gates keep it for inspection.
"""
publish_root = ROOT / "artifacts" / "publish"
if not publish_root.exists():
return "artifacts/publish absent — nothing to remove"

try:
size_bytes = sum(f.stat().st_size for f in publish_root.rglob("*") if f.is_file())
shutil.rmtree(publish_root)
except OSError as error:
# Best-effort hygiene: a locked file (AV scanner, IDE indexer, Windows handle)
# must not flip a passing gate into a false failure. Leave the remainder for
# the next run to sweep.
return f"artifacts/publish cleanup skipped: {error}"

return f"removed artifacts/publish ({size_bytes / (1024 * 1024):.0f} MB)"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved


def clean_env() -> dict[str, str]:
env = dict(os.environ)
for key in list(env):
Expand Down
Loading