Files
yao-meta-skill/scripts/ci_test.py
T
YAO 31ce04c655 Split meta skill CLI and review gates
Merge the beta-ready Yao Meta Skill architecture, report, evidence gate, and release-boundary updates.\n\nRelease boundary: beta/public testing is allowed; formal world-class, fully reviewed, or superiority claims remain blocked until the pending evidence gates are accepted.
2026-06-17 18:43:02 +08:00

163 lines
4.7 KiB
Python

#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
import tempfile
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SAFE_ENV_KEYS = (
"HOME",
"LANG",
"LC_ALL",
"PATH",
"PYTHONPATH",
"PYTHONIOENCODING",
"TEMP",
"TERM",
"TMP",
"TMPDIR",
"TZ",
)
DEFAULT_TARGETS = [
"eval",
"eval-suite",
"route-scorecard",
"route-confusion-check",
"description-optimization",
"description-optimization-check",
"promotion-check",
"python-compat-check",
"architecture-maintainability-check",
"yao-cli-check",
"yao-cli-world-class-check",
"skill-overview-check",
"skill-interpretation-check",
"skill-report-metrics-check",
"skill-report-charts-check",
"html-rendering-check",
"skill-ir-check",
"compiler-check",
"output-eval-check",
"output-execution-check",
"output-review-kit-check",
"output-review-adjudication-check",
"runtime-conformance-check",
"runtime-permission-check",
"trust-check",
"skill-atlas-check",
"registry-audit-check",
"package-verify-check",
"install-simulation-check",
"upgrade-check",
"review-viewer-check",
"review-studio-check",
"skill-os2-audit-check",
"skill-os2-coverage-check",
"world-class-evidence-check",
"world-class-ledger-check",
"world-class-intake-check",
"world-class-submission-kit-check",
"world-class-preflight-check",
"world-class-submission-review-check",
"world-class-runbook-check",
"world-class-claim-guard-check",
"benchmark-reproducibility-check",
"evidence-consistency-check",
"feedback-check",
"adaptation-safety-check",
"skillops-opportunity-check",
"daily-skillops-check",
"weekly-curator-check",
"adoption-drift-check",
"telemetry-import-check",
"telemetry-emit-check",
"telemetry-hooks-check",
"telemetry-native-host-check",
"review-waivers-check",
"review-annotations-check",
"baseline-compare-check",
"reference-scan-check",
"github-benchmark-scan-check",
"reference-synthesis-check",
"output-risk-profile-check",
"artifact-design-profile-check",
"prompt-quality-profile-check",
"system-model-check",
"iteration-directions-check",
"description-drift-history",
"iteration-ledger",
"regression-history",
"context-reports",
"portability-report",
"portability-check",
"failure-regression-check",
"package-check",
"package-failure-check",
"security-boundary-check",
"local-install-sync-check",
"snapshot-check",
"validate",
"lint",
"governance-check",
"resource-boundary-check",
"quality-check",
]
def tail_text(path: Path, max_lines: int) -> str:
lines = path.read_text(encoding="utf-8", errors="replace").splitlines()
if len(lines) <= max_lines:
return "\n".join(lines)
hidden = len(lines) - max_lines
tail = "\n".join(lines[-max_lines:])
return f"... truncated {hidden} earlier lines ...\n{tail}"
def run_target(target: str, index: int, total: int, tail_lines: int) -> None:
print(f"[{index}/{total}] {target}")
start = time.perf_counter()
with tempfile.NamedTemporaryFile(prefix=f"ci-{target}-", suffix=".log", delete=False) as handle:
log_path = Path(handle.name)
child_env = {key: os.environ[key] for key in SAFE_ENV_KEYS if key in os.environ}
child_env["CI"] = "1"
try:
with log_path.open("w", encoding="utf-8") as log_file:
proc = subprocess.run(
["make", "--silent", target],
cwd=ROOT,
stdout=log_file,
stderr=subprocess.STDOUT,
text=True,
env=child_env,
)
elapsed = time.perf_counter() - start
if proc.returncode != 0:
print(f"FAILED {target} ({elapsed:.1f}s)")
print(f"--- {target} log ---")
print(tail_text(log_path, tail_lines))
raise SystemExit(proc.returncode)
print(f"OK {target} ({elapsed:.1f}s)")
finally:
if log_path.exists():
log_path.unlink()
def main() -> None:
parser = argparse.ArgumentParser(description="Run CI test targets with compact logging.")
parser.add_argument("--tail-lines", type=int, default=200, help="How many log lines to show on failure.")
parser.add_argument("targets", nargs="*", default=DEFAULT_TARGETS, help="Optional target override.")
args = parser.parse_args()
total = len(args.targets)
for index, target in enumerate(args.targets, start=1):
run_target(target, index, total, args.tail_lines)
print(f"Completed {total} CI targets.")
if __name__ == "__main__":
main()