|
| 1 | +# Drop this into a repo at .github/workflows/announce-pr.yml to make it a town-crier producer. |
| 2 | +# |
| 3 | +# Setup (once per repo or org): |
| 4 | +# - Variable TOWN_CRIER_URL = https://<app>.fly.dev |
| 5 | +# - Secret TOWN_CRIER_TOKEN = the bearer token minted for "github-action" |
| 6 | +# |
| 7 | +# Produces BOTH sides of a request's lifecycle, so the bus never drifts from GitHub: |
| 8 | +# - announce: when "Agent Review Requested" lands on a PR, tell the crier once. |
| 9 | +# - 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. |
| 12 | +# Joined harnesses pick up open requests from the bus — this workflow does NOT poll or review. |
| 13 | +name: town-crier producer (announce + resolve) |
| 14 | + |
| 15 | +on: |
| 16 | + pull_request: |
| 17 | + types: [labeled, closed] |
| 18 | + |
| 19 | +jobs: |
| 20 | + announce: |
| 21 | + if: github.event.action == 'labeled' && github.event.label.name == 'Agent Review Requested' |
| 22 | + runs-on: ubuntu-latest |
| 23 | + steps: |
| 24 | + - name: Announce to the crier |
| 25 | + env: |
| 26 | + CRIER_URL: ${{ vars.TOWN_CRIER_URL }} |
| 27 | + CRIER_TOKEN: ${{ secrets.TOWN_CRIER_TOKEN }} |
| 28 | + PR_URL: ${{ github.event.pull_request.html_url }} |
| 29 | + REPO: ${{ github.repository }} |
| 30 | + TITLE: ${{ github.event.pull_request.title }} |
| 31 | + REQUESTER: ${{ github.event.pull_request.user.login }} |
| 32 | + run: | |
| 33 | + # jq builds the JSON so a PR title with quotes can't break the payload. |
| 34 | + curl -fsS -X POST "$CRIER_URL/announce" \ |
| 35 | + -H "Authorization: Bearer $CRIER_TOKEN" \ |
| 36 | + -H "Content-Type: application/json" \ |
| 37 | + -d "$(jq -n \ |
| 38 | + --arg pr "$PR_URL" \ |
| 39 | + --arg repo "$REPO" \ |
| 40 | + --arg title "$TITLE" \ |
| 41 | + --arg requester "$REQUESTER" \ |
| 42 | + '{pr_url:$pr, repo:$repo, title:$title, requester:$requester}')" |
| 43 | +
|
| 44 | + resolve: |
| 45 | + if: github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'Agent Review Requested') |
| 46 | + runs-on: ubuntu-latest |
| 47 | + steps: |
| 48 | + - name: Resolve on the crier |
| 49 | + env: |
| 50 | + CRIER_URL: ${{ vars.TOWN_CRIER_URL }} |
| 51 | + CRIER_TOKEN: ${{ secrets.TOWN_CRIER_TOKEN }} |
| 52 | + PR_URL: ${{ github.event.pull_request.html_url }} |
| 53 | + MERGED: ${{ github.event.pull_request.merged }} |
| 54 | + run: | |
| 55 | + NOTE=$([ "$MERGED" = "true" ] && echo "merged" || echo "closed without merge") |
| 56 | + curl -fsS -X POST "$CRIER_URL/resolve" \ |
| 57 | + -H "Authorization: Bearer $CRIER_TOKEN" \ |
| 58 | + -H "Content-Type: application/json" \ |
| 59 | + -d "$(jq -n --arg pr "$PR_URL" --arg note "$NOTE" '{pr_url:$pr, note:$note}')" |
0 commit comments