Allow releasing specific commits, and publishing immediately - #868
Conversation
`create-release.yml` could only release the head of a branch, and only as a draft. Neither works for an automated caller: a cloud release branch pins a specific api-go commit, and a draft release creates no tag, which is the thing the release invariant actually requires. Add `api_ref` and `api_go_ref` so a caller can name the commits to release, and `auto_publish` so it can skip the manual publish step. All three default to the existing behavior, so a manual dispatch is unaffected. Publishing this repo's release is what fires `release: published`, which `trigger-api-go-publish-release.yml` turns into api-go's `publish-release.yml` -- the step that creates the api-go tag. The new job therefore has to run after `release-api-go` and has to use the app token; the comment explains why, since getting either wrong yields a green run and no tag. Also add the `permissions: contents: read` block this workflow never had, matching ci.yml and push-to-buf.yml. Read-only covers every job: the releases are created and published with a GitHub App token rather than GITHUB_TOKEN, and the reusable workflows called from here only read. Without it the SAST scan fails on security.gha.missing-explicit-permissions. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| env: | ||
| GH_TOKEN: ${{ steps.generate_token.outputs.token }} | ||
| TAG: ${{ github.event.inputs.tag }} | ||
| run: gh release edit "$TAG" --draft=false -R "$GITHUB_REPOSITORY" |
There was a problem hiding this comment.
Does this always set the new release as "latest"? If so, maybe we need an extra input to decide if this is "latest" or not.
There was a problem hiding this comment.
As written, this does not set it as latest. How should we approach that? I can see four options; two are defensible:
- Always set it as latest. I think this is what we've done historically, but that doesn't mean it's right (but it does mean that it at least isn't so wrong that it's caused issues so far).
- Add an input to allow setting latest, default to true. Preserves historical behavior but gives us an escape hatch; downside is extra complexity that I'm not sure we'd ever actually use.
Two are less defensible:
- Add an input to allow setting latest, default to false. Diverges from historical behavior, adds complexity, and I'm not sure we gain anything.
- Never set it as latest (the current approach). Diverges from historical behavior for no good reason.
Happy to defer to your judgment on this -- RelEng just wants to cut releases however releases should be cut.
There was a problem hiding this comment.
I've updated this to always mark as latest, which is at least more correct than never marking it as latest. Happy to adjust that if needed.
| - release-api-go | ||
| if: | | ||
| !cancelled() && | ||
| (inputs.auto_publish == true || inputs.auto_publish == 'true') && |
There was a problem hiding this comment.
When would we need the == 'true' part? Isn't it always boolean since it's an input?
There was a problem hiding this comment.
Isn't it always boolean since it's an input?
If Github Actions was even just a moderately terrible system, yes. But instead, no. workflow_call events pass booleans as booleans, but workflow_dispatch events pass them as strings. Even though this WF currently only has a workflow_dispatch trigger, adding both is smart forward-compatibility, because someone adding a workflow_call trigger would not necessarily suspect that the exact same input variable might be a boolean in one case and a string in another, even though it's declared as a boolean in both.
There was a problem hiding this comment.
Gotcha; ok that makes sense 👍
What changed?
Add
api_refandapi_go_refso a caller can name the commits to release, andauto_publishso it can skip the manual publish step. All three default to the existing behavior, so a manual dispatch is unaffected.Why?
These changes will allow us to automate API releases as part of server releases.
create-release.ymlcould only release the head of a branch, and only as a draft. Neither works for an automated caller: a cloud release branch pins a specific api-go commit, and a draft release creates no tag, which is the thing the release invariant actually requires.Breaking changes
None.
Server PR
N/A