Render a Homebrew formula from release artifacts and push it to a
tap repo. Earlier tinfoil versions shelled out to a generated
scripts/update-homebrew.sh; this module replaces it so the whole
release lifecycle stays in Elixir and is unit-testable.
Called from mix tinfoil.homebrew, which the generated workflow
invokes on a separate CI job after the GitHub Release publish step
succeeds. See Tinfoil.Publish for the release-assets counterpart.
Inputs at CI time
artifacts/directory containing the release tarballs plus.sha256sidecar files (downloaded from the build matrix)GITHUB_REF_NAMEenv var holding the tag that triggered the release (e.g.v1.2.3)- Auth material depending on
config.homebrew.auth::token—HOMEBREW_TAP_TOKENenv with PAT:deploy_key— SSH agent configured with a deploy key for the tap repo (typically viawebfactory/ssh-agent)
What the module does
- Reads
.sha256sidecars for every target's archive and builds a map oftarget => sha256. - Renders the user's checked-in
.tinfoil/formula.rb.eex(falling back to the default template) with real version + SHAs. - Clones the tap repo into a temp dir, writes the rendered formula
at
Formula/<formula_name>.rb, commits and pushes.
The git operations shell out to git — no extra deps. Authentication
is left to the environment: HTTPS with a token-bearing URL, or SSH
via an already-running ssh-agent.
Summary
Types
Known error atoms returned by publish/2. Catch-all is
{:error, term()} for unexpected failures.
Functions
Render the formula and push it to the tap repo.
Types
@type error() :: :homebrew_not_enabled | :missing_tag | :missing_homebrew_tap_token | :malformed_sha_sidecar | {:missing_sha_sidecar, atom(), Path.t()} | {:missing_formula_template, Path.t()} | {:formula_template_read_error, Path.t(), term()} | {:git_failed, [String.t()], non_neg_integer(), String.t()}
Known error atoms returned by publish/2. Catch-all is
{:error, term()} for unexpected failures.
:homebrew_not_enabled-- config hashomebrew.enabled: false:missing_tag-- no tag given andGITHUB_REF_NAMEis unset:missing_homebrew_tap_token--auth: :tokenbutHOMEBREW_TAP_TOKENenv var is missing or empty{:missing_sha_sidecar, target, path}-- a.sha256sidecar file couldn't be read frominput_dir:malformed_sha_sidecar-- a.sha256sidecar didn't contain a 64-hex-character digest{:missing_formula_template, path}-- the EEx formula template couldn't be found (default.tinfoil/formula.rb.eex){:formula_template_read_error, path, reason}-- template read failed for a reason other than:enoent{:git_failed, args, exit_status, output}-- agitsubprocess call returned non-zero
Functions
@spec publish(Tinfoil.Config.t(), opts()) :: {:ok, result()} | {:ok, preview()} | {:error, error() | term()}
Render the formula and push it to the tap repo.
Options (all optional, sane defaults):
:input_dir— directory with archives + sha256 sidecars (default"artifacts"):tag— release tag, usually taken fromGITHUB_REF_NAMEenv:formula_template— path to the EEx formula template (default".tinfoil/formula.rb.eex"):tap_dir— temp dir to clone into (default a new mktemp):git— module implementing thegitcallbacks (seeTinfoil.Homebrew.Git); injected for testing