Skip to content

feat(release): Homebrew bottle build+publish flow (#139)#143

Merged
Pushkinist merged 1 commit into
mainfrom
feat/139-homebrew-bottle
Jun 18, 2026
Merged

feat(release): Homebrew bottle build+publish flow (#139)#143
Pushkinist merged 1 commit into
mainfrom
feat/139-homebrew-bottle

Conversation

@Pushkinist

Copy link
Copy Markdown
Owner

Summary

Addresses #139 — adds the durable in-repo mechanism to ship a Homebrew bottle (precompiled binary) so a future brew install rmlx downloads the binary instead of compiling from source, while depends_on "mlx-c" keeps the clean install-time dependency-error path (vs a dyld crash).

Approach (non-breaking)

The committed formula packaging/homebrew/rmlx.rb is left unchanged — no bottle do block. Rationale: a block with placeholder sha256 makes brew install try 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. The bottle do block is produced + committed at release time, after the real .tar.gz asset is live on the GitHub Release. This is standard third-party-tap practice.

Changes

  • scripts/release/build_bottle.sh (new) — runs brew 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 JSON filename field), and prints the ready-to-paste bottle do … end block (root_url + cellar + sha256) plus the exact gh release upload command. shellcheck-clean.
  • Makefilemake bottle target (+ .PHONY), slotted after release-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 OK
  • brew style packaging/homebrew/rmlx.rb → no offenses
  • brew audit --strict → exit 0, no errors
  • shellcheck scripts/release/build_bottle.sh + bash -n → clean
  • Source-install path unchanged (formula diff is empty) → existing tap users unaffected.

Remaining (release-time, requires a release cut — not automatable here)

  • Build the real bottle (brew install --build-bottle … then make bottle), upload the .tar.gz to the Release, commit the printed bottle do block to the formula, make tap-sync.
  • Clean-machine verify: brew install rmlx pulls the binary (no compile); uninstall mlx-c → install fails cleanly.

Note: build_bottle.sh invokes brew bottle rmlx (bare keg name), so the brew bottle --json top-level key is rmlx — matching the jq lookups in the script.

🤖 Generated with Claude Code

- 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.
@Pushkinist Pushkinist self-assigned this Jun 18, 2026
@Pushkinist Pushkinist merged commit 02f39cf into main Jun 18, 2026
2 checks passed
@Pushkinist Pushkinist deleted the feat/139-homebrew-bottle branch June 18, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant