Skip to content

fix: Run the Homebrew formula job automatically as part of a release #266

Description

@inureyes

Problem / Background

The update-homebrew job never runs as part of a release. After every release the Homebrew tap formula has to be bumped by a manual workflow_dispatch. The intended behavior is that the formula updates automatically once the release finishes and all artifacts have been uploaded.

The cause is the job-level condition in .github/workflows/update_homebrew_formula.yml (line 26):

if: github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call'

Inside a reusable workflow invoked through uses:, github.event_name resolves to the caller's originating event, not to workflow_call. When release.yml calls this workflow during a release, github.event_name is release, so both sides of the condition are false and the job is skipped. For the uses: path this condition is unsatisfiable.

Everything else in the chain is already correct:

  • release.yml invokes it as a job named update-homebrew with needs: [publish-release], uses: ./.github/workflows/update_homebrew_formula.yml, with: release_tag: ${{ github.event.release.tag_name }}, and secrets: inherit.
  • The ordering is correct and needs no change. update-homebrew needs publish-release, which needs build. All five build jobs upload their release assets and checksums before publish-release runs, so every artifact is present by the time the formula job would start.
  • The tag plumbing is correct. Line 39 reads INPUT_TAG="${{ github.event.inputs.release_tag || inputs.release_tag }}", handling both the dispatch input and the call input, with a fallback to the latest official release.

Evidence that this has never worked from the release chain:

  • v2.4.2: run 31790934989, job 94746343757 skipped in 0s. The tap stayed at 2.4.1 until a manual dispatch (run 31793965455) bumped it, producing the tap commit bump: bssh, bssh-server, and bssh-keygen to v2.4.2 at 2026-08-14T10:53:37Z.
  • v2.4.1: run 30817624402, job 91700817094 skipped the same way. The tap's 2.4.1 commit is dated 2026-08-03T13:56:26Z and came from a separate workflow_dispatch run (30820217861, started 13:55:29Z), while the release run started at 13:22:08Z.

Proposed Solution

Remove the if on line 26 entirely. The workflow declares only two triggers, workflow_dispatch and workflow_call, so no other event can start it and the condition can only exclude legitimate runs. If a guard is still wanted, base it on something other than github.event_name, for example an explicit input passed by the caller.

Second case to decide as part of this issue

publish-release in release.yml carries if: github.event_name == 'release' && github.event.release.prerelease. It converts a pre-release into an official release. If a maintainer publishes a release directly as official (not a pre-release), publish-release is skipped, and because update-homebrew declares needs: [publish-release], it is skipped too. Fixing line 26 alone would still leave the formula un-updated on that path.

Decide and implement one of:

  1. Make update-homebrew also run on that path, for example by relaxing its needs/if so it runs whenever the build succeeded and the release is official.
  2. Declare the pre-release flow the only supported release path and state that explicitly in the release documentation.

Acceptance Criteria

  • Cutting a release updates the tap formula with no manual workflow_dispatch.
  • Manual workflow_dispatch with an explicit release_tag still works, since it is the recovery path.
  • The formula job still runs only after every release asset has been uploaded, so the sha256 values it computes come from the final artifacts.
  • The behavior for a release published directly as official is either supported or explicitly documented as unsupported.
  • Verified on a real release rather than by reading the YAML, since this defect is only observable in a release run.

Technical Considerations

  • github.event_name is never workflow_call in a called workflow; it always reflects the caller's triggering event. Any condition that needs to distinguish the call path must use an input the caller sets, or github.workflow_ref / github.job context, not event_name.
  • Do not change the needs ordering between build, publish-release, and update-homebrew except as required by the second case above, since the current ordering is what guarantees the checksums are computed from uploaded assets.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions