77# Produces BOTH sides of a request's lifecycle, so the bus never drifts from GitHub:
88# - announce: when "Agent Review Requested" lands on a PR, tell the crier once.
99# - resolve: when that PR closes/merges, retire its thread — otherwise a landed PR
10- # sits "open" on the bus forever (there is no GitHub->bus merge sync) and
11- # joined harnesses keep getting offered already-merged work.
10+ # sits "open" on the bus forever (there is no GitHub->bus merge sync).
1211# Joined harnesses pick up open requests from the bus — this workflow does NOT poll or review.
1312#
14- # The bus is fail-open: a town-crier hiccup (cold start, transient 5xx) must never red a
15- # PR's checks, so both jobs use continue-on-error + a curl --max-time. Neither job touches
16- # the GITHUB_TOKEN (they auth to the bus with TOWN_CRIER_TOKEN), so permissions are dropped.
13+ # Failure policy (two distinct modes, so a real problem is never silently masked):
14+ # - MISSING provisioning (no TOWN_CRIER_URL/TOKEN) is a config error -> fail LOUD (red).
15+ # - A bus HICCUP (cold start / transient 5xx / timeout) -> ::warning:: + stay GREEN (fail-open;
16+ # a coordination-layer blip must never red a contributor's PR checks).
17+ # Neither job uses the GITHUB_TOKEN (they auth to the bus with TOWN_CRIER_TOKEN), so permissions
18+ # are dropped to nothing.
1719name : town-crier producer (announce + resolve)
1820
1921permissions : {}
2830 runs-on : ubuntu-latest
2931 steps :
3032 - name : Announce to the crier
31- continue-on-error : true
3233 env :
3334 CRIER_URL : ${{ vars.TOWN_CRIER_URL }}
3435 CRIER_TOKEN : ${{ secrets.TOWN_CRIER_TOKEN }}
3738 TITLE : ${{ github.event.pull_request.title }}
3839 REQUESTER : ${{ github.event.pull_request.user.login }}
3940 run : |
41+ # Missing provisioning is a config error — fail LOUD so it can't pass silently.
42+ if [ -z "$CRIER_URL" ] || [ -z "$CRIER_TOKEN" ]; then
43+ echo "::error::town-crier not provisioned — set the TOWN_CRIER_URL variable + TOWN_CRIER_TOKEN secret"
44+ exit 1
45+ fi
4046 # jq builds the JSON so a PR title with quotes can't break the payload.
47+ # A bus hiccup is not the PR's fault — degrade to a warning, keep the check green.
4148 curl -fsS --max-time 10 -X POST "$CRIER_URL/announce" \
4249 -H "Authorization: Bearer $CRIER_TOKEN" \
4350 -H "Content-Type: application/json" \
@@ -46,22 +53,27 @@ jobs:
4653 --arg repo "$REPO" \
4754 --arg title "$TITLE" \
4855 --arg requester "$REQUESTER" \
49- '{pr_url:$pr, repo:$repo, title:$title, requester:$requester}')"
56+ '{pr_url:$pr, repo:$repo, title:$title, requester:$requester}')" \
57+ || echo "::warning::town-crier announce failed (transient bus issue?) — not blocking the PR"
5058
5159 resolve :
5260 if : github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'Agent Review Requested')
5361 runs-on : ubuntu-latest
5462 steps :
5563 - name : Resolve on the crier
56- continue-on-error : true
5764 env :
5865 CRIER_URL : ${{ vars.TOWN_CRIER_URL }}
5966 CRIER_TOKEN : ${{ secrets.TOWN_CRIER_TOKEN }}
6067 PR_URL : ${{ github.event.pull_request.html_url }}
6168 MERGED : ${{ github.event.pull_request.merged }}
6269 run : |
70+ if [ -z "$CRIER_URL" ] || [ -z "$CRIER_TOKEN" ]; then
71+ echo "::error::town-crier not provisioned — set the TOWN_CRIER_URL variable + TOWN_CRIER_TOKEN secret"
72+ exit 1
73+ fi
6374 NOTE=$([ "$MERGED" = "true" ] && echo "merged" || echo "closed without merge")
6475 curl -fsS --max-time 10 -X POST "$CRIER_URL/resolve" \
6576 -H "Authorization: Bearer $CRIER_TOKEN" \
6677 -H "Content-Type: application/json" \
67- -d "$(jq -n --arg pr "$PR_URL" --arg note "$NOTE" '{pr_url:$pr, note:$note}')"
78+ -d "$(jq -n --arg pr "$PR_URL" --arg note "$NOTE" '{pr_url:$pr, note:$note}')" \
79+ || echo "::warning::town-crier resolve failed (transient bus issue?) — not blocking the PR"
0 commit comments