Repository navigation
Hosted launch metrics: aggregate counters, ref attribution, admin view #967
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Generated by tend 0.3.14. Regenerate with: uvx tend@latest init | |
| # | |
| # Do not edit this file directly — it will be overwritten on regeneration. | |
| # To change this workflow, edit .config/tend.yaml. To change what the agent | |
| # does, edit the relevant skill (for example, `running-tend`) in this repo's | |
| # .claude/skills/ directory, or open an issue at | |
| # https://github.com/max-sixty/tend/issues for changes that need to | |
| # happen upstream in the tend-ci-runner plugin. | |
| name: tend-mention-relay | |
| # Review events for tend-mention. Their runs carry `refs/pull/N/merge`, which | |
| # the operational secrets' environment does not admit, so this workflow holds | |
| # no secret: it re-posts each event as a `repository_dispatch`, which starts | |
| # tend-mention on the default branch. It is a workflow of its own because | |
| # GitHub lists every job of a review event's run among the PR's checks, skipped | |
| # jobs included, so the run holds only the job that can execute. Same-repo PRs | |
| # only — the notifications poll covers fork PRs. | |
| on: | |
| pull_request_review: | |
| types: [submitted] | |
| # Not `created`: GitHub also fires `pull_request_review` for every new inline | |
| # comment (probed across the comments endpoint, the replies endpoint, the | |
| # "Add single comment" button, and reviews submitted with inline comments), | |
| # so subscribing would relay each one twice. An edit fires no review event, | |
| # so `edited` stays, to catch "@bot" added to an existing comment. | |
| pull_request_review_comment: | |
| types: [edited] | |
| jobs: | |
| # Move the event onto a ref the environment admits, and nothing else. The | |
| # merge ref itself can never be admitted — a same-repo `pull_request` run | |
| # executes the PR head's own workflow files on that same ref, so admitting | |
| # it would hand a pushed workflow the secrets the environment exists to | |
| # deny. All judgement lives in tend-mention's `verify`, which re-reads the | |
| # review or comment from the API, so a skipped event costs one extra short | |
| # run rather than a second copy of the heuristics here. | |
| relay: | |
| # Fork PRs are excluded to hold long-standing behaviour: the notifications | |
| # poll covers them, and it applies author-association tiers that this path | |
| # does not. What the filter buys is that no fork head is checked out into a | |
| # secret-bearing run; it is not an authorship gate, since a mention from | |
| # any user with read access already wakes `handle` on a same-repo PR. | |
| # Widening this is a separate decision, and moot while a fork run's token | |
| # is refused the dispatch POST (403, probed). | |
| # | |
| # This job boots no agent, but it carries the pause check anyway: a paused | |
| # repo's tend-mention skips everything it would dispatch, so running it | |
| # would only spend a runner, the dispatch POST, and a second empty run. | |
| if: >- | |
| vars.TEND_ENABLED != 'false' && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| runs-on: ubuntu-24.04 | |
| # No secrets here. `contents: write` is what the dispatch POST needs, and | |
| # is the whole of what this token can do — probed both ways on a live | |
| # repo: an otherwise identical same-repo run declaring `contents: read` | |
| # is refused with 403, so a narrower token would leave every review | |
| # mention unanswered rather than merely unprivileged. It grants nobody a | |
| # new capability: only someone who can already push a branch can open the | |
| # same-repo PR whose workflow file this is, and they could declare any | |
| # permissions they liked in it. The merge restriction is what bounds that, | |
| # here as everywhere. | |
| permissions: | |
| contents: write | |
| steps: | |
| # The review or comment travels as identifiers: `verify` re-reads it from the | |
| # API, so the words the bot weighs and acts on are the ones GitHub | |
| # holds, and a forged dispatch faces the same scrutiny as a relayed one. | |
| # The PR title names the tend-mention run and nothing else: the | |
| # notifications poll matches a live run to its subject by that name. | |
| - name: Re-enter on an admitted ref | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| gh api "repos/$GITHUB_REPOSITORY/dispatches" \ | |
| -f event_type=tend-mention-review \ | |
| -f "client_payload[kind]=${{ github.event_name }}" \ | |
| -f "client_payload[pr]=${{ github.event.pull_request.number }}" \ | |
| -f "client_payload[id]=${{ github.event.review.id || github.event.comment.id }}" \ | |
| -f "client_payload[title]=$PR_TITLE" |