gobottle

command module
v0.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 4 Imported by: 0

README

gobottle

Status: experimental. Interfaces and behavior change without notice.

gobottle is ko for Homebrew: it cross-compiles Go binaries, packages them as real Homebrew bottles, publishes them to GHCR using the same OCI conventions as homebrew-core, and generates the tap formula — all in pure Go, from any platform, with no Ruby, no skopeo, and no per-OS build runners.

Nothing else in the ecosystem does this: goreleaser generates formulae (now casks) that build from source or download release tarballs; official bottles require brew bottle + brew pr-upload running natively on every target platform. Static Go binaries (CGO_ENABLED=0) don't need any of that — one machine can bottle for every platform Homebrew supports.

Pipeline

gobottle build   -o json > bottles.json   # cross-compile + package bottles
gobottle push    -o json < bottles.json   # publish OCI index + blobs to GHCR
gobottle release -i bottles.json          # generate formula, commit to tap

Each verb emits machine-readable JSON on stdout (progress on stderr), so the stages compose in CI; gobottle release without -i runs the whole pipeline in one shot.

Configuration lives in .gobottle.yaml (see gobottle init); the formula is fully generated — description, license, dependencies, caveats, completions, test block and more are driven from the formula: section of the config, with a Go-template escape hatch for anything not yet modeled.

The generated formula also builds from source: its def install emits depends_on "go" => :build and system "go", "build", *std_go_args(...) with the ldflags, tags and flags inherited from source.build, so brew install --build-from-source and brew install --HEAD compile correctly while everyone else gets a poured bottle. Override it under formula.build, or set formula.build.enabled: false for the older bottle-only install block (the head stanza is then omitted, since a bin.install block cannot build a git checkout). gobottle init imports the build recipe from an existing goreleaser config so the source build reproduces the released binaries.

Recovering a failed release

gobottle release is idempotent: bottles already in the registry are re-pushed unchanged and an up-to-date formula is not committed again, so a release that failed part-way (say, a GitHub 5xx on the tap commit) is simply re-run. Keep bottles.json as a workflow artifact and the formula step alone can be replayed without rebuilding:

gh run download <run-id> -n bottles-manifest-v1.2.3
GOBOTTLE_TAP_TOKEN=... gobottle release -i bottles.json

Installation

brew trust isometry/tap               # Homebrew ≥6: one-time tap trust
brew install isometry/tap/gobottle    # poured as a bottle, naturally
go install github.com/isometry/gobottle@latest

In GitHub Actions, use isometry/gobottle-setup to install from verified release binaries.

Requirements

  • Go toolchain (for --source=go builds)
  • A GitHub token with write:packages (GHCR) and contents: write (tap)
  • After the first push, flip the GHCR package visibility to public so brew's anonymous pulls work

Claude Code plugin

This repository doubles as a Claude Code plugin providing a gobottle skill (usage, configuration reference, and a goreleaser-migration guide):

/plugin marketplace add isometry/gobottle
/plugin install gobottle@gobottle

License

MIT — see LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
git
Package git provides git repository operations using go-git.
Package git provides git repository operations using go-git.
oci
Package oci publishes Homebrew bottles to an OCI registry using the exact conventions brew expects when pouring from GHCR (Homebrew's github_packages.rb is the reference implementation):
Package oci publishes Homebrew bottles to an OCI registry using the exact conventions brew expects when pouring from GHCR (Homebrew's github_packages.rb is the reference implementation):
tap

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL