fix(ci): pass App token to checkout so bot pushes trigger downstream workflows#3045
fix(ci): pass App token to checkout so bot pushes trigger downstream workflows#3045amikofalvy wants to merge 1 commit intomainfrom
Conversation
…workflows actions/checkout sets http.extraheader with an AUTHORIZATION header containing whichever token is passed to its `token` input. This header takes precedence over URL-embedded credentials. Both auto-format.yml and ci.yml were generating the App token AFTER checkout and overriding the remote URL, but the extraheader from checkout (set with the default GITHUB_TOKEN) still won — so pushes were silently attributed to GITHUB_TOKEN and GitHub skipped triggering downstream workflows. This is the same root cause fixed for release.yml in d85f7ca (persist-credentials: false). For these two workflows we take a cleaner approach: generate the App token BEFORE checkout and pass it directly to checkout's `token` input, so the extraheader is set correctly from the start. No manual `git remote set-url` needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
TL;DR — Moves the GitHub App token generation step before Key changes
Summary | 2 files | 1 commit | base: App token moved before checkout to authenticate git automatically
|
There was a problem hiding this comment.
Clean, well-motivated fix. The root cause diagnosis is correct — actions/checkout sets http.extraheader, which takes precedence over URL-embedded credentials from git remote set-url. Moving token generation before checkout is the right approach. One minor nit on token fallback consistency.
Claude Opus | 𝕏
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| # Use the App token so git's extraheader authenticates as the App, | ||
| # ensuring pushes trigger downstream workflows. | ||
| token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
Nit: This falls back to secrets.GITHUB_TOKEN, while ci.yml:71 uses github.token. They're functionally equivalent, but github.token is the modern idiom and avoids the impression that it's a user-managed secret. Consider aligning both files to github.token for consistency.
| token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} | |
| token: ${{ steps.app-token.outputs.token || github.token }} |
| # to prevent infinite loops. | ||
| - name: Generate GitHub App Token | ||
| id: app-token | ||
| if: steps.pr-check.outputs.skip != 'true' |
There was a problem hiding this comment.
The auto-format workflow also triggers on push to main (line 6-8). On push events, steps.pr-check is skipped entirely, so steps.pr-check.outputs.skip is empty — which passes this != 'true' condition. That means App token generation runs on push-to-main too, which seems intentional (the workflow pushes formatting commits on main as well). Just flagging for visibility — no change needed.
There was a problem hiding this comment.
Approved. The fix correctly addresses the extraheader precedence issue.
Claude Opus | 𝕏
There was a problem hiding this comment.
PR Review Summary
(0) Total Issues | Risk: Low
💭 Consider (1) 💭
Inline Comments:
- 💭 Consider:
ci.yml:71Inconsistent token reference (github.tokenvssecrets.GITHUB_TOKENin auto-format.yml)
🧹 While You're Here (1) 🧹
🧹 1) release.yml:36 Different approach for same problem
Issue: release.yml uses persist-credentials: false + post-checkout token generation, while this PR establishes a cleaner pattern of pre-checkout token generation with token: input.
Why: Two valid patterns for the same problem increases cognitive load during maintenance. The new approach in this PR is cleaner and more straightforward.
Fix: Consider a follow-up PR to update release.yml to use the same token: input approach for consistency across all workflows.
Refs:
✅ APPROVE
Summary: This PR correctly fixes the root cause of bot commits not triggering downstream CI workflows. The solution — generating the GitHub App token before checkout and passing it to checkout's token: input — is cleaner than the previous git remote set-url workaround that was silently overridden by the http.extraheader set by actions/checkout.
The implementation is sound:
- ✅ Security: Actions are SHA-pinned, permissions properly scoped
- ✅ Fork handling: Fallback tokens ensure fork PRs still work (app token skipped, falls back gracefully)
- ✅ Root cause addressed: Checkout now uses App token identity from the start, so pushes trigger downstream workflows
The only suggestions are cosmetic consistency improvements. Ship it! 🚀
Discarded (0)
None.
Reviewers (1)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-devops |
3 | 0 | 1 | 1 | 1 | 0 | 0 |
| Total | 3 | 0 | 1 | 1 | 1 | 0 | 0 |
| fetch-depth: 0 | ||
| # Use the App token so git's extraheader authenticates as the App, | ||
| # ensuring pushes trigger downstream workflows. | ||
| token: ${{ steps.app-token.outputs.token || github.token }} |
There was a problem hiding this comment.
💭 Consider: Inconsistent token reference naming
Issue: This uses github.token while auto-format.yml:67 uses secrets.GITHUB_TOKEN as the fallback. Both reference the same token, but inconsistent naming could cause confusion.
Why: Cosmetic inconsistency; doesn't affect functionality but reduces maintainability.
Fix:
| token: ${{ steps.app-token.outputs.token || github.token }} | |
| token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} |
Refs:
- auto-format.yml:67 — uses
secrets.GITHUB_TOKEN
Preview URLsUse these stable preview aliases for testing this PR:
These point to the same Vercel preview deployment as the bot comment, but they stay stable and easier to find. Raw Vercel deployment URLs
|

Summary
actions/checkoutsetshttp.extraheaderwith theGITHUB_TOKEN, which overrides URL-embedded credentials — so the manualgit remote set-urlwith the App token was silently ignoredrelease.ymlin d85f7ca (persist-credentials: false), but auto-format and CI were never updatedWhat changed
Both workflows now generate the App token before checkout and pass it to checkout's
token:input, so theextraheaderis set with the App identity from the start. This eliminates the need for manualgit remote set-urloverrides in the push steps.Fix history
b204079git remote set-urlto auto-format + CIextraheaderfrom checkout overrides URL credentials3debd2eremote set-urlapproach for release.ymld85f7capersist-credentials: falsetoken:Test plan
GITHUB_TOKEN/github.token)🤖 Generated with Claude Code