Homebrew bottle builder and tap manager for OCaml monorepos
homebrew#
Homebrew bottle builder and tap manager for OCaml monorepos.
Overview#
Build, upload, and release Homebrew bottles from dune monorepos. Generates Ruby formulas with platform-specific SHA256 checksums, uploads bottles to S3-compatible storage, and manages tap repositories.
Features#
- YAML configuration for binary definitions and storage settings
- Platform-aware bottle building (macOS ARM64/Intel, Linux x86_64/ARM64)
- S3-compatible storage upload via rclone (dated + rolling "latest" releases)
- Automatic Ruby formula generation with head-build support
- SHA256 checksum computation and formula updating
- Full release workflow: build, upload, update tap, commit and push
Installation#
Install with opam:
$ opam install homebrew
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install homebrew
Configuration#
Create a homebrew.yml file:
handle: gazagnaire.org
storage:
bucket: homebrew-bottles
region: fr-par
profile: homebrew-monopam
tap:
clone_url: https://tangled.org/gazagnaire.org/homebrew-monopam.git
push_url: git@git.recoil.org:gazagnaire.org/homebrew-monopam
build:
linux: static # static (Alpine + musl) or linuxbrew (Homebrew on Linux)
packages:
- name: prune
target: prune/bin/main.exe
description: "Dead code remover for OCaml .mli files"
conflicts_with:
- graphviz
- name: merlint
target: merlint/bin/main.exe
description: "Opinionated OCaml linter powered by Merlin"
- name: agent
target: ocaml-agent/bin/main.exe
description: "Claude Code container orchestrator"
head_deps:
- name: docker
type: recommended
Package fields#
| Field | Required | Default | Description |
|---|---|---|---|
name |
yes | — | Homebrew formula name (and installed binary name) |
target |
yes | — | Path to dune executable (e.g., pkg/bin/main.exe) |
description |
yes | — | Short description for the formula |
homepage |
no | "" |
Custom homepage URL |
head_deps |
no | [] |
Runtime dependencies for --HEAD builds |
conflicts_with |
no | [] |
Homebrew packages that conflict |
Build strategy#
build.linux picks how Linux bottles are built:
static(default) — Alpine + musl container with-staticlinking. Produces fully static binaries that run on any Linux distro, and can be distributed outside Homebrew too. Requires pure-OCaml dependencies (no OpenSSL, no glibc-specific features).linuxbrew— Homebrew-on-Linux container, dynamic linking against brew's libs. Only usable viabrew installon Linux; not portable to non-brew systems.
macOS bottles always use the native runner and link dynamically against
libSystem.dylib (Apple requirement).
Optional config fields#
| Field | Default |
|---|---|
mono_url |
https://tangled.org/{handle}/mono.git |
license |
ISC |
build_dir |
_homebrew_build |
build.linux |
static |
storage.endpoint |
https://s3.{region}.scw.cloud |
storage.rclone_remote |
scaleway |
tap.local_path |
../homebrew-monopam |
S3 layout#
Uploaded bottles are laid out under the bucket as:
{bucket}/{package}/{platform}/{version}.bottle.tar.gz
{bucket}/{package}/{platform}/latest.bottle.tar.gz
Usage#
$ # Show parsed configuration
$ bottler config
$ # Build bottles for current platform
$ bottler build
$ # Build specific binaries only
$ bottler build prune merlint
$ # Upload bottles to S3
$ bottler upload
$ # Generate formula files
$ bottler formula
$ # Full release: build + upload + update tap
$ bottler release
$ # Set up Scaleway + rclone credentials
$ bottler login
$ # Verify credentials and connectivity
$ bottler doctor
API#
Homebrew.load_config- Load YAML configurationHomebrew.detect_platform- Detect current build platformHomebrew.build- Build bottlesHomebrew.upload- Upload to S3 storageHomebrew.generate_formula- Generate Ruby formulaHomebrew.sha256_file- Compute SHA256 digestHomebrew.release- Full release workflow
Related Work#
- homebrew-core - The official Homebrew formula repository
- goreleaser - Go binary release automation (similar concept for Go)
- cargo-dist - Rust binary distribution tool
Licence#
ISC License. See LICENSE.md for details.