#!/usr/bin/env python3 """Check that the pinned image tag was actually built (STATE-WP-0084-T02). A helm upgrade pinned to a tag no registry holds fails as a pre-upgrade hook timeout after ~5 minutes, and the message names a timeout rather than a missing image. The cause is easy to reach honestly: `.forgejo/workflows/image.yaml` has a `paths:` filter, so a chart-only commit is green in CI and builds nothing. A green pipeline is not evidence of an image. Exits non-zero if the pinned tag's commit never ran `build-and-push`. """ from __future__ import annotations import json import re import subprocess import sys import urllib.request from pathlib import Path VALUES = Path(__file__).resolve().parents[1] / "deploy/railiance/apps/helm/state-hub-values.yaml" API = "https://forgejo.coulomb.social/api/v1/repos/coulomb/state-hub/actions/tasks?limit=50" def main() -> int: m = re.search(r'^\s*tag:\s*"?main-([0-9a-f]{7,40})"?\s*$', VALUES.read_text(), re.M) if not m: print(f"could not read a main- tag from {VALUES}") return 2 sha = m.group(1) try: with urllib.request.urlopen(API, timeout=30) as r: runs = json.load(r).get("workflow_runs", []) except Exception as exc: # noqa: BLE001 - offline is inconclusive, not a failure print(f"could not reach the forge ({type(exc).__name__}); pin unverified") return 0 built = { run["head_sha"][:7] for run in runs if run.get("name") == "build-and-push" and run.get("status") == "success" } if sha[:7] in built: print(f"ok: main-{sha} was built by build-and-push") return 0 print(f"main-{sha} has no successful build-and-push run.") try: changed = subprocess.run( ["git", "show", "--name-only", "--format=", sha], capture_output=True, text=True, cwd=VALUES.parents[3], ).stdout.split() if changed and all(p.startswith("deploy/") or p.endswith(".md") for p in changed): print("It is a chart/docs-only commit, which the paths: filter excludes.") except Exception: # noqa: BLE001 pass recent = [r["head_sha"][:7] for r in runs if r.get("name") == "build-and-push"][:3] print(f"Most recent built commits: {', '.join(recent) or 'none found'}") return 1 if __name__ == "__main__": sys.exit(main())