ci: keep EKSCTLBOT_TOKEN out of the release-notes rendering job - #8862
Closed
sapphirew wants to merge 1 commit into
Closed
ci: keep EKSCTLBOT_TOKEN out of the release-notes rendering job#8862sapphirew wants to merge 1 commit into
sapphirew wants to merge 1 commit into
Conversation
The Draft Release Notes workflow ran as a single job that both handled
the release-drafter output and held EKSCTLBOT_TOKEN. That token is what
starts the publish pipeline (start-release.yaml triggers on a tag push
and passes it to publish-release.yaml, which runs GoReleaser and commits
the Homebrew formula), so it is the highest-value credential in the repo
and it does not need to be present while the drafter output is being
turned into a file.
Split the job in two:
render_release_draft contents: write, pull-requests: read
Runs release-drafter, renders the notes file and
the pull request body into RUNNER_TEMP, uploads
them as an artifact. No EKSCTLBOT_TOKEN, and no
checkout -- it does not need the working tree.
update_release_draft_pr contents: read
Checks out, copies the rendered notes into
docs/release_notes/, opens the pull request with
EKSCTLBOT_TOKEN. Consumes the drafter output only
as file content, via `body-path`, so it is never
interpolated into a run step.
Other changes this requires:
- `tag_name` is promoted to a job output. It comes from the
`tag-template: 'v$NEXT_MINOR_VERSION'` in .github/release-drafter.yml
and is only used in action inputs, not in a shell.
- The pull request body moves from an inline `body:` to `body-path:`,
rendered with printf. Verified byte-identical to what the previous YAML
template produced for the same tag and body.
- `add-paths: docs/release_notes` scopes the commit to the notes file.
- `pull-requests: write` drops to `read` on the drafter job.
.github/release-drafter.yml configures no `autolabeler:`, so nothing in
this workflow applies labels; the pull request labels are applied by
create-pull-request in the second job using its own token.
- `retention-days: 1` on the artifact, since it is only a job-to-job hand-off.
The `if: github.event.repository.fork == false` guard stays on the first
job; the second is gated transitively through `needs`.
sapphirew
force-pushed
the
ci/isolate-eksctlbot-token
branch
from
September 11, 2026 21:55
7f6c888 to
8aa94c2
Compare
This was referenced Sep 11, 2026
Merged
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Follows #8860, now merged. Rebased onto it, so this is a single commit touching only
.github/workflows/release-drafter.yaml.Description
The Draft Release Notes workflow runs as a single job that both handles the release-drafter output and holds
EKSCTLBOT_TOKEN. Those two things do not need to be in the same job.EKSCTLBOT_TOKENis the highest-value credential in the repo:start-release.yamltriggers on a tag push and passes it topublish-release.yaml, which runs GoReleaser and commits the Homebrew formula toweaveworks/homebrew-tap. UnlikeGITHUB_TOKEN, a tag pushed with a PAT does start workflows. Meanwhile the same job does the string handling onsteps.draft.outputs.body, which is assembled from merged pull request titles — so the least trustworthy input in the workflow sits in the job with the most reach.#8860 fixed the shell quoting. This separates the two concerns structurally, so the rendering step has nothing valuable within reach even if something about it regresses later.
The split
render_release_draftupdate_release_draft_prcontents: write,pull-requests: readcontents: readEKSCTLBOT_TOKENpersist-credentials: falseRUNNER_TEMP, uploads as an artifactbody-pathThe second job never interpolates the drafter output into a
run:step — it copies one file intodocs/release_notes/and hands another tocreate-pull-requestas a path.Supporting changes
tag_namepromoted to a job output. It comes fromtag-template: 'v$NEXT_MINOR_VERSION'in.github/release-drafter.ymland is only used in action inputs (commit-message,title), never in a shell.body:tobody-path:, rendered withprintfin the first job.body-pathhas been available since create-pull-request v6; this repo is on v8.1.1.add-paths: docs/release_notesscopes the commit to the notes file, so nothing else in the tree can end up in the PR.pull-requests: write→readon the drafter job..github/release-drafter.ymlconfigures noautolabeler:, so nothing in this workflow applies labels; the PR's own labels are applied by create-pull-request in the second job with its own token. Please sanity-check this one — it's the only permission I reduced based on what the config does rather than what the workflow obviously needs, and it's a one-line revert if I have it wrong.retention-days: 1on the artifact, since it's only a job-to-job hand-off.if: github.event.repository.fork == falsestays on the first job; the second is gated transitively throughneeds.Checklist
area/nodegroup) and target version (e.g.version/0.12.0)Testing
The PR body is the part most likely to regress silently, since it moved from a YAML template to
printf. I rendered it both ways for the same tag and body and diffed them — the old template is read straight out ofgit show 8e1d569:.github/workflows/release-drafter.yaml:Also confirmed the notes file lands at
docs/release_notes/0.220.0.mdfor tagv0.220.0, and that a body containing- evil"; whoami; echo " (#124)is written verbatim with nothing executed.Workflow YAML parses; job graph and permissions are as intended:
Not verifiable locally: the artifact hand-off and the
create-pull-requestinvocation only exercise on a real push tomain. If the artifact path is wrong the symptom is a failed "Copy release notes from Draft" step rather than a malformed PR, so it fails closed.