From d31378b180a67276c3af32c07c74e53da10c05e1 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Fri, 5 Jun 2026 17:06:43 +0000 Subject: [PATCH] =?UTF-8?q?feat(recipe-report):=20restructure=20page=20?= =?UTF-8?q?=E2=80=94=20priority-sorted=20wire=20table=20w/=20CVE=20column,?= =?UTF-8?q?=20addendum,=20per-recipe=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New page order: short lead -> the full wire table (sorted by priority-to-address, CVE recipes first, new CVEs count column) -> Addendum (bullets of real special issues, omitted if clean) -> Security Bulletin -> per-recipe "What changed". - recipe-report.py: _table() gains a CVEs column + recipe-name linking; new _changes() helper; render() reordered; docstring SPEC SHAPE updated (cve/addendum/changes added, needs_attention/routine removed). - recipe-report/SKILL.md + example-spec.json: new procedure, spec shape, and gold-standard template (2026-06-05, new format). - launch-report.py: kickoff text reflects the new priority-ordered structure. Co-Authored-By: Claude Opus 4.8 --- .claude/skills/recipe-report/SKILL.md | 63 +-- .../skills/recipe-report/example-spec.json | 428 +++++++++++++++++- cc-ci-plan/launch-report.py | 4 +- cc-ci-plan/recipe-report.py | 80 +++- 4 files changed, 528 insertions(+), 47 deletions(-) diff --git a/.claude/skills/recipe-report/SKILL.md b/.claude/skills/recipe-report/SKILL.md index eacb6e0..addf268 100644 --- a/.claude/skills/recipe-report/SKILL.md +++ b/.claude/skills/recipe-report/SKILL.md @@ -1,6 +1,6 @@ --- name: recipe-report -description: Generate the weekly public "Recipe Report" after the cc-ci /upgrade-all run. Reviews how the upgrade went and the state of every recipe + open PR, classifies what needs attention vs routine, and publishes a self-contained HTML page to report.ci.commoninternet.net (one page per week + a home index). Read-only — reports, never merges or edits PRs. Runs as its own agent (model configured separately from the upgrader; default opus). Invoke as /recipe-report [YYYY-MM-DD]. +description: Generate the weekly public "Recipe Report" after the cc-ci /upgrade-all run. Reviews how the upgrade went and the state of every recipe + open PR, and publishes a self-contained HTML page to report.ci.commoninternet.net (one page per week + a home index). Page order: short lead → the full wire table (priority-sorted, CVE-count column, CVE recipes first) → Addendum of special issues → Security Bulletin → per-recipe "what changed". Read-only — reports, never merges or edits PRs. Runs as its own agent (model configured separately from the upgrader; default opus). Invoke as /recipe-report [YYYY-MM-DD]. --- # recipe-report @@ -24,34 +24,45 @@ Helper: `python3 /srv/cc-ci/cc-ci-plan/recipe-report.py {survey|render|publish}` verdict; and each recipe's **per-recipe upgrade notes** (`upgrade_notes_md` — the breaking-change / **CVE / security** analysis the upgrade did). Read it all. -3. **Review & classify — this is a front page, write it like an editor.** - - **Security first.** Scan the per-recipe `upgrade_notes_md` + the summary (and use your own knowledge - of the version bumps) for upgrades that fix **CVEs / security issues**. Anything **critical/high** - leads the page → the `security` bulletin (recipe · CVE id(s) + severity · what it fixes · PR link). - This is the most important section; be specific about severity and what's exposed if not merged. - - **Lead / editorial.** Write the `lead` in opus's voice — useful, concrete, opinionated. **~3 short - paragraphs, ~150–180 words:** - 1. **Fleet state** in a line or two — how healthy, what moved, any trend. - 2. **What to focus on** — security/critical merges first, then the key failures. - 3. **Anything strange worth looking into** — odd or unexpected failures, parser snags, PR-state - oddities (e.g. a recipe carrying two open PRs to reconcile), drift from the summary, leftover - artifacts. This is the "editor's eye" paragraph; flag what a careful maintainer would want to notice. - Lead with the single most important thing; the rest of the page carries the detail. - - **Needs attention** — GREEN PRs ready to merge + errors/failures to investigate (RED `!testme`, - recipe bugs). Short, specific prose + links. Flag cross-cutting issues (e.g. two open PRs to reconcile). - - **Routine** — minor/clean bumps, stale-test PRs (need operator `--with-tests`), up-to-date / skipped. +3. **Review & classify.** The page order is: **short lead → the full wire table (priority-sorted) → + Addendum → Security Bulletin → per-recipe "What changed".** Same newspaper style; this order. + - **Security analysis.** Scan the per-recipe `upgrade_notes_md` + the summary (and use your own + knowledge of the version bumps) for upgrades that fix **CVEs / security issues**. For each recipe, + **count the CVEs** the PR fixes — this drives both the table's `cve` column and the priority sort. + Anything **critical/high** also gets a `security` bulletin entry (recipe · CVE id(s) + severity · + what it fixes · PR link); be specific about severity and what's exposed if not merged. + - **Lead — ONE short paragraph.** A tight, concrete opener in opus's voice: fleet state in a sentence + (how healthy, what moved) and what to address first. Lead with the single most important thing; the + table and sections carry all the detail. Do NOT write multiple paragraphs. + - **Priority sort for the table.** Order rows by **recommended priority to address**: + 1. recipes **with CVEs** first (more/higher-severity CVEs higher), + 2. then **FAILED** (RED) recipes, + 3. then **STALE**-test recipes, + 4. then routine **GREEN** bumps, + 5. then **UPTODATE / SKIPPED** last. + - **Addendum — special issues to look into.** A bullet list of real anomalies worth an operator's + eye: a recipe carrying **two open PRs** to reconcile, a **CI-run oddity** (flaky tier, needed + re-runs), drift between the summary and reality, a **misleading branch name**, a tooling snag that + silently drops a recipe, leftover artifact PRs, or **something in the test run that could be + improved**. **Only real issues — if everything looks clean, leave it empty; do NOT invent items.** + - **What changed — per recipe with a PR.** One short section per recipe that has a PR this week + describing what the upgrade actually changes (versions, notable deps, migrations/gotchas, reconcile + notes). Skip recipes with no PR. -4. **Write the spec** `/tmp/report-spec.json` (shape in the helper header): `date`, `subtitle` - ("Week of "), `lead` (the editorial, blank-line-separated paragraphs), `security[]` - (critical-CVE upgrades — may be empty), `needs_attention[]`, `routine[]`, and a **comprehensive - `table[]`** with EVERY recipe (`recipe`, `change` "a → b", `status` - GREEN/STALE/FAILED/SKIPPED/UPTODATE, `ci` as a level/result number+info string e.g. `build 154 ✓` - or `RED · restore` with `ci_url`, `pr`/`pr_url`, `notes`). **CI = link + number/info only; no images.** +4. **Write the spec** `/tmp/report-spec.json` (shape in the helper header): + - `date`, `subtitle` ("Week of "), + - `lead` — **one short paragraph**, + - `table[]` — EVERY recipe, **sorted by the priority above**. Fields: `recipe`, `change` "a → b", + `status` GREEN/FAILED/STALE/SKIPPED/UPTODATE, **`cve`** (integer count of CVEs this PR fixes; `0` + or omit for none), `ci` as a level/result number+info string e.g. `build 154 ✓` or `RED 200 · + install` with `ci_url`, `pr`/`pr_url`, `notes`. **CI = link + number/info only; no images.** + - `addendum[]` — list of bullet strings (may be empty), + - `security[]` — critical-CVE bulletin entries (may be empty), + - `changes[]` — `{recipe, body, links[]}`, one per recipe that has a PR. **Template — match this.** `.claude/skills/recipe-report/example-spec.json` is the gold-standard - example (the 2026-06-02 report; the operator approved its style/format). **Match its editorial voice, - structure, field shapes, and level of specificity** — the only deliberate change is the **shorter - `lead`** described above. Read it before writing your spec. + example (operator-approved style/format/voice). **Match its editorial voice, field shapes, and level + of specificity**, following the section order above. Read it before writing your spec. 5. **Render & publish.** `python3 .../recipe-report.py render /tmp/report-spec.json /tmp/week-.html` diff --git a/.claude/skills/recipe-report/example-spec.json b/.claude/skills/recipe-report/example-spec.json index fae67b0..0e0ada4 100644 --- a/.claude/skills/recipe-report/example-spec.json +++ b/.claude/skills/recipe-report/example-spec.json @@ -1 +1,427 @@ -{"date": "2026-06-02", "subtitle": "Week of June 2, 2026", "lead": "The recipe fleet is healthy this week. Of 18 recipes, eleven upgrades are !testme GREEN and ready to merge, two failed on genuine recipe bugs, and one waits on a stale-test refresh \u2014 a clean run overall.\n\nDo the security merges first: the nginx 1.29\u21921.31 bump closes a high-severity batch (heap overflows, request smuggling, an HTTP/3 spoofing flaw) and ships in custom-html and cryptpad, both green. Then triage the two reds \u2014 mattermost-lts and plausible \u2014 both pre-existing backup/restore bugs, not regressions from this week.\n\nWorth a closer look: four recipes \u2014 discourse, ghost, mattermost-lts, plausible \u2014 now carry two open PRs each (a fresh upgrade alongside an older backup fix) that want reconciling; immich and lasuite-drive both tripped abra's image-tag parser on digest-pinned / non-standard tags, a recurring format snag; and a stray recipe-create-pr smoke-test PR still lingers on bluesky-pds.", "security": [{"title": "nginx 1.31 \u2014 memory-safety + request-smuggling CVE batch (high) \u00b7 custom-html, cryptpad", "body": "Bumping the nginx sidecar from 1.29 to 1.31.1 closes a cluster of CVEs fixed in 1.31.0/1.31.1: heap buffer overflows in the rewrite module, data injection via proxy_set_body, an HTTP/3 address-spoofing flaw, and a use-after-free in the DNS/ssl_ocsp path. Two recipes ship the sidecar \u2014 custom-html (also alpine/git \u2192 v2.52.0) and cryptpad \u2014 and both are !testme GREEN. These are the highest-value merges of the week; do them first.", "links": [{"text": "custom-html PR #1 (build 163)", "url": "https://git.autonomic.zone/recipe-maintainers/custom-html/pulls/1"}, {"text": "cryptpad PR #4 (build 154)", "url": "https://git.autonomic.zone/recipe-maintainers/cryptpad/pulls/4"}]}, {"title": "mailu \u2014 Roundcube webmail CVE-2026-49217 (high) \u00b7 internet-facing", "body": "mailu 2024.06.37 \u2192 2024.06.52 rolls up the Roundcube security fix CVE-2026-49217 along with certdumper v2.11.2 and a redis 8.8 bump. Webmail is exposed on a mail host, so this one is worth prioritising. No config changes; !testme GREEN.", "links": [{"text": "mailu PR #1 (build 157)", "url": "https://git.autonomic.zone/recipe-maintainers/mailu/pulls/1"}]}, {"title": "uptime-kuma \u2014 authenticated RCE fix (high) \u00b7 plus MariaDB 12.3 major bump", "body": "uptime-kuma 2.2.1 \u2192 2.4.0 patches a remote-code-execution flaw in an upstream dependency (exploitable by authenticated users). It is bundled with a MariaDB 11.8 \u2192 12.3 major-version bump, so take a database backup before deploying if you run the mariadb overlay. !testme GREEN.", "links": [{"text": "uptime-kuma PR #2 (build 165)", "url": "https://git.autonomic.zone/recipe-maintainers/uptime-kuma/pulls/2"}]}, {"title": "redis 8.8 \u2014 CVE-2026-23479, CVE-2026-25243 (moderate) \u00b7 lasuite-meet, lasuite-docs", "body": "The redis 8.6.3 \u2192 8.8.0 bump carries several redis security patches, including CVE-2026-23479 and CVE-2026-25243. It ships in lasuite-meet (alongside the meet v1.16\u2192v1.17 app upgrade) and lasuite-docs. Redis is used purely as cache/session/pub-sub here, so the upgrade is drop-in. Both green.", "links": [{"text": "lasuite-meet PR #3 (build 156)", "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-meet/pulls/3"}, {"text": "lasuite-docs PR #4 (build 169)", "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-docs/pulls/4"}]}, {"title": "static-web-server \u2014 Basic-Auth timing attack CVE-2026-27480 (low/moderate) \u00b7 custom-html-tiny", "body": "static-web-server 2.38 \u2192 2.42 picks up CVE-2026-27480, a timing attack in Basic Auth fixed in v2.41.0. Note v2.41 also flips --ignore-hidden-files and --disable-symlinks on by default; this recipe serves an explicit -d path and is unaffected. !testme GREEN.", "links": [{"text": "custom-html-tiny PR #6 (build 164)", "url": "https://git.autonomic.zone/recipe-maintainers/custom-html-tiny/pulls/6"}]}], "needs_attention": [{"title": "Eleven green PRs await your merge", "body": "The merge-ready set: cryptpad, custom-html, custom-html-tiny, discourse, keycloak, lasuite-docs, lasuite-meet, mailu, n8n, and uptime-kuma \u2014 plus ghost, which the operator already resolved. discourse #2 is the late arrival: it is now !testme GREEN at build 179, clearing the stale-test RED (the allow_uncategorized_topics default flip) that the morning run had flagged. Full per-recipe detail in the wire below.", "links": []}, {"title": "mattermost-lts \u2014 RED on restore; a security patch is held hostage", "body": "The 10.11.19 ESR bump is correct and carries medium-severity security fixes, but !testme is RED at build 161 on test_restore_returns_state \u2014 a pre-existing backup/restore bug (the ci_marker row does not survive backup\u2192restore), not something this upgrade introduced. Three restore strategies were tried without success. A companion fix PR (#1, ci/pg-restore) is open; reconcile the pair. The security patch cannot land until restore is fixed.", "links": [{"text": "upgrade PR #2 (build 161 RED)", "url": "https://git.autonomic.zone/recipe-maintainers/mattermost-lts/pulls/2"}, {"text": "companion fix PR #1", "url": "https://git.autonomic.zone/recipe-maintainers/mattermost-lts/pulls/1"}]}, {"title": "plausible \u2014 RED on deploy after the pg13\u219216 + ClickHouse 24 jump", "body": "plausible 4.0.0+v2.1.5 (image moved Docker Hub \u2192 GHCR, postgres 13\u219216, ClickHouse 23.4\u219224.3) is RED at build 168. The ClickHouse IPv6-bind crash was fixed with an ipv4-only config, but the deploy still fails: Postgres appears to stay at 13 and the app gets NXDOMAIN for the events DB \u2014 most likely abra re-fetching the upstream compose over the PR head. A companion PR (#1, ci/clickhouse-backup-resilient) is also open and RED. Note: the v3.x-only CVE-2026-8467 does not affect this v2.1.5 target.", "links": [{"text": "upgrade PR #2 (build 168 RED)", "url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/2"}, {"text": "companion PR #1", "url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/1"}]}, {"title": "matrix-synapse \u2014 green except for one stale test; run --with-tests", "body": "synapse v1.149.1 \u2192 v1.153.0 (with mas 1.17, nginx 1.31.1, pgautoupgrade 17\u219218) is RED at build 158 only on test_upgrade_preserves_data \u2014 the ci_marker table is lost across the pg17\u219218 in-place upgrade. Everything else passes (reconverge, serving, backup, restore, /_matrix/client/versions 200), so the diagnosis is a stale CI test, not a broken upgrade. Refresh it with /recipe-upgrade matrix-synapse --with-tests.", "links": [{"text": "PR #1 (build 158 RED \u00b7 upgrade-test)", "url": "https://git.autonomic.zone/recipe-maintainers/matrix-synapse/pulls/1"}]}, {"title": "n8n \u2014 GREEN, but a mandatory migration rides with it", "body": "n8n 2.20.6 \u2192 2.23.2 is !testme GREEN at build 162, but the pgautoupgrade 17\u219218 bump requires the volume mount path to move from /var/lib/postgresql/data to /var/lib/postgresql, and an in-place pg_upgrade --link runs on first start. Back up the database first, and apply the path change on existing deployments \u2014 green here does not mean no-op for operators.", "links": [{"text": "n8n PR #4 (build 162)", "url": "https://git.autonomic.zone/recipe-maintainers/n8n/pulls/4"}]}, {"title": "ghost \u2014 already resolved since the run", "body": "Ghost now has no open PR. The operator merged the backup-fix PR (#1, which landed Ghost at 6.42.0-alpine and added a proper mysql restore hook) and closed the 6.43.1 PR (#3). Net effect: the data-loss-on-restore bug is fixed, but Ghost sits one patch behind the 6.43.1 the upgrader had proposed \u2014 a future run can re-offer that bump.", "links": [{"text": "merged PR #1", "url": "https://git.autonomic.zone/recipe-maintainers/ghost/pulls/1"}]}], "routine": [{"title": "Clean dependency bumps", "body": "keycloak 10.7.1 \u2192 10.8.0 (MariaDB 12.2 \u2192 12.3, app unchanged) and lasuite-docs 0.3.3 \u2192 0.3.4 (redis 8.8) are routine, no-operator-action bumps \u2014 both green. lasuite-meet also carries its meet v1.17.0 app upgrade with no required config changes.", "links": []}, {"title": "Skipped \u2014 already current", "body": "bluesky-pds, mumble, and lasuite-drive are up-to-date (drive's collabora/minio/onlyoffice tags are unparseable to abra, but its core images are at latest).", "links": []}, {"title": "immich \u2014 blocked by an abra tooling limit", "body": "immich was skipped: abra cannot parse its tag-plus-digest image references (e.g. ghcr.io/immich-app/postgres:14-vectorchord\u2026@sha256:\u2026), so the survey can't compute an upgrade. An explanatory comment was left on its open PR #1. This is a tooling gap, not a recipe fault.", "links": [{"text": "immich PR #1", "url": "https://git.autonomic.zone/recipe-maintainers/immich/pulls/1"}]}, {"title": "Infrastructure footnote", "body": "Eight recipes initially failed the survey with an abra go-git auth error (credentials must be embedded in the git origin URL, not via .netrc); all were recovered before the run completed. No fleet impact.", "links": []}], "table": [{"recipe": "cryptpad", "change": "0.5.4+v2026.2.0 \u2192 0.5.5+v2026.2.0", "status": "GREEN", "ci": "build 154 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/154", "pr": "#4", "pr_url": "https://git.autonomic.zone/recipe-maintainers/cryptpad/pulls/4", "notes": "nginx 1.29 \u2192 1.31 (CVE batch). Ready to merge."}, {"recipe": "custom-html", "change": "1.11.0+1.29.0 \u2192 1.13.0+1.31.1", "status": "GREEN", "ci": "build 163 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/163", "pr": "#1", "pr_url": "https://git.autonomic.zone/recipe-maintainers/custom-html/pulls/1", "notes": "nginx 1.31.1 CVEs + alpine/git v2.52.0. Ready to merge."}, {"recipe": "custom-html-tiny", "change": "1.0.1+2.38.0 \u2192 1.1.0+2.42.0", "status": "GREEN", "ci": "build 164 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/164", "pr": "#6", "pr_url": "https://git.autonomic.zone/recipe-maintainers/custom-html-tiny/pulls/6", "notes": "static-web-server 2.42 (Basic-Auth timing CVE)."}, {"recipe": "discourse", "change": "0.7.0+3.3.1 \u2192 0.8.0+3.5.0", "status": "GREEN", "ci": "build 179 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/179", "pr": "#2", "pr_url": "https://git.autonomic.zone/recipe-maintainers/discourse/pulls/2", "notes": "Now green \u2014 stale test cleared. pg13\u219216, backup fix, bitnami\u2192bitnamilegacy (archived mirror)."}, {"recipe": "ghost", "change": "1.2.0+6.21.2-alpine \u2192 1.3.0+6.42.0-alpine", "status": "UPTODATE", "ci": "merged", "pr": "#1", "pr_url": "https://git.autonomic.zone/recipe-maintainers/ghost/pulls/1", "notes": "Resolved by operator: #1 merged (backup fix, 6.42.0); 6.43.1 PR #3 closed."}, {"recipe": "keycloak", "change": "10.7.1+26.6.2 \u2192 10.8.0+26.6.2", "status": "GREEN", "ci": "build 155 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/155", "pr": "#2", "pr_url": "https://git.autonomic.zone/recipe-maintainers/keycloak/pulls/2", "notes": "MariaDB 12.2 \u2192 12.3. Clean."}, {"recipe": "lasuite-docs", "change": "0.3.3+v5.1.0 \u2192 0.3.4+v5.1.0", "status": "GREEN", "ci": "build 169 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/169", "pr": "#4", "pr_url": "https://git.autonomic.zone/recipe-maintainers/lasuite-docs/pulls/4", "notes": "redis 8.6.3 \u2192 8.8.0 (CVEs). Clean."}, {"recipe": "lasuite-meet", "change": "0.3.0+v1.16.0 \u2192 0.3.0+v1.17.0", "status": "GREEN", "ci": "build 156 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/156", "pr": "#3", "pr_url": "https://git.autonomic.zone/recipe-maintainers/lasuite-meet/pulls/3", "notes": "meet v1.17.0 + redis 8.8 (CVEs). Swagger routes now /api-prefixed."}, {"recipe": "mailu", "change": "3.0.1+2024.06.37 \u2192 3.0.1+2024.06.52", "status": "GREEN", "ci": "build 157 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/157", "pr": "#1", "pr_url": "https://git.autonomic.zone/recipe-maintainers/mailu/pulls/1", "notes": "Roundcube CVE-2026-49217 + certdumper v2.11.2 + redis 8.8."}, {"recipe": "matrix-synapse", "change": "7.1.1+v1.149.1 \u2192 7.2.0+v1.153.0", "status": "STALE", "ci": "RED 158 \u00b7 upgrade-test", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/158", "pr": "#1", "pr_url": "https://git.autonomic.zone/recipe-maintainers/matrix-synapse/pulls/1", "notes": "Stale test_upgrade_preserves_data (pg17\u219218 ci_marker loss). Run --with-tests."}, {"recipe": "mattermost-lts", "change": "2.1.10+10.11.18 \u2192 2.2.0+10.11.19", "status": "FAILED", "ci": "RED 161 \u00b7 restore", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/161", "pr": "#2", "pr_url": "https://git.autonomic.zone/recipe-maintainers/mattermost-lts/pulls/2", "notes": "Pre-existing restore bug; see companion #1. ESR carries a medium-severity security patch."}, {"recipe": "n8n", "change": "3.2.0+2.20.6 \u2192 3.3.0+2.23.2", "status": "GREEN", "ci": "build 162 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/162", "pr": "#4", "pr_url": "https://git.autonomic.zone/recipe-maintainers/n8n/pulls/4", "notes": "\u26a0 pg17\u219218: volume path /var/lib/postgresql/data \u2192 /var/lib/postgresql; back up first."}, {"recipe": "plausible", "change": "3.0.1+v2.0.0 \u2192 4.0.0+v2.1.5", "status": "FAILED", "ci": "RED 168 \u00b7 deploy", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/168", "pr": "#2", "pr_url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/2", "notes": "GHCR move + pg13\u219216 + ClickHouse 24. ClickHouse fixed; deploy still fails (pg re-fetch). See #1."}, {"recipe": "uptime-kuma", "change": "3.0.0+2.2.1 \u2192 4.0.0+2.4.0", "status": "GREEN", "ci": "build 165 \u2713", "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/165", "pr": "#2", "pr_url": "https://git.autonomic.zone/recipe-maintainers/uptime-kuma/pulls/2", "notes": "Authenticated RCE fix + MariaDB 11.8 \u2192 12.3 (back up first)."}, {"recipe": "bluesky-pds", "change": "\u2014", "status": "UPTODATE", "ci": "", "pr": "", "notes": "Up-to-date."}, {"recipe": "mumble", "change": "\u2014", "status": "UPTODATE", "ci": "", "pr": "", "notes": "Up-to-date."}, {"recipe": "lasuite-drive", "change": "\u2014", "status": "UPTODATE", "ci": "", "pr": "", "notes": "Up-to-date (some tags unparseable; core images at latest)."}, {"recipe": "immich", "change": "\u2014", "status": "SKIPPED", "ci": "", "pr": "#1", "pr_url": "https://git.autonomic.zone/recipe-maintainers/immich/pulls/1", "notes": "abra cannot parse tag+digest image pins; explanatory comment left on PR."}]} \ No newline at end of file +{ + "date": "2026-06-05", + "subtitle": "Week of June 5, 2026", + "lead": "A clean run: of 18 recipes, thirteen upgrades are !testme GREEN and merge-ready, custom-html landed directly upstream, three are up-to-date, and only plausible is red. The table below is ordered by what to address first — CVE-bearing PRs at the top (keycloak, the nginx batch, mailu, uptime-kuma), then the one failure, then routine bumps.", + "table": [ + { + "recipe": "keycloak", + "change": "10.7.1+26.6.2 → 10.8.0+26.6.3", + "status": "GREEN", + "cve": 16, + "ci": "build 187 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/187", + "pr": "#3", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/keycloak/pulls/3", + "notes": "Identity provider — 16 security fixes (OIDC/SAML/WebAuthn/LDAP) + MariaDB 12.2→12.3. Close superseded PR #2 (26.6.2)." + }, + { + "recipe": "lasuite-drive", + "change": "0.8.0+v0.18.0 → 0.9.0+v0.18.0", + "status": "GREEN", + "cve": 7, + "ci": "build 189 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/189", + "pr": "#1", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/lasuite-drive/pulls/1", + "notes": "nginx 1.30 → 1.31.1 (memory-safety + HTTP/3-spoofing CVE batch) + redis 8.6.4. Ready to merge." + }, + { + "recipe": "matrix-synapse", + "change": "7.1.1+v1.149.1 → 7.3.0+v1.154.0", + "status": "GREEN", + "cve": 7, + "ci": "build 192 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/192", + "pr": "#1", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/matrix-synapse/pulls/1", + "notes": "synapse v1.154.0 + nginx 1.31.1 (same CVE batch) + MAS 1.18 (device_code_grant now defaults false — set true if used) + pg17→18. Bridges deferred." + }, + { + "recipe": "mailu", + "change": "3.0.1+2024.06.37 → 3.0.1+2024.06.52", + "status": "GREEN", + "cve": 1, + "ci": "build 191 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/191", + "pr": "#1", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/mailu/pulls/1", + "notes": "Internet-facing Roundcube webmail CVE-2026-49217 + certdumper v2.11.2 + redis 8.0.6 (corrected from an unintended 8.8 jump)." + }, + { + "recipe": "uptime-kuma", + "change": "3.0.0+2.2.1 → 4.0.0+2.4.0", + "status": "GREEN", + "cve": 1, + "ci": "build 165 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/165", + "pr": "#2", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/uptime-kuma/pulls/2", + "notes": "Authenticated RCE fix (LiquidJS) + MariaDB 11.8 → 12.3 (back up the mariadb overlay first)." + }, + { + "recipe": "lasuite-meet", + "change": "0.3.0+v1.16.0 → 0.4.0+v1.19.0", + "status": "GREEN", + "cve": 1, + "ci": "build 190 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/190", + "pr": "#3", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/lasuite-meet/pulls/3", + "notes": "meet v1.19.0 (CVE-2026-45409 idna) + redis 8.6.4. Stale PR #4 closed. Ready to merge." + }, + { + "recipe": "custom-html-tiny", + "change": "1.0.1+2.38.0 → 1.1.0+2.42.0", + "status": "GREEN", + "cve": 1, + "ci": "build 164 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/164", + "pr": "#6", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/custom-html-tiny/pulls/6", + "notes": "static-web-server 2.42 (Basic-Auth timing CVE-2026-27480) + alpine/git v2.52.0. Ready to merge." + }, + { + "recipe": "plausible", + "change": "3.0.1+v2.0.0 → 4.0.0+v2.0.0", + "status": "FAILED", + "cve": 0, + "ci": "RED 200 · install", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/200", + "pr": "#2", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/2", + "notes": "pg 13→14 only (app stays v2.0.0, despite the v2.1.5 branch name). ClickHouse crash-loops every ~6s; v3 entrypoint may not redeploy. See companion PR #1 (also RED)." + }, + { + "recipe": "immich", + "change": "—", + "status": "SKIPPED", + "cve": 0, + "ci": "RED 121 · backup PR", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/121", + "pr": "#1", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/immich/pulls/1", + "notes": "abra can't parse tag+digest image pins, so no upgrade computed. Pre-existing backup-fix PR #1 sits RED at build 121." + }, + { + "recipe": "cryptpad", + "change": "0.5.5+v2026.2.0 → 0.6.0+v2026.5.1", + "status": "GREEN", + "cve": 0, + "ci": "build 181 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/181", + "pr": "#5", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/cryptpad/pulls/5", + "notes": "2026.5.1 office-corruption + security fixes; nginx already 1.31. SSO users: move SSO plugin to v0.5.0+. (Summary mis-filed it as skipped.)" + }, + { + "recipe": "discourse", + "change": "0.7.0+3.3.1 → 0.9.0+3.5.0", + "status": "GREEN", + "cve": 0, + "ci": "build 184 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/184", + "pr": "#2", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/discourse/pulls/2", + "notes": "discourse 3.5.0, redis 7.4→8.0, pg13→pgvector pg17 (manual dump/restore), bitnami→bitnamilegacy. Reconcile with fix PR #1. (183 flaked, 184 green.)" + }, + { + "recipe": "ghost", + "change": "1.3.0+6.42.0-alpine → 1.4.0+6.44.0-alpine", + "status": "GREEN", + "cve": 0, + "ci": "build 185 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/185", + "pr": "#4", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/ghost/pulls/4", + "notes": "ghost 6.44.0 (no breaking changes) + MySQL 8.0 → 8.4 LTS, in-place. Ready to merge." + }, + { + "recipe": "lasuite-docs", + "change": "0.3.4+v5.1.0 → 0.3.4+v5.2.0", + "status": "GREEN", + "cve": 0, + "ci": "build 188 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/188", + "pr": "#5", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/lasuite-docs/pulls/5", + "notes": "impress v5.2.0; auto-migration 0027; two optional new config vars. Clean." + }, + { + "recipe": "mattermost-lts", + "change": "2.1.10+10.11.18 → 2.1.11+10.11.19", + "status": "GREEN", + "cve": 0, + "ci": "build 196 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/196", + "pr": "#2", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/mattermost-lts/pulls/2", + "notes": "10.11.19 LTS patch; pg kept at 15 (16 broke PGDATA). Backup/restore reworked to inline labels (fixes a Swarm config-race). Reconcile with fix PR #1." + }, + { + "recipe": "n8n", + "change": "3.3.0+2.23.2 → 3.4.0+2.25.3", + "status": "GREEN", + "cve": 0, + "ci": "build 197 ✓", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/197", + "pr": "#5", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/n8n/pulls/5", + "notes": "n8n 2.25.3 ($jmespath unsafe-token hardening); pg unchanged at 18; no required migrations. Clean." + }, + { + "recipe": "custom-html", + "change": "1.11.0+1.29.0 → 1.13.0+1.31.1", + "status": "UPTODATE", + "cve": 0, + "ci": "build 182 ✓ · merged upstream", + "ci_url": "https://drone.ci.commoninternet.net/recipe-maintainers/cc-ci/182", + "pr": "", + "notes": "nginx 1.31.1 CVE batch + alpine/git v2.52.0 — merged directly into coopcloud upstream; mirror synced, PR #1 closed. No PR to action (CVEs already landed)." + }, + { + "recipe": "bluesky-pds", + "change": "—", + "status": "UPTODATE", + "cve": 0, + "ci": "", + "pr": "#1", + "pr_url": "https://git.autonomic.zone/recipe-maintainers/bluesky-pds/pulls/1", + "notes": "Up-to-date. Stray recipe-create-pr smoke-test PR #1 lingers — can be closed." + }, + { + "recipe": "mumble", + "change": "—", + "status": "UPTODATE", + "cve": 0, + "ci": "", + "pr": "", + "notes": "Up-to-date." + } + ], + "addendum": [ + "cryptpad is filed under “skipped / up-to-date” in the upgrade-all summary, yet it carries a green upgrade PR (#5, build 181). The run's counts double-count it (13+1+1+4 = 19 vs 18 considered) — worth fixing the survey's classification so a recipe with an open upgrade PR is never also counted as skipped.", + "Four recipes hold two open PRs each to reconcile: keycloak (#3 supersedes the older #2 — close #2), discourse (#2 upgrade + #1 bitnami→bitnamilegacy fix), mattermost-lts (#2 upgrade + #1 restore fix, now folded into #2), and plausible (#2 + #1, both RED). Decide which of each pair lands.", + "plausible's PR branch is named v2.1.5 but the actual change is a conservative pg13→14 (the app stays at v2.0.0). The misleading branch name is worth correcting so reviewers aren't misled.", + "plausible is RED: the clickhouse container restart-loops every ~6s at build 200. Either the CLICKHOUSE_ENTRYPOINT_VERSION=v3 config bump isn't being re-deployed under abra's --chaos deploy, or the 23.4.2.11-alpine image needs a version bump. Needs operator investigation — not a regression from the pg bump itself.", + "immich was skipped because abra can't parse its tag-plus-digest image pins (e.g. …postgres:14-vectorchord@sha256:…). This is a tooling gap in abra, not a recipe regression — but it silently removes immich from the weekly survey, and its pre-existing backup-fix PR #1 (RED at build 121) guards real data and deserves a look.", + "Backup-tier CI flakiness recurred this run: keycloak needed a re-run (186 backup flake → 187 green) and discourse did too (183 flake → 184 green). The recipe upgrades themselves are fine, but the backup tier is intermittently failing on first attempt — worth investigating to cut wasted re-runs.", + "Two non-upgrade PRs linger and can be closed: bluesky-pds #1 (a recipe-create-pr skill smoke test) and hedgedoc #1 (a cc-ci generic-suite probe, green at build 113). hedgedoc is not part of the 18-recipe fleet." + ], + "security": [ + { + "title": "nginx 1.31.1 — memory-safety + HTTP/3-spoofing CVE batch (high) · lasuite-drive, matrix-synapse", + "body": "The nginx 1.29/1.30 → 1.31.1 bump closes a cluster of CVEs fixed in 1.31.0/1.31.1: heap buffer overflows in the rewrite/scgi/uwsgi modules (CVE-2026-42945/42946/9256), a charset-decode overread (CVE-2026-42934), proxy_set_body data injection on HTTP/2 backends (CVE-2026-42926), an HTTP/3 connection-migration address-spoofing flaw (CVE-2026-40460), and a use-after-free in the ssl_ocsp/DNS path (CVE-2026-40701). It ships GREEN this week in lasuite-drive (1.30.0→1.31.1, also redis 8.6.4) and matrix-synapse (1.29.6→1.31.1). cryptpad and custom-html already run 1.31.x. nginx serves here as a standard reverse proxy / static server, so the 1.31.0 HTTP/2 hop-by-hop header rejection does not affect well-behaved clients. Highest-value merges of the week.", + "links": [ + { + "text": "lasuite-drive PR #1 (build 189)", + "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-drive/pulls/1" + }, + { + "text": "matrix-synapse PR #1 (build 192)", + "url": "https://git.autonomic.zone/recipe-maintainers/matrix-synapse/pulls/1" + } + ] + }, + { + "title": "keycloak 26.6.3 — sixteen security fixes on the identity provider (high) · keycloak", + "body": "keycloak 26.6.2 → 26.6.3 is a security patch release carrying sixteen fixes — including CVE issues across OIDC token handling, SAML processing, WebAuthn validation, and LDAP federation — plus a Quarkus 3.33.2 bump. As an identity provider fronting other services, keycloak is a high-priority merge. Bundled with a routine MariaDB 12.2 → 12.3 bump; no config changes required. !testme GREEN at build 187 (build 186 was a backup-tier flake). Note an older superseded upgrade PR (#2, 26.6.2) is still open — close it in favour of #3.", + "links": [ + { + "text": "keycloak PR #3 (build 187)", + "url": "https://git.autonomic.zone/recipe-maintainers/keycloak/pulls/3" + } + ] + }, + { + "title": "mailu — Roundcube webmail CVE-2026-49217 (high) · internet-facing", + "body": "mailu 2024.06.37 → 2024.06.52 rolls up the Roundcube security fix CVE-2026-49217 along with certdumper v2.11.2 and a redis 8.0.6 patch (corrected back from an unintended 8.8 jump). Webmail is exposed on a mail host, so this one is worth prioritising. No config changes; !testme GREEN at build 191.", + "links": [ + { + "text": "mailu PR #1 (build 191)", + "url": "https://git.autonomic.zone/recipe-maintainers/mailu/pulls/1" + } + ] + }, + { + "title": "uptime-kuma — authenticated RCE fix (high) · plus MariaDB 12.3 major bump", + "body": "uptime-kuma 2.2.1 → 2.4.0 patches a remote-code-execution flaw in the upstream LiquidJS dependency (exploitable by authenticated users; 2.2.1 had only a partial fix). It is bundled with a MariaDB 11.8 → 12.3 major-version bump on the mariadb overlay, so take a database backup before deploying that overlay. !testme GREEN at build 165 (head unchanged since 2026-06-02).", + "links": [ + { + "text": "uptime-kuma PR #2 (build 165)", + "url": "https://git.autonomic.zone/recipe-maintainers/uptime-kuma/pulls/2" + } + ] + }, + { + "title": "lasuite-meet — CVE-2026-45409 (moderate) · lasuite-meet", + "body": "lasuite-meet v1.16.0 → v1.19.0 picks up CVE-2026-45409 (idna ≥3.15, baked into the image) in v1.19.0, alongside a deprecated-LiveKit-room-options API replacement and a redis 8.6.4 patch. No breaking changes; AUTO_MIGRATIONS handles the DB. !testme GREEN at build 190.", + "links": [ + { + "text": "lasuite-meet PR #3 (build 190)", + "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-meet/pulls/3" + } + ] + } + ], + "changes": [ + { + "recipe": "keycloak", + "body": "10.7.1+26.6.2 → 10.8.0+26.6.3. A security patch release: sixteen fixes spanning OIDC token handling, SAML processing, WebAuthn validation and LDAP federation, plus a Quarkus 3.33.2 bump and a routine MariaDB 12.2 → 12.3. No config changes. An older superseded PR #2 (26.6.2) is still open — close it for #3.", + "links": [ + { + "text": "PR #3 (build 187)", + "url": "https://git.autonomic.zone/recipe-maintainers/keycloak/pulls/3" + } + ] + }, + { + "recipe": "lasuite-drive", + "body": "0.8.0 → 0.9.0 (drive app already at v0.18.0). nginx 1.30 → 1.31.1 brings in the memory-safety + HTTP/3-spoofing CVE batch; redis patched to 8.6.4. Clean GREEN.", + "links": [ + { + "text": "PR #1 (build 189)", + "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-drive/pulls/1" + } + ] + }, + { + "recipe": "matrix-synapse", + "body": "synapse v1.149.1 → v1.154.0, with MAS 1.14 → 1.18, nginx 1.31.1 (same CVE batch) and pgautoupgrade 17 → 18. One gotcha: MAS 1.18 changes device_code_grant_enabled to default false — set oauth.device_code_grant_enabled: true if you rely on device-code grants. The signal/telegram bridges and their pg13→17 dump/restore were deliberately deferred to a later PR.", + "links": [ + { + "text": "PR #1 (build 192)", + "url": "https://git.autonomic.zone/recipe-maintainers/matrix-synapse/pulls/1" + } + ] + }, + { + "recipe": "mailu", + "body": "2024.06.37 → 2024.06.52. Rolls up the Roundcube webmail fix CVE-2026-49217, certdumper v2.11.2, and a redis 8.0.6 patch (corrected back from an unintended 8.8 jump). Internet-facing — prioritise. No config changes.", + "links": [ + { + "text": "PR #1 (build 191)", + "url": "https://git.autonomic.zone/recipe-maintainers/mailu/pulls/1" + } + ] + }, + { + "recipe": "uptime-kuma", + "body": "2.2.1 → 2.4.0. Patches an authenticated RCE in the upstream LiquidJS dependency (2.2.1 had only a partial fix), bundled with a MariaDB 11.8 → 12.3 major bump — back up the mariadb overlay before deploying it.", + "links": [ + { + "text": "PR #2 (build 165)", + "url": "https://git.autonomic.zone/recipe-maintainers/uptime-kuma/pulls/2" + } + ] + }, + { + "recipe": "lasuite-meet", + "body": "v1.16.0 → v1.19.0. Picks up CVE-2026-45409 (idna ≥3.15), replaces a deprecated LiveKit room-options API, and patches redis to 8.6.4. AUTO_MIGRATIONS handles the DB; no breaking changes. Stale PR #4 was closed.", + "links": [ + { + "text": "PR #3 (build 190)", + "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-meet/pulls/3" + } + ] + }, + { + "recipe": "custom-html-tiny", + "body": "2.38.0 → 2.42.0. static-web-server 2.42 fixes the Basic-Auth timing leak CVE-2026-27480; alpine/git bumped to v2.52.0. Clean GREEN.", + "links": [ + { + "text": "PR #6 (build 164)", + "url": "https://git.autonomic.zone/recipe-maintainers/custom-html-tiny/pulls/6" + } + ] + }, + { + "recipe": "plausible", + "body": "A conservative postgres 13.12 → 14.18 in-place upgrade (the app stays at v2.0.0, despite the v2.1.5 branch name). RED across three runs: the clickhouse container restart-loops every ~6s at build 200. Two pre-existing recipe bugs were fixed along the way (a missing stack-prefixed CLICKHOUSE_DATABASE_URL and a fragile ClickHouse entrypoint), but the v3 entrypoint bump may not redeploy under abra --chaos, or the image needs bumping. Companion fix PR #1 is also RED.", + "links": [ + { + "text": "upgrade PR #2 (build 200 RED)", + "url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/2" + }, + { + "text": "companion fix PR #1 (build 122 RED)", + "url": "https://git.autonomic.zone/recipe-maintainers/plausible/pulls/1" + } + ] + }, + { + "recipe": "immich", + "body": "No upgrade was computed — abra can't parse immich's tag-plus-digest image pins, so it was skipped from the survey. Separately, its pre-existing backup-fix PR #1 (back up the postgres database, previously unprotected) is RED at build 121 and guards real data.", + "links": [ + { + "text": "PR #1 (build 121 RED)", + "url": "https://git.autonomic.zone/recipe-maintainers/immich/pulls/1" + } + ] + }, + { + "recipe": "cryptpad", + "body": "0.5.5+v2026.2.0 → 0.6.0+v2026.5.1. 2026.5.1 ships office-corruption and security fixes; nginx is already 1.31. SSO users must move the SSO plugin to v0.5.0+. (The upgrade-all summary mis-filed this as skipped/up-to-date.)", + "links": [ + { + "text": "PR #5 (build 181)", + "url": "https://git.autonomic.zone/recipe-maintainers/cryptpad/pulls/5" + } + ] + }, + { + "recipe": "discourse", + "body": "0.7.0+3.3.1 → 0.9.0+3.5.0. discourse 3.5.0, redis 7.4 → 8.0, postgres 13 → pgvector pg17 (manual dump/restore per the recipe README), and bitnami → bitnamilegacy after Docker Hub emptied bitnami/discourse. Reconcile with fix PR #1. (183 flaked, 184 green.)", + "links": [ + { + "text": "PR #2 (build 184)", + "url": "https://git.autonomic.zone/recipe-maintainers/discourse/pulls/2" + } + ] + }, + { + "recipe": "ghost", + "body": "6.42.0 → 6.44.0 (no breaking changes) plus a conservative MySQL 8.0 → 8.4 LTS in-place bump with no schema changes. Ready to merge.", + "links": [ + { + "text": "PR #4 (build 185)", + "url": "https://git.autonomic.zone/recipe-maintainers/ghost/pulls/4" + } + ] + }, + { + "recipe": "lasuite-docs", + "body": "0.3.4+v5.1.0 → 0.3.4+v5.2.0. impress v5.2.0 with auto-migration 0027 and two optional new config vars. Clean GREEN.", + "links": [ + { + "text": "PR #5 (build 188)", + "url": "https://git.autonomic.zone/recipe-maintainers/lasuite-docs/pulls/5" + } + ] + }, + { + "recipe": "mattermost-lts", + "body": "10.11.18 → 10.11.19 LTS patch. postgres kept at 15 (16 broke PGDATA). Backup/restore reworked to inline labels, fixing a Swarm config-race. Reconcile with fix PR #1 (the restore-was-a-no-op fix, now folded into #2).", + "links": [ + { + "text": "PR #2 (build 196)", + "url": "https://git.autonomic.zone/recipe-maintainers/mattermost-lts/pulls/2" + } + ] + }, + { + "recipe": "n8n", + "body": "3.3.0+2.23.2 → 3.4.0+2.25.3. Spans n8n 2.24/2.25 with a $jmespath unsafe-token hardening; postgres unchanged at 18; no required migrations. Clean.", + "links": [ + { + "text": "PR #5 (build 197)", + "url": "https://git.autonomic.zone/recipe-maintainers/n8n/pulls/5" + } + ] + }, + { + "recipe": "custom-html", + "body": "1.11.0+1.29.0 → 1.13.0+1.31.1. nginx 1.31.1 CVE batch + alpine/git v2.52.0 — but this one was merged directly into coopcloud upstream, so the mirror was synced and PR #1 closed. No PR to action; the CVE fixes have already landed.", + "links": [] + } + ] +} \ No newline at end of file diff --git a/cc-ci-plan/launch-report.py b/cc-ci-plan/launch-report.py index d30f363..b78915a 100755 --- a/cc-ci-plan/launch-report.py +++ b/cc-ci-plan/launch-report.py @@ -44,8 +44,8 @@ def build_kickoff(date): f"Full spec: {WORKDIR}/.claude/skills/recipe-report/SKILL.md. Creds in {WORKDIR}/.testenv; " f"reach the CI server with `ssh cc-ci`.\n" f"You are READ-ONLY: review the latest /upgrade-all run + every recipe's open PRs + CI verdicts, " - f"classify needs-attention vs routine, and publish one HTML page per run to " - f"report.ci.commoninternet.net (+ regenerate the index). Public page — NO secrets/tokens/raw logs. " + f"order the wire table by priority-to-address (CVE recipes first), and publish one HTML page per " + f"run to report.ci.commoninternet.net (+ regenerate the index). Public page — NO secrets/tokens/raw logs. " f"Never merge/edit/comment on PRs. When done, print the report URL + 'RECIPE REPORT COMPLETE' and " f"go idle (do NOT loop)." ) diff --git a/cc-ci-plan/recipe-report.py b/cc-ci-plan/recipe-report.py index 9d30a2d..ca44fb3 100755 --- a/cc-ci-plan/recipe-report.py +++ b/cc-ci-plan/recipe-report.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 """recipe-report — data + HTML helper for the weekly "Recipe Report" (/recipe-report skill). -A newspaper-style front page: masthead, an editorial LEAD (overall recipe-fleet state + what to focus -on), a SECURITY BULLETIN of critical-CVE upgrades up top, then needs-attention / routine, and the -comprehensive table ("the full wire") at the end. +A newspaper-style front page: masthead, a SHORT editorial LEAD, then the comprehensive table ("the +full wire" — priority-sorted, CVEs column), an ADDENDUM of special issues, a SECURITY BULLETIN, and a +per-recipe "what changed" section at the end. Subcommands (the /recipe-report agent runs them around its own review/classification): survey [DATE] JSON of the run + every recipe's open PRs + CI verdict + per-recipe upgrade @@ -11,14 +11,22 @@ Subcommands (the /recipe-report agent runs them around its own review/classifica render SPEC.json OUT.html render the agent's report spec -> a self-contained newspaper HTML page publish OUT.html DATE copy to cc-ci:/var/lib/cc-ci-reports/week-DATE.html and regen the archive index +Page order: short lead → the full wire table (priority-sorted, CVEs column) → Addendum → Security +Bulletin → per-recipe "What changed". + SPEC SHAPE (the agent writes this JSON): {"date":"YYYY-MM-DD","subtitle":"Week of ", - "lead":"", - "security":[{"title":"recipe — CVE-… (critical)","body":"what it fixes","links":[{"text":"PR #","url":"…"}]}], - "needs_attention":[{"title":"…","body":"…","links":[…]}], - "routine":[ {same shape} ], - "table":[{"recipe":"x","change":"a → b","status":"GREEN","ci":"build 154 ✓","ci_url":"…", - "pr":"#4","pr_url":"…","notes":"…"}]} + "lead":"", + "table":[{"recipe":"x","change":"a → b","status":"GREEN|FAILED|STALE|SKIPPED|UPTODATE", + "cve":16, # number of CVEs this PR fixes; 0/omit for none + "ci":"build 154 ✓","ci_url":"…","pr":"#4","pr_url":"…","notes":"…"}], + # ROWS SORTED by recommended priority to address — recipes WITH CVEs first, then failures, + # then stale-tests, then routine green, then up-to-date/skipped. + "addendum":["a special issue to look into (multiple open PRs, a CI-run oddity, a possible + improvement) …"], # only real issues — omit/empty if everything's clean + "security":[{"title":"recipe — CVE-… (high)","body":"what it fixes","links":[{"text":"PR #","url":"…"}]}], + "changes":[{"recipe":"x","body":"what changed in this recipe's PR","links":[{"text":"PR #4","url":"…"}]}]} + # one `changes` entry per recipe that has a PR this week. PUBLIC PAGE — include only public-safe data (no secrets/tokens/raw logs). """ import base64, html, json, os, re, subprocess, sys, urllib.request @@ -114,6 +122,11 @@ th{border-bottom:2px solid var(--rule);font-size:.72rem;text-transform:uppercase footer{margin-top:2.6rem;border-top:4px double var(--rule);padding-top:.8rem;font-size:.82rem;color:var(--mut);text-align:center} .idx{list-style:none;padding:0}.idx li{padding:.55rem 0;border-bottom:1px solid #d8d2c2;font-size:1.1rem} .idx .d{color:var(--mut);font-size:.85rem;float:right} +td .cve{color:var(--red);font-weight:800}.muted{color:#999} +.addendum-h{font-size:1rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin:1.7rem 0 .3rem;color:var(--ink)} +ul.addendum{margin:.2rem 0 1.2rem 1.2rem;padding:0}ul.addendum li{margin:.35rem 0;line-height:1.55} +.change{margin:.8rem 0;padding-bottom:.7rem;border-bottom:1px solid #d8d2c2} +.change .ch{font-weight:700;font-size:1.12rem}.change .cb{margin:.2rem 0 .35rem;color:#2b2b2b} """ @@ -148,25 +161,48 @@ def _stories(items, repo_url=None): f'
{lk(it.get("body"))}
{_links(it.get("links"))}' for it in items) -def _table(rows): +def _table(rows, repo_url=None): if not rows: return "" - head = "RecipeChangeStatusCIPRNotes" + head = ("RecipeChangeStatusCVEs" + "CIPRNotes") trs = [] for r in rows: scls = "s-" + str(r.get("status", "")).upper().replace("-", "").replace(" ", "") + name = _esc(r.get("recipe")) + if repo_url and r.get("recipe") in repo_url: + name = f'{name}' + cve = r.get("cve") + cve_cell = (f'{int(cve)}' if isinstance(cve, (int, float)) and cve + else 'none') ci = _esc(r.get("ci")) if r.get("ci_url"): ci = f'{ci}' pr = _esc(r.get("pr")) if r.get("pr_url"): pr = f'{pr}' - trs.append(f"{_esc(r.get('recipe'))}{_esc(r.get('change'))}" - f'{_esc(r.get("status"))}{ci}{pr}' - f"{_esc(r.get('notes'))}") + trs.append(f"{name}{_esc(r.get('change'))}" + f'{_esc(r.get("status"))}{cve_cell}' + f"{ci}{pr}{_esc(r.get('notes'))}") return f"{head}{''.join(trs)}
" +def _changes(items, repo_url=None): + """Per-recipe 'what changed' sections (one per recipe that has a PR).""" + if not items: + return "" + lk = (lambda x: _linkify_recipes(_esc(x), repo_url)) if repo_url else _esc + out = [] + for c in items: + name = c.get("recipe") + hdr = _esc(name) + if repo_url and name in repo_url: + hdr = f'{hdr}' + out.append(f'
{hdr}
' + f'
{lk(c.get("body"))}
{_links(c.get("links"))}
') + return "\n".join(out) + + def _page(title, body): return (f'' f'' @@ -195,12 +231,20 @@ def render(spec_path, out_path): f'' f'
{lead}
') + # 1) the full wire — every recipe, in the agent's recommended priority order (CVEs first); CVEs column. + body += f'

The full wire — every recipe, in priority order

{_table(s.get("table"), repo_url)}' + # 2) addendum — special issues to look into (normal-size header); omitted entirely if there are none. + add = [a for a in (s.get("addendum") or []) if str(a).strip()] + if add: + body += ('

Addendum

    ' + + "".join(f"
  • {_linkify_recipes(_esc(b), repo_url)}
  • " for b in add) + "
") + # 3) security bulletin if s.get("security"): body += ('
Security Bulletin
' - '

🔒 Critical CVE upgrades — merge first

' + _stories(s["security"], repo_url) + "
") - body += f'

⚑ Needs attention

{_stories(s.get("needs_attention"), repo_url)}' - body += f'

Routine

{_stories(s.get("routine"), repo_url)}
' - body += f'

The full wire — every recipe

{_table(s.get("table"))}' + '

🔒 Critical CVE upgrades

' + _stories(s["security"], repo_url) + "") + # 4) what changed — a short section per recipe that has a PR + if s.get("changes"): + body += f'

What changed

{_changes(s.get("changes"), repo_url)}' body += (f'') open(out_path, "w").write(_page("The Recipe Report — " + s["date"], body))