"""Vérifie l'état du dernier run CI Gitea d'ObsiGate (lecture seule).""" import json import subprocess import sys import urllib.request REPO = "Projets/ObsiGate" BASE = f"https://git.dracodev.net/api/v1/repos/{REPO}" UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126 Safari/537.36" cred = subprocess.run( ["git", "credential", "fill"], input="protocol=https\nhost=git.dracodev.net\n\n", capture_output=True, text=True, cwd=r"C:\dev\git\python\ObsiGate", ) token = "" for line in cred.stdout.splitlines(): if line.startswith("password"): token = line.split("=", 1)[1] if not token: raise SystemExit("pas de jeton git disponible") sha = subprocess.run( ["git", "rev-parse", "HEAD"], capture_output=True, text=True, cwd=r"C:\dev\git\python\ObsiGate", ).stdout.strip() def get(path: str): req = urllib.request.Request( f"{BASE}{path}", headers={ "Authorization": f"token {token}", "Accept": "application/json", "User-Agent": UA, }, ) with urllib.request.urlopen(req, timeout=25) as resp: return json.load(resp) runs = get("/actions/runs?limit=10").get("workflow_runs", []) print(f"HEAD local : {sha[:8]} — {len(runs)} run(s) récent(s)") target = None for run in runs: head = str(run.get("head_sha") or "") title = run.get("display_title") or run.get("name") or "?" flag = " <== HEAD" if head.startswith(sha[:8]) else "" print(f" #{run.get('id')} {title[:60]} | {run.get('status')}/{run.get('conclusion')} | {head[:8]}{flag}") if head.startswith(sha[:8]) and target is None: target = run if target is None: print("Aucun run pour le HEAD courant (encore en file d'attente ?)") sys.exit(0) jobs_resp = get(f"/actions/runs/{target['id']}/jobs") print(f"run #{target['id']} : status={target.get('status')} conclusion={target.get('conclusion')} " f"started={target.get('run_started_at')} updated={target.get('updated_at')}") print(f"clés jobs: {list(jobs_resp)[:6]}") for job in jobs_resp.get("workflow_jobs", jobs_resp.get("jobs", [])) or []: print(f" - {job.get('name')}: {job.get('status')}/{job.get('conclusion')}") if job.get("status") != "completed": for step in job.get("steps", []) or []: print(f" · {step.get('name')}: {step.get('status')}/{step.get('conclusion')}") try: runners = get("/actions/runners") entries = runners.get("runners", runners) if isinstance(runners, dict) else runners print(f"runners: {len(entries) if isinstance(entries, list) else entries}") if isinstance(entries, list): for runner in entries: print(f" - {runner.get('name')} status={runner.get('status')} labels={runner.get('labels')}") except Exception as exc: # noqa: BLE001 print(f"runners indisponibles: {exc}")