Add brew input to make Homebrew tap publishing skippable - #109
Merged
Conversation
Every caller of the reusable release workflow currently publishes a
formula to the public conductorone/homebrew-baton tap on every tag
push: the brews block in the binaries goreleaser config is
unconditional, and the goreleaser-binaries job that renders it always
runs. Unlike docker/lambda/msi, there is no input to opt out, so
connectors whose repositories are private still get a public formula
pointing at release assets anonymous users cannot download - leaking
the repository name, version history, and release cadence with no
working install to show for it.
Add a `brew` boolean input (default true) following the msi/docker
convention. Because the brews block lives inside the always-running
goreleaser-binaries job - which also produces the binaries, S3
uploads, and manifest the rest of the pipeline depends on - it cannot
be gated at the job level like the other inputs. Instead the input is
plumbed through the existing envsubst render: the "Generate configs
for binaries" step exports BREW_SKIP_UPLOAD=(!brew), and the brews
block gains `skip_upload: "${BREW_SKIP_UPLOAD}"`. goreleaser skips the
tap push only when skip_upload is exactly "true" ("false" publishes
normally, verified against the pinned v2.13 source), so all existing
callers - none of which pass the input - are behaviorally unchanged.
When skipped, the formula is still written to the local dist dir and
everything else in the release (binaries, signing, SBOM, provenance,
S3, ECR, registry record) proceeds as before.
The expression uses `inputs.brew != true` rather than a &&/|| ternary
deliberately: empty strings are falsy in Actions expressions, so a
ternary with an empty true-branch would invert the logic.
Verified: workflow YAML parses; actionlint output is identical to
main (same 13 pre-existing shellcheck notes, line-shifted); envsubst
render with both values produces valid goreleaser config; templates
are checked out at the same sha as the invoked workflow, so older
version tags are unaffected.
kans
approved these changes
Aug 21, 2026
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.
Every caller of the reusable release workflow currently publishes a formula to the public conductorone/homebrew-baton tap on every tag push: the brews block in the binaries goreleaser config is unconditional, and the goreleaser-binaries job that renders it always runs. Unlike docker/lambda/msi, there is no input to opt out, so connectors whose repositories are private still get a public formula pointing at release assets anonymous users cannot download - leaking the repository name, version history, and release cadence with no working install to show for it.
Add a
brewboolean input (default true) following the msi/docker convention. Because the brews block lives inside the always-running goreleaser-binaries job - which also produces the binaries, S3 uploads, and manifest the rest of the pipeline depends on - it cannot be gated at the job level like the other inputs. Instead the input is plumbed through the existing envsubst render: the "Generate configs for binaries" step exports BREW_SKIP_UPLOAD=(!brew), and the brews block gainsskip_upload: "${BREW_SKIP_UPLOAD}". goreleaser skips the tap push only when skip_upload is exactly "true" ("false" publishes normally, verified against the pinned v2.13 source), so all existing callers - none of which pass the input - are behaviorally unchanged. When skipped, the formula is still written to the local dist dir and everything else in the release (binaries, signing, SBOM, provenance, S3, ECR, registry record) proceeds as before.The expression uses
inputs.brew != truerather than a &&/|| ternary deliberately: empty strings are falsy in Actions expressions, so a ternary with an empty true-branch would invert the logic.Verified: workflow YAML parses; actionlint output is identical to main (same 13 pre-existing shellcheck notes, line-shifted); envsubst render with both values produces valid goreleaser config; templates are checked out at the same sha as the invoked workflow, so older version tags are unaffected.