Skip to content

chore(ci): replace expiring PAT with GitHub App token for Homebrew tap#28

Merged
mudrii merged 1 commit into
mainfrom
chore/homebrew-app-token
Apr 29, 2026
Merged

chore(ci): replace expiring PAT with GitHub App token for Homebrew tap#28
mudrii merged 1 commit into
mainfrom
chore/homebrew-app-token

Conversation

@mudrii
Copy link
Copy Markdown
Owner

@mudrii mudrii commented Apr 29, 2026

Pull Request

Type

  • chore — tooling, CI, config

Summary

The HOMEBREW_TAP_TOKEN PAT expired between v2026.4.13 (2026-04-13) and v2026.4.29 (2026-04-29) — exactly 38 days after it was last rotated on 2026-03-22, consistent with a 30-day fine-grained PAT lifetime. This caused the v2026.4.29 GoReleaser run to fail at the Homebrew formula push step with 401 Bad credentials.

Replace the static PAT with a GitHub App installation token minted fresh on every workflow run. Installation tokens don't expire between releases — they're issued at runtime from a long-lived private key and die after ~1 hour. The .goreleaser.yml is unchanged; only the source of HOMEBREW_TAP_TOKEN changes.

What Changed

File What changed
.github/workflows/release.yml Added actions/create-github-app-token@v2 step before GoReleaser; HOMEBREW_TAP_TOKEN env var now reads from steps.tap-token.outputs.token instead of secrets.HOMEBREW_TAP_TOKEN

Test Evidence

No production code changed. The workflow change is validated by the next tag push after the two new secrets are set.

Test output (existing suite unaffected)
# No Go code changed — suite output unchanged from v2026.4.29 CI run.

Checklist

Code quality

  • No new globals outside the 7 module objects + 4 utilities ($, esc, safeColor, relTime)
  • Every dynamic value inserted into the DOM goes through esc()
  • No hardcoded hex colors — CSS variables only (var(--accent), etc.)
  • No new frontend dependencies (no import, no CDN <script>)
  • No new Go module dependencies (go.mod stays stdlib-only)

Tests

  • All existing tests pass: go test -race ./...
  • New behaviour has at least one test

Manual verification

  • Tested in at least one dark theme and one light theme
  • Tested on desktop and mobile viewport (< 768px)
  • If chart code changed: verified both 7d and 30d views
  • If session/cron table changed: verified scroll position preserved after refresh

Documentation

  • CHANGELOG.md updated under the correct version heading
  • README.md updated if a new panel or config key was added

Screenshots / Recordings

CI-only change. No visual output.

Breaking Changes

None. The .goreleaser.yml brews.repository.token field still reads {{ .Env.HOMEBREW_TAP_TOKEN }} — only where that env var comes from changes.

Agent Review Notes

Before merging, complete the one-time setup:

  1. Go to https://github.com/settings/apps/new
    • Name: anything (e.g. openclaw-homebrew-tap-writer)
    • Homepage URL: https://github.com/mudrii/openclaw-dashboard
    • Permissions → Repository → Contents: Read & write (nothing else needed)
    • Uncheck "Active" under Webhook
  2. Click "Create GitHub App" → note the App ID (shown on the app's settings page)
  3. Scroll to "Private keys" → "Generate a private key" → download the .pem
  4. Click "Install App" → install on mudrii/homebrew-tap only
  5. Run:
    gh secret set HOMEBREW_TAP_APP_ID --body "<App ID>" --repo mudrii/openclaw-dashboard
    gh secret set HOMEBREW_TAP_APP_PRIVATE_KEY < /path/to/key.pem --repo mudrii/openclaw-dashboard
    gh secret delete HOMEBREW_TAP_TOKEN --repo mudrii/openclaw-dashboard
  6. Merge this PR, then re-run the failed v2026.4.29 release job:
    gh run rerun 25105399366 --failed --repo mudrii/openclaw-dashboard

The PAT used to push Homebrew formula updates expires on a calendar
schedule (30-day default). A GitHub App installation token is minted
fresh on every workflow run from a long-lived private key stored as a
repo secret, so it never expires between releases.

Replace the static HOMEBREW_TAP_TOKEN secret with two new secrets:
  HOMEBREW_TAP_APP_ID          — numeric App ID
  HOMEBREW_TAP_APP_PRIVATE_KEY — RSA .pem file contents

The new "Mint homebrew-tap token" step uses
actions/create-github-app-token@v2 scoped to mudrii/homebrew-tap only.
GoReleaser continues to read HOMEBREW_TAP_TOKEN from the environment —
only the source of that value changes.

Setup (one-time, done in the browser before merging):
  1. Create a GitHub App at github.com/settings/apps/new
     - Permissions: Repository > Contents: Read & write
  2. Install the App on mudrii/homebrew-tap only
  3. Generate and download a private key
  4. gh secret set HOMEBREW_TAP_APP_ID --repo mudrii/openclaw-dashboard
  5. gh secret set HOMEBREW_TAP_APP_PRIVATE_KEY < key.pem --repo mudrii/openclaw-dashboard
  6. Delete the old HOMEBREW_TAP_TOKEN secret
Copilot AI review requested due to automatic review settings April 29, 2026 12:29
@gemini-code-assist
Copy link
Copy Markdown

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the release workflow to stop relying on an expiring fine-grained PAT for pushing the Homebrew tap, and instead mint a short-lived GitHub App installation token at runtime to keep GoReleaser releases unblocked.

Changes:

  • Add an actions/create-github-app-token@v2 step to mint a GitHub App installation token for mudrii/homebrew-tap.
  • Wire HOMEBREW_TAP_TOKEN for the GoReleaser step to steps.tap-token.outputs.token (instead of a stored PAT secret).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mudrii mudrii merged commit 79c1ffd into main Apr 29, 2026
8 checks passed
@mudrii mudrii deleted the chore/homebrew-app-token branch April 29, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants