feat(3 U1): wire app screenshot capture into run_recipe_ci (best-effort, post-healthy, secret-safe; sets results.json screenshot)

This commit is contained in:
autonomic-bot
2026-05-31 06:56:20 +00:00
parent 18d2bd1443
commit 5fa15d4949

View File

@ -50,6 +50,7 @@ from harness import ( # noqa: E402
lifecycle,
naming,
results as results_mod,
screenshot as screenshot_mod,
warm,
warmsnap,
)
@ -914,6 +915,7 @@ def main() -> int:
results: dict[str, str] = {}
lifecycle.janitor()
dep_teardown_error: str | None = None
screenshot_rel: str | None = None # Phase 3 U1 (R4): set once the app screenshot is captured
try:
# ---- (Q3.2a) install-time OIDC: provision the warm-dep realm BEFORE the single deploy so
# install_steps.sh can read $CCCI_DEPS_FILE and wire the OIDC env into that one deploy. On
@ -963,6 +965,19 @@ def main() -> int:
print(f"!! deploy/readiness failed: {e}", flush=True)
deploy_ok = False
# ---- Phase 3 U1 (R4): capture a real app screenshot while the app is up, at the cleanest
# "freshly installed + healthy" moment (before any tier mutates state and before teardown).
# Placed OUTSIDE the deploy try/except so a screenshot issue can NEVER flip deploy_ok.
# Secret-safe by default (landing page, never a credentials page; recipes opt into a
# post-login view via a SCREENSHOT meta hook). Best-effort — capture() swallows all errors and
# returns None, so this never blocks or fails the run (R7). None → results.json `screenshot`
# stays null → the card shows the "no screenshot" placeholder (cosmetics never change verdict).
if deploy_ok:
shot = screenshot_mod.capture(
domain, screenshot_mod.screenshot_path(run_artifact_dir), recipe_meta=meta
)
screenshot_rel = os.path.basename(shot) if shot else None
# ---- INSTALL tier (always; additive generic + overlay, no op) ----
if "install" in stages:
results["install"] = (
@ -1213,6 +1228,7 @@ def main() -> int:
sso_unverified=sso_unverified,
clean_teardown=clean_teardown,
no_secret_leak=True, # narrowed below by an actual scan of the serialised artifact
screenshot=screenshot_rel, # Phase 3 U1 (R4): relative PNG name iff capture succeeded
finished_ts=time.time(),
)
# Real (if narrow) leak check: no known infra-secret value may appear in the artifact (R7).