#29 adds a step that notifies releasetools/homebrew-tap when a release ships, gated on a HOMEBREW_TAP_TOKEN secret that does not exist yet. Rather than create a PAT, this should use the automation GitHub App that releasetools/terraform-github-app already provisions.
Why a token is needed at all
GITHUB_TOKEN is scoped to the repository running the workflow, so it cannot POST /repos/releasetools/homebrew-tap/dispatches. The repository_dispatch trigger works fine with GITHUB_TOKEN — that's an explicit exception in the docs — but the cross-repo authorization is the blocker, not the trigger.
The second reason, which matters more
The tap's bump workflow (releasetools/homebrew-tap#16) opens a PR. Per GitHub's docs:
When a pull request is created or updated by a workflow using GITHUB_TOKEN, pull_request events with the opened, synchronize, or reopened activity types create workflow runs that require approval.
So a bump PR opened with GITHUB_TOKEN sits with its CI gated pending approval — and that CI is brew test-bot --only-formulae, the only thing standing between a bad formula and users. An automated bump whose verification doesn't run unattended is most of the way back to the silent-no-op problem this whole thread has been about.
An App installation token is not subject to that restriction, so the bump PR gets tested immediately. It also removes the dependency on Settings → Actions → Allow GitHub Actions to create and approve pull requests being enabled on the tap.
Why not a PAT
- Tied to a person — it dies when they rotate it, lose access, or leave
- Long-lived by default; App installation tokens expire in an hour
- Audit trail reads as a human, not as automation
- Per-repo scoping is manual, whereas the App installation's repo access is already managed as code in
terraform-github-app
What already exists
terraform-github-app creates the App from manifest.json, stores GH_APP_CLIENT_ID / GH_APP_ID as org variables and GH_APP_PRIVATE_KEY as an org secret, and pins installation access with Terraform. multirepo/.github/workflows/terraform.yml already consumes it:
- name: Generate a GitHub App token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
client-id: ${{ vars.GH_APP_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: |
${{ github.event.repository.name }}
So this is wiring, not new infrastructure.
What's missing
manifest.json currently declares:
"default_permissions": {
"administration": "write",
"environments": "write",
"issues": "write",
"contents": "write",
"metadata": "read",
"secrets": "read",
"organization_secrets": "read"
}
contents: write already covers both sending the dispatch and pushing the bump branch. pull_requests: write is absent and is required to open the bump PR.
Note that editing manifest.json only affects newly created Apps — an existing App's permissions have to be changed in its settings, and the installation must then approve the new permission.
Tasks
Acceptance criteria
- Tagging a release causes the tap to open a bump PR without human involvement
- That PR's
brew test-bot runs immediately, with no approval step
- No PAT exists anywhere in the flow
- A release still succeeds if the App is unavailable, falling back to the tap's daily schedule
Refs
#29 adds a step that notifies
releasetools/homebrew-tapwhen a release ships, gated on aHOMEBREW_TAP_TOKENsecret that does not exist yet. Rather than create a PAT, this should use the automation GitHub App thatreleasetools/terraform-github-appalready provisions.Why a token is needed at all
GITHUB_TOKENis scoped to the repository running the workflow, so it cannotPOST /repos/releasetools/homebrew-tap/dispatches. Therepository_dispatchtrigger works fine withGITHUB_TOKEN— that's an explicit exception in the docs — but the cross-repo authorization is the blocker, not the trigger.The second reason, which matters more
The tap's bump workflow (releasetools/homebrew-tap#16) opens a PR. Per GitHub's docs:
So a bump PR opened with
GITHUB_TOKENsits with its CI gated pending approval — and that CI isbrew test-bot --only-formulae, the only thing standing between a bad formula and users. An automated bump whose verification doesn't run unattended is most of the way back to the silent-no-op problem this whole thread has been about.An App installation token is not subject to that restriction, so the bump PR gets tested immediately. It also removes the dependency on Settings → Actions → Allow GitHub Actions to create and approve pull requests being enabled on the tap.
Why not a PAT
terraform-github-appWhat already exists
terraform-github-appcreates the App frommanifest.json, storesGH_APP_CLIENT_ID/GH_APP_IDas org variables andGH_APP_PRIVATE_KEYas an org secret, and pins installation access with Terraform.multirepo/.github/workflows/terraform.ymlalready consumes it:So this is wiring, not new infrastructure.
What's missing
manifest.jsoncurrently declares:contents: writealready covers both sending the dispatch and pushing the bump branch.pull_requests: writeis absent and is required to open the bump PR.Note that editing
manifest.jsononly affects newly created Apps — an existing App's permissions have to be changed in its settings, and the installation must then approve the new permission.Tasks
"pull_requests": "write"tomanifest.jsoninterraform-github-appreleasetools/cliandreleasetools/homebrew-tapreleasetools/clirelease.yaml, mint an App token scoped tohomebrew-tapand use it for the dispatch, replacingsecrets.HOMEBREW_TAP_TOKENreleasetools/homebrew-tapbump-formula.yml, mint an App token and use it for the branch push andgh pr create, replacinggithub.token::notice::rather than a failure, so a release is never blocked by App misconfigurationterraform-github-appREADME, which describes Contents asreadwhile the manifest sayswriteAcceptance criteria
brew test-botruns immediately, with no approval stepRefs
HOMEBREW_TAP_TOKENplaceholderbump-formula.sh