ci(town-crier): producer workflow (announce + resolve on close)#36
Conversation
This comment has been minimized.
This comment has been minimized.
Goosterhof
left a comment
There was a problem hiding this comment.
Agent Review — COMMENT (no blockers)
Actions-security headline: clean. The injection vector this rollout had to get right — PR-author-controlled title reaching a run: shell — is handled correctly: every event field is passed through env: and consumed via jq -n --arg, never interpolated into the shell. Trigger is plain pull_request (no pull_request_target), no PR code is checked out, and the token comes from ${{ secrets.TOWN_CRIER_TOKEN }}. Nothing to pin — there are no third-party uses: actions, just curl.
Counts: 0 blockers, 2 concerns, 0 nits.
Findings index
- Concern — no
permissions:block; both jobs inherit the repo-defaultGITHUB_TOKENscope a pure-egress producer never uses (announce-pr.yml:20). - Concern —
curl -fsShard-fails the run on any bus non-2xx; the bus is fail-open by design, so a Fly hiccup reddens every labeled/closed PR in the repo (announce-pr.yml:34).
Both are inline. Neither blocks merge.
Automated war-room agent review — posted because this PR carries the Agent Review Requested label.
Goosterhof
left a comment
There was a problem hiding this comment.
Round 2 — since e225f9e: 2 addressed, 0 new, 0 still open
APPROVE — both standing concerns from the prior round are fixed and the Actions-security surface is unchanged-clean.
Delta:
- Addressed —
permissions: {}is now declared at the workflow top level (announce-pr.yml:16). A pure-egress producer that never touchesGITHUB_TOKENnow grants it nothing. Correct least-privilege. - Addressed — both jobs carry
continue-on-error: true(announce-pr.yml:24,announce-pr.yml:54).curl -fsSstill fails the step on a bus non-2xx, butcontinue-on-errorkeeps the job green, so a Fly hiccup no longer reds every labeled/closed PR in the repo. Fail-open is preserved at the job boundary, which is the right level for it.
Unchanged-clean (no re-litigation): title and other PR-author fields reach the script through env: + jq -n --arg, never interpolated into the shell — no injection vector. Trigger is plain pull_request (no pull_request_target), no PR head code is checked out, token from ${{ secrets.TOWN_CRIER_TOKEN }}, no third-party uses: to pin.
Counts: 0 blockers, 0 concerns, 0 nits. CI green (check (8.4), check (8.5)).
The header comment's promise — "permissions are dropped" and "continue-on-error + a curl --max-time" — now matches the YAML. Description claims the TOWN_CRIER_URL var + TOWN_CRIER_TOKEN secret are provisioned in this repo; that's the one thing unverifiable from outside, and if either is missing the producer 401s/no-ops silently rather than failing loudly (acceptable given the fail-open design, but worth a one-time post-merge confirmation that a labeled PR actually lands on the bus).
Automated war-room agent review — posted because this PR carries the Agent Review Requested label.
Goosterhof
left a comment
There was a problem hiding this comment.
Round 3 — since 3535b3b: config-error-loud / bus-open split — correct
APPROVE — the new guard implements the loud-vs-open split the right way round, and the Actions-security surface is unchanged-clean. No blockers, no concerns, no nits.
Verdict: approve-worthy · Blockers 0 · Concerns 0 · Nits 0
Delta of interest (the only thing new this round): the missing-provisioning guard. A config error (absent TOWN_CRIER_URL/TOWN_CRIER_TOKEN) now exit 1s loud and red; a transient bus error (5xx / timeout / refused, secret present) still degrades to a ::warning:: and keeps the check green. The two are not conflated — see inline.
Standing concerns from prior rounds — confirmed still resolved:
permissions: {}at the workflow level (line 16) — both jobs run with noGITHUB_TOKENscope. Correct; they auth to the bus withTOWN_CRIER_TOKEN, not the repo token.- Fail-open-on-bus-hiccup preserved (
|| echo "::warning::..."on both curls).
Actions-security headline: clean. title is env:-passed and consumed through jq -n --arg (no shell interpolation of PR-author data); trigger is plain pull_request with no head checkout; token from secrets.; no third-party uses: to SHA-pin.
Automated war-room agent review — posted because this PR carries the Agent Review Requested label.
Review Loop · 9/10 · PASS — 🟡 1phpstan-warroom-rules #36 · AC anchor: PR description: town-crier producer workflow (announce on label, resolve on close) · head Tip Reviewed the new announce-pr.yml producer workflow against its stated intent (announce-on-label, resolve-on-close) — the two failure modes are correctly split (provisioning missing → fail loud exit 1; bus hiccup → fail-open warning), permissions are dropped to {}, and jq builds the payload so a quoted title can't break it; no rule-set/contract change so no consumer ripple. Clean, with one soft completeness edge on the un-label-then-close path. 1 finding(s) posted inline:
Actionmerge-ready |
Adds the town-crier producer workflow — announce on the
Agent Review Requestedlabel, resolve on PR close (merged/closed).The bus's resolve-by-
pr_urlendpoint is deployed (script-development/town-crier#14) and this repo'sTOWN_CRIER_URLvar +TOWN_CRIER_TOKENsecret are already provisioned, so it's ready to merge. Part of the producer rollout — keeps merged PRs from sittingopenon the bus.🤖 Generated with Claude Code