feat(release): Homebrew bottle build+publish flow (#139)#143
Merged
Conversation
- scripts/release/build_bottle.sh: builds a bottle from the installed rmlx keg via `brew bottle --json --root-url`, renames the local double-dash filename to the remote single-dash expected by Homebrew, prints the bottle do block to paste into the formula, and prints the gh release upload command. shellcheck-clean. - Makefile: adds `make bottle` target wired to the new script; adds it to the .PHONY list alongside the other release targets. - docs/RELEASING.md: new step 8 in the cut-a-release flow covering the full bottle lifecycle (brew install --build-bottle → make bottle → upload → paste bottle do block → commit → tap-sync); updated Files table; added Homebrew bottle verification section. Formula approach: no bottle do block is committed until a real bottle artifact exists on the Release. The source-build path (depends_on "rust" => :build) remains the fallback for any macOS version without a matching bottle, so the formula stays installable at all times. The bottle do block is added in a separate formula-update commit at release time, after the bottle tar.gz is uploaded to the GitHub Release.
This was referenced Jun 18, 2026
Merged
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.
Summary
Addresses #139 — adds the durable in-repo mechanism to ship a Homebrew bottle (precompiled binary) so a future
brew install rmlxdownloads the binary instead of compiling from source, whiledepends_on "mlx-c"keeps the clean install-time dependency-error path (vs a dyld crash).Approach (non-breaking)
The committed formula
packaging/homebrew/rmlx.rbis left unchanged — nobottle doblock. Rationale: a block with placeholder sha256 makesbrew installtry to fetch a nonexistent bottle and hard-fail. With no block, Homebrew falls back to the existing source build (depends_on "rust" => :build+cargo install) for everyone until a real bottle is published. Thebottle doblock is produced + committed at release time, after the real.tar.gzasset is live on the GitHub Release. This is standard third-party-tap practice.Changes
scripts/release/build_bottle.sh(new) — runsbrew bottle --json --root-url=<github-release-root> --no-rebuild --force-core-tap rmlx, renames the local double-dash bottle file to the remote single-dash asset name (via the JSONfilenamefield), and prints the ready-to-pastebottle do … endblock (root_url + cellar + sha256) plus the exactgh release uploadcommand. shellcheck-clean.Makefile—make bottletarget (+.PHONY), slotted afterrelease-sign.docs/RELEASING.md— new step in the cut-a-release flow covering the full bottle lifecycle (build keg with--build-bottle,make bottle, upload asset, paste+commit the block,make tap-sync) + a clean-machine bottle verification note.Verification
ruby -c packaging/homebrew/rmlx.rb→ Syntax OKbrew style packaging/homebrew/rmlx.rb→ no offensesbrew audit --strict→ exit 0, no errorsshellcheck scripts/release/build_bottle.sh+bash -n→ cleanRemaining (release-time, requires a release cut — not automatable here)
brew install --build-bottle …thenmake bottle), upload the.tar.gzto the Release, commit the printedbottle doblock to the formula,make tap-sync.brew install rmlxpulls the binary (no compile); uninstall mlx-c → install fails cleanly.Note:
build_bottle.shinvokesbrew bottle rmlx(bare keg name), so thebrew bottle --jsontop-level key isrmlx— matching the jq lookups in the script.🤖 Generated with Claude Code