#!/usr/bin/env python3 """Generate Part 2 of the report FROM the evidence file, so the table cannot drift from it.""" import json, io, os HERE = os.path.dirname(os.path.abspath(__file__)) d = json.load(open(os.path.join(HERE, "demo-updates.json"), encoding="utf-8")) mv = json.load(open(os.path.join(HERE, "moves.json"), encoding="utf-8")) out = [] out.append("## Part 2 — the promotion train\n") out.append("### The moves\n") out.append("Fifteen commits, one per app, `catalog_since: \"%s\"` on each. Every gate run before " "each commit; nothing forced, nothing dropped. `check-image-resolvable.py` confirms all " "18 unique pins still exist upstream.\n" % mv["catalog_since"]) out.append("| app | move | commit |") out.append("|---|---|---|") for app, human, h in mv["moved"]: out.append("| `%s` | %s | `%s` |" % (app, human, h)) out.append("| `nextcloud` | **ENGINE** `mariadb:11.6` -> `mariadb:12.3` | `39374d5` |") out.append("") out.append("### The guarded Update, pressed on both demo boxes\n") for box, rec in d.items(): out.append("#### `%s` — %s\n" % (box, rec["base"])) if rec["not_installed"]: out.append("**Not installed on this box, so not pressed:** %s.\n" % ", ".join("`%s`" % a for a in rec["not_installed"])) out.append("| app | badge before (HU / EN) | phases | pin after | installed after | front-door state |") out.append("|---|---|---|---|---|---|") for app, a in rec["apps"].items(): bh = "; ".join(t["text"] for t in a["badge_before_hu"]["tags"]) or "—" be = "; ".join(t["text"] for t in a["badge_before_en"]["tags"]) or "—" ph = " → ".join("`%s` +%.1fs" % (p["phase"], p["t"]) for p in a["update"]["phases"]) or "—" pin = (a["after"]["pinned_images"] or {}).get(app, "—") ins = ((a["after"]["insta" "lled_images"] or {}).get(app) or {}).get("ref", "—") st = a["after"]["state"] out.append("| `%s` | `%s` / `%s` | %s | `%s` | `%s` | `%s` |" % (app, bh, be, ph, pin, ins, st)) out.append("") out.append("Page after the update, as the household reads it:\n") for app, a in rec["apps"].items(): hu = (a["page_after_hu"]["context"] or "").strip() en = (a["page_after_en"]["context"] or "").strip() out.append("- **`%s`** — HU: *%s*" % (app, hu[:170])) out.append(" EN: *%s*" % en[:170]) out.append("") io.open(os.path.join(HERE, "PART2.md"), "w", encoding="utf-8").write("\n".join(out) + "\n") print("\n".join(out)[:1500])