Build Envoy on a remote Mac mini and publish the binary as a GitHub release asset.
SSHes to your Mac mini, runs a Bazel build, streams logs live, downloads the result via scp, and publishes it to a GitHub release — all from a single command. Linux builds run inside OrbStack VMs on the mini.
sshandscp(standard on macOS/Linux)gh— GitHub CLI, authenticated
brew install gh gh auth login
-
OrbStack on the Mac mini — required for Linux builds; macOS builds run natively
Both Linux machines must use Debian 11 (Bullseye) — the bundled Envoy sysroots require glibc < 2.34:
orb create --arch arm64 debian:11 linux-arm64 orb create --arch amd64 debian:11 linux-amd64
brew install dio/tap/envoy-mini-builder
Or download a binary from the releases page.
envoy-mini-builder build --sha <ref> [flags]
| Flag | Default | Description |
|---|---|---|
--sha |
(required) | Commit SHA, branch, or tag |
--repo |
envoyproxy/envoy |
Source repo (owner/repo); forks work |
--patch |
Patch applied before build: https:// URL or file:// local path |
|
--tag |
envoy-{sha8} |
Override release tag; required for variant builds |
--no-release |
false |
Build only, skip release create/upload |
--force-build |
false |
Always rebuild even if the asset already exists |
--out |
./dist |
Local directory for the downloaded binary |
--suffix |
Suffix appended to binary/asset name (e.g. -patched) |
|
--no-strip |
false |
Skip post-build strip -x |
--platform |
darwin-arm64 |
Target: darwin-arm64 | linux-arm64 | linux-amd64 |
--all-platforms |
false |
Build all supported platforms under one release |
--host |
dio@mini |
SSH host of the Mac mini |
--port |
22 |
SSH port |
--jobs |
HOST_CPUS |
Bazel --jobs value |
--bazel-arg |
Extra Bazel flag; repeatable; prefix platform: to scope (e.g. linux-arm64:--flag) |
|
--gh-repo |
dio/envoy-builder |
GitHub repo for release assets |
--bb-key |
BuildBuddy API key; see env vars below | |
--detach |
false |
Start build in background on the mini; use jobs/logs/fetch to manage |
# Minimal: build main, publish to dio/envoy-builder envoy-mini-builder build --sha main # All platforms under one release tag envoy-mini-builder build --sha main --all-platforms # Detached: start builds in background, check later envoy-mini-builder build --sha main --all-platforms --detach envoy-mini-builder jobs envoy-mini-builder fetch envoy-abc123ef # Fork + patch + custom tag envoy-mini-builder build \ --repo your-org/envoy \ --sha a1b2c3d4 \ --patch https://raw.githubusercontent.com/.../my.patch \ --suffix -patched \ --tag envoy-a1b2c3d4-patched # Build only, no release envoy-mini-builder build --sha main --no-release --out ./dist # Custom SSH host envoy-mini-builder build --sha main --host [email protected] --port 2222
| Variable | Description |
|---|---|
BUILDBUDDY_API_KEY_DARWIN_ARM64 |
BuildBuddy key for darwin arm64 builds |
BUILDBUDDY_API_KEY_LINUX_ARM64 |
BuildBuddy key for Linux arm64 builds |
BUILDBUDDY_API_KEY_LINUX_AMD64 |
BuildBuddy key for Linux amd64 builds |
BUILDBUDDY_API_KEY |
Fallback key used when no platform-specific var is set |
test run compiles and runs Bazel test targets on the remote Mac mini without
producing a release binary. The main use-case is validate a patch before
building: apply the patch remotely, compile the affected test, run it,
stream the output live.
1. List test targets matching your change
# All test targets under the affected package envoy-mini-builder test ls --sha 0d6e3c60aa55 \ --path test/extensions/clusters/dynamic_modules/... # Narrow by name glob envoy-mini-builder test ls "*cluster*" --sha 0d6e3c60aa55 \ --path test/extensions/clusters/... # Only unit tests (size = small or medium) envoy-mini-builder test ls --sha 0d6e3c60aa55 --type unit \ --path test/extensions/clusters/dynamic_modules/...
Sample output:
//test/extensions/clusters/dynamic_modules:cluster_test
1 test target(s)
If your patch adds new cc_test targets, pass --patch to see them:
envoy-mini-builder test ls --sha 0d6e3c60aa55 \
--patch file:///path/to/my.patch \
--path test/extensions/clusters/dynamic_modules/...2. Run the whole test target
envoy-mini-builder test run \
--sha 0d6e3c60aa55 \
--patch file:///path/to/my.patch \
--target //test/extensions/clusters/dynamic_modules:cluster_testThe patch is uploaded via scp before the script runs; the remote
git apply happens inside the already-cloned workspace, so only the
incremental diff is compiled.
3. Run a single GTest case
Use --filter to pass --test_filter to Bazel (forwarded as
--gtest_filter inside the binary). Any GTest filter syntax works:
# Exact case envoy-mini-builder test run \ --sha 0d6e3c60aa55 \ --patch file:///path/to/my.patch \ --target //test/extensions/clusters/dynamic_modules:cluster_test \ --filter "DynamicModuleClusterTest.AbiCallbacksAddHostsWithHostnames" # Glob across cases in a suite envoy-mini-builder test run \ --sha 0d6e3c60aa55 \ --patch file:///path/to/my.patch \ --target //test/extensions/clusters/dynamic_modules:cluster_test \ --filter "DynamicModuleClusterTest.*Hostname*"
4. Multiple targets at once
--target is repeatable:
envoy-mini-builder test run \
--sha 0d6e3c60aa55 \
--patch file:///path/to/my.patch \
--target //test/extensions/clusters/dynamic_modules:cluster_test \
--target //test/extensions/dynamic_modules:abi_testquery runs a raw bazel query and prints all matching labels — not just
test targets. Useful for checking BUILD visibility or locating a library:
envoy-mini-builder query "dynamic_module*" --sha main \
--path source/extensions/clusters/dynamic_modules/...Both --patch flags accept:
| Form | Behaviour |
|---|---|
https://… or http://… |
fetched with curl on the remote |
file:///abs/path/to/file.patch |
uploaded via scp to a temp path; deleted on exit |
| Flag | Default | Description |
|---|---|---|
--sha |
(required) | Commit SHA, branch, or tag |
--patch |
Patch: https:// URL or file:// local path |
|
--target |
(required for run) |
Bazel test target; repeatable |
--filter |
GTest filter (--test_filter value) |
|
--path |
... |
Package path for ls |
--type |
unit or integration (size-based) for ls |
|
--repo |
envoyproxy/envoy |
Source repo |
--host |
dio@mini |
SSH host |
--port |
22 |
SSH port |
--jobs |
HOST_CPUS |
Bazel --jobs |
--bb-key |
BuildBuddy API key (remote cache) | |
--platform |
darwin-arm64 |
darwin-arm64 | linux-arm64 | linux-amd64 |
--detach starts the build in the background on the mini and returns immediately.
# Start envoy-mini-builder build --sha main --all-platforms --detach # Check status envoy-mini-builder jobs # Tail logs for a specific platform envoy-mini-builder logs envoy-abc123ef --platform linux-arm64 # Download and publish once done envoy-mini-builder fetch envoy-abc123ef # Cancel and clean up envoy-mini-builder cancel envoy-abc123ef
fetch creates the GitHub release, uploads binaries, and publishes it — then removes local job state.
For each platform the CLI first checks the release for an existing asset. If found it is downloaded; its .params.json sidecar is verified to match current build params. Only missing or mismatched assets trigger a remote build. Use --force-build to always rebuild.
The auto tag envoy-{sha8} is reserved for default-param builds (envoyproxy/envoy, no patch, no extra Bazel args, no --no-strip). Variant builds must supply --tag explicitly — the CLI errors otherwise.
macOS builds
- SSH to the mini, pipe the build script to
bash -s - Stream build logs live; capture
BINARY_PATH:…sentinel from stdout - Download the binary via
scp - Upload to GitHub release via
gh
Linux builds
Same, but the build script runs inside an OrbStack VM via orb run -m <machine>. The binary lives inside the VM, so it is streamed directly to the local machine via orb run -m <machine> cat <path> over the existing SSH connection — no intermediate staging needed.
Mac mini — uses your local ssh-agent or ~/.ssh/id_{ed25519,rsa,ecdsa}. No passwords.
GitHub — uses gh CLI. Run gh auth login once; the token is never forwarded to the mini.
BuildBuddy — the API key is forwarded to the mini as a process environment variable, written to .bazelrc.cache outside the workspace, and deleted on script exit via trap. Never written to shell history or any persistent config.
git clone https://github.com/dio/envoy-mini-builder cd envoy-mini-builder go build -o envoy-mini-builder .
MIT