Skip to content

ci(town-crier): producer workflow (announce + resolve on close)#4

Merged
jasperboerhof merged 3 commits into
mainfrom
ci/town-crier-producer
Jun 20, 2026
Merged

ci(town-crier): producer workflow (announce + resolve on close)#4
jasperboerhof merged 3 commits into
mainfrom
ci/town-crier-producer

Conversation

@jasperboerhof

Copy link
Copy Markdown
Contributor

Adds the town-crier producer workflow — announce on the Agent Review Requested label, resolve on PR close (merged/closed).

The bus's resolve-by-pr_url endpoint is deployed (script-development/town-crier#14) and this repo's TOWN_CRIER_URL var + TOWN_CRIER_TOKEN secret are already provisioned, so it's ready to merge. Part of the producer rollout — keeps merged PRs from sitting open on the bus.

🤖 Generated with Claude Code

@jasperboerhof jasperboerhof added the Agent Review Requested Requesting review of specialized AI review agents. label Jun 20, 2026
@jasperboerhof

This comment has been minimized.

Comment thread .github/workflows/announce-pr.yml

@Goosterhof Goosterhof left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: concerns (no blockers) — 0 blockers / 2 concerns / 0 nits. CI green (check 8.4/8.5 pass; announce self-test passed, resolve skipped as expected).

Actions-security headline: clean. No injection vector — PR-author-controlled title/requester reach the shell through env: and are referenced as quoted --arg values inside jq, never interpolated into a run: string. Trigger is plain pull_request, not pull_request_target. Token is ${{ secrets.TOWN_CRIER_TOKEN }}, not hardcoded. No third-party actions to SHA-pin. This is the right shape.

Two non-blocking concerns and one confirmation of @jasperboerhof's own unlabeled note, all inline.

Findings

  • Concern — no permissions: block; the workflow inherits the broad repo default token for a job that only POSTs to an external bus (announce job).
  • Concerncurl -fsS hard-fails the step on any bus non-2xx/outage, reddening the PR's checks; the bus is fail-open by design.
  • Confirm (MINOR)@jasperboerhof's unlabeled-gap finding holds.

Automated war-room agent review — posted because this PR carries the Agent Review Requested label.

Comment thread .github/workflows/announce-pr.yml
Comment thread .github/workflows/announce-pr.yml
Comment thread .github/workflows/announce-pr.yml
Comment thread .github/workflows/announce-pr.yml
Goosterhof
Goosterhof previously approved these changes Jun 20, 2026

@Goosterhof Goosterhof left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 — since bec01bc7: 2 addressed, 0 new, 0 still open. Verdict: approve-worthy (0 blockers / 0 concerns / 0 nits). CI green (check 8.4/8.5 pass).

Both standing concerns from the prior round are closed by this head:

  • permissions: block — addressed. permissions: {} at line 16 drops the token to zero scopes, which is correct: neither job touches GITHUB_TOKEN (they auth to the bus with TOWN_CRIER_TOKEN). Stronger than the contents: read I'd have settled for.
  • Fail-open — addressed. continue-on-error: true on both the announce and resolve steps, plus --max-time 10 on both curls. A bus cold-start or 5xx now leaves the step red but the job green, so a town-crier hiccup no longer reds the PR's checks. curl -fsS still exits non-zero on a bus error, but continue-on-error is the right containment — the failure is visible in the run log without blocking merge.

Actions-security posture unchanged and clean: PR-author-controlled title/requester reach the shell only through env: and as quoted jq --arg values, never interpolated into a run: string; trigger is plain pull_request, not pull_request_target; token is ${{ secrets.TOWN_CRIER_TOKEN }}, not hardcoded; no third-party actions to SHA-pin.

One residual, unchanged and out of scope for an approve: the unlabeled-gap MINOR (@jasperboerhof's own note, which I confirmed last round) — types: [labeled, closed] means removing the label before close leaves the bus thread open. Author-acknowledged; not a blocker.

Automated war-room agent review — posted because this PR carries the Agent Review Requested label.

Comment thread .github/workflows/announce-pr.yml Outdated
Comment thread .github/workflows/announce-pr.yml

@Goosterhof Goosterhof left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 3 — since a788feb: config-error-loud/bus-open split — correct. Verdict: approve-worthy (0 blockers / 0 concerns / 0 nits). CI green (check 8.4/8.5 pass).

The single new commit replaces the prior round's blanket continue-on-error: true with an in-script split that distinguishes the two failure modes — which is exactly what closes the swallow-integration-zero trap I'd have worried about with a blanket tolerance:

  • Config error fails LOUD. Missing TOWN_CRIER_URL/TOWN_CRIER_TOKEN hits ::error:: + exit 1 (announce-pr.yml:43-44, :71-72), reddening the job so a misprovisioned repo in the rollout is discoverable.
  • Bus hiccup fails OPEN. With the secret present, a curl -fsS non-2xx/timeout falls to || echo "::warning::" (:57, :79), which exits 0 — step stays green, so a Fly cold-start or 5xx never reds a contributor's checks.

Removing continue-on-error and gating loud-vs-open purely in-script is the right call: a blanket continue-on-error would have swallowed the config exit 1 too. Anchored inline at the new guard.

Actions-security posture unchanged and clean: PR-author-controlled title/requester reach the shell only via env: and as quoted jq --arg values, never interpolated into a run: string; trigger is plain pull_request, not pull_request_target; token is ${{ secrets.TOWN_CRIER_TOKEN }}; permissions: {} holds; no third-party actions to SHA-pin.

The unlabeled-gap MINOR (@jasperboerhof's own note, confirmed in prior rounds) remains the one residual — types: [labeled, closed] leaves a label-removed-before-close thread open on the bus. Author-acknowledged, out of scope for this approve.

Automated war-room agent review — posted because this PR carries the Agent Review Requested label.

Comment thread .github/workflows/announce-pr.yml
Comment thread .github/workflows/announce-pr.yml
@jasperboerhof

Copy link
Copy Markdown
Contributor Author

Review Loop · 9/10 · PASS

kendo-report-tool #4 · AC anchor: PR description: town-crier producer workflow (announce on label, resolve on close) · head 5f147a378f

Tip

Reviewed the single new GitHub Actions workflow (announce-pr.yml) as the primary surface — injection vector, permissions, the two-mode failure policy, and the resolve-job close gate. The diff is clean: PR-author-controlled TITLE/REQUESTER reach the script only as quoted jq --arg values (no shell splice), permissions:{} correctly zeroes the unused GITHUB_TOKEN, and the config-error-loud / bus-hiccup-fail-open split is implemented exactly as documented. The one real correctness gap (a label-removed-before-close PR never fires /resolve, leaking an open bus thread) is already a colleague-confirmed MINOR thread on the PR, so it is not mine to re-derive or count.

No findings — clean against the review checklist.

Action

merge-ready

@jasperboerhof jasperboerhof merged commit 099a7e1 into main Jun 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Agent Review Requested Requesting review of specialized AI review agents.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants