Scope the release app token to what releaseo needs - #6266
Conversation
actions/create-github-app-token with no permission-* inputs mints a token carrying every permission the app installation holds. This one is handed to releaseo, which pushes a branch and opens a pull request, so contents and pull-requests are all it needs. Also binds the three releaseo outputs in the summary step through env: rather than interpolating them into the shell. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6266 +/- ##
==========================================
+ Coverage 72.71% 72.74% +0.02%
==========================================
Files 742 742
Lines 77299 77299
==========================================
+ Hits 56209 56228 +19
+ Misses 17126 17110 -16
+ Partials 3964 3961 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Validated by dispatch rather than left as an open question — run 31419393149, triggered from this branch with All three steps that mattered passed: the token minted (so That was the only blocker I had flagged on this PR, so it is ready. One carry-over for the remaining app-token work: the Homebrew tap token in |
Second of the release-workflow changes tracked in #6253, after #6263.
Summary
actions/create-github-app-tokenwith nopermission-*inputs mints a token scoped to the whole installation. This one is handed toreleaseo, which pushes a branch and opens a pull request — socontents: writeandpull-requests: writeare all it needs.env:rather than interpolated into the shell. No behaviour change.create-release-pr.ymlgoes from 4 findings to 1 —github-appand all threetemplate-injectionclear. The remainingartipackedis deliberately untouched, see below.✅ Verified by a real dispatch run
permission-*inputs can only narrow a token, never grant — so if theRELEASE_APPinstallation did not holdcontents: writeorpull-requests: write, the token step would fail and no release PR could ever be created. Reading installation permissions needsadmin:org, which I do not have, so this was settled by observation instead.create-release-pr.ymlisworkflow_dispatch, so it was run from this branch (run 31419393149) withbump_type=patch:env:binding renders correctlyIt produced a genuine release pull request — #6267,
Release v0.42.2, touchingVERSION, bothChart.yamlfiles, both chartREADME.mdfiles andvalues.yaml. That is the point: the whole path ran under the reduced token, not just the token step. It has been closed and its branch deleted, andmain'sVERSIONis confirmed still0.42.1.Of the four release workflows this is the only one that can be exercised at all, which is why it was chosen to go early.
Part of #6253
Type of change
Test plan
Unit tests (
task test)E2E tests (
task test-e2e)Linting (
task lint-fix)Manual testing (describe below)
Read
stacklok/releaseo'saction.ymlto establish what the token is actually used for, rather than inferring it from the workflow: it is passed asGITHUB_TOKENto thereleaseobinary, which creates the branch and the pull request. Nothing else in this workflow consumes the app token — the stale-branch cleanup step usessecrets.GITHUB_TOKEN.Workflow parses as YAML;
actionlintclean.zizmoron this file:github-app1 → 0,template-injection3 → 0.Exercised for real via the dispatch described above — token minted, branch pushed, pull request opened, summary rendered. Cleaned up afterwards.
Does this introduce a user-facing change?
No. The app installation holds both permissions, confirmed by the dispatch run.
Special notes for reviewers
artipackedfinding on the checkout is left alone on purpose.releaseotakes the token as an explicit input, which strongly suggests it authenticates itself rather than using the credentialactions/checkoutleaves in.git/config— but "strongly suggests" is not verification, and if it does rely on the persisted credential thenpersist-credentials: falsewould break release PR creation. Not worth guessing at in a workflow that cannot be tested by an ordinary pull request.create-release-tag.yml, and the Homebrew tap token inreleaser.yml) use the same pattern, so this run de-risks them — but note the Homebrew one is a different app,HOMEBREW_TAP_APP, whose installation permissions are still unverified and which cannot be dispatch-tested.Generated with Claude Code