Skip to content

Commit 2f15d24

Browse files
mbeczynskiclaude
andcommitted
ci: cask do tapu przez GitHub App renacode-tap zamiast PAT
HOMEBREW_TAP_TOKEN był fine-grained PAT-em właściciela, wygasającym 7.10.2027. Teraz job robi godzinny token aplikacji `renacode-tap` (Contents: write) ograniczony do RenaCode/homebrew-tap (actions/create-github-app-token v3.2.0, przypięta po SHA). Sekret TAP_APP_KEY + zmienna TAP_APP_CLIENT_ID. Token i próba `git ls-remote` tapu chodzą przy KAŻDYM przebiegu, więc utrata instalacji wychodzi na PR, a nie po opublikowaniu DMG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 56b0608 commit 2f15d24

2 files changed

Lines changed: 37 additions & 11 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ name: Release
2727
# Without it the release does NOT build: an ad-hoc signature changes the
2828
# app's identity on every release and macOS revokes Full Disk Access after
2929
# every upgrade.
30-
# HOMEBREW_TAP_TOKEN - token with write access to RenaCode/homebrew-tap.
30+
# TAP_APP_KEY (secret) + TAP_APP_CLIENT_ID (variable) - GitHub App `renacode-tap`
31+
# (Contents: write, installed on RenaCode/homebrew-tap). The job mints a
32+
# 1-hour token scoped to that one repository; nothing expires.
3133
#
3234
# Still no Developer ID and no notarization - Gatekeeper does not know the
3335
# publisher; the cask removes the quarantine attribute in postflight.
@@ -277,23 +279,41 @@ jobs:
277279
mac-app/build/*.sha256
278280
generate_release_notes: true
279281

280-
- name: Check tap token
282+
- name: Check tap app
281283
if: env.IS_RELEASE == 'true'
282284
env:
283-
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
285+
TAP_APP_CLIENT_ID: ${{ vars.TAP_APP_CLIENT_ID }}
286+
TAP_APP_KEY: ${{ secrets.TAP_APP_KEY }}
284287
run: |
285-
if [ -z "$TAP_TOKEN" ]; then
286-
echo "::error::Release published, but HOMEBREW_TAP_TOKEN is missing - the cask in the tap was NOT updated. Contents to insert manually:"
288+
if [ -z "$TAP_APP_CLIENT_ID" ] || [ -z "$TAP_APP_KEY" ]; then
289+
echo "::error::Release published, but TAP_APP_CLIENT_ID/TAP_APP_KEY is missing - the cask in the tap was NOT updated. Contents to insert manually:"
287290
cat mac-app/build/cloudmachine.rb
288291
exit 1
289292
fi
290293
294+
# Token and the access probe run on EVERY build, not only on release:
295+
# an app that lost its installation (or a missing key) fails the PR,
296+
# not the release after the DMG is already published.
297+
- name: Tap token
298+
id: tap-token
299+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
300+
with:
301+
client-id: ${{ vars.TAP_APP_CLIENT_ID }}
302+
private-key: ${{ secrets.TAP_APP_KEY }}
303+
owner: RenaCode
304+
repositories: homebrew-tap
305+
306+
- name: Check tap access
307+
env:
308+
TAP_TOKEN: ${{ steps.tap-token.outputs.token }}
309+
run: git ls-remote "https://x-access-token:${TAP_TOKEN}@github.com/RenaCode/homebrew-tap.git" HEAD
310+
291311
- name: Check out tap
292312
if: env.IS_RELEASE == 'true'
293313
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
294314
with:
295315
repository: RenaCode/homebrew-tap
296-
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
316+
token: ${{ steps.tap-token.outputs.token }}
297317
path: homebrew-tap
298318

299319
- name: Push cask to tap

‎packaging/README.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,21 @@ rm -rf "$work"
8080
Do this **once**. A new certificate is a new identity: every Mac would have to
8181
grant Full Disk Access again.
8282

83-
### 2. The tap repository and `HOMEBREW_TAP_TOKEN`
83+
### 2. The tap repository and the `renacode-tap` app
8484

8585
1. Create the public repository `RenaCode/homebrew-tap` (empty is fine; the
8686
workflow creates `Casks/`).
87-
2. Create a fine-grained token limited to that repository with
88-
*Contents: Read and write*, and store it:
89-
`gh secret set HOMEBREW_TAP_TOKEN -R RenaCode/CloudMachine`
87+
2. Create a GitHub App in the RenaCode organization (no webhook, Repository
88+
permissions *Contents: Read and write*), install it on `homebrew-tap` only,
89+
and store its client ID and private key:
90+
`gh variable set TAP_APP_CLIENT_ID -R RenaCode/CloudMachine --body <client id>`
91+
`gh secret set TAP_APP_KEY -R RenaCode/CloudMachine < key.pem`
9092

91-
Without the token the release is still published, but the job fails and
93+
The release job turns the key into a one-hour token for `homebrew-tap`
94+
(`actions/create-github-app-token`), so there is no token to renew. The app
95+
is `renacode-tap` (since 2026-10-23; before that a fine-grained PAT).
96+
97+
Without the app the release is still published, but the job fails and
9298
prints the cask, so a missing tap update cannot go unnoticed.
9399

94100
## What the cask does and deliberately does not do

0 commit comments

Comments
 (0)