iTranslated by AI
How to Distribute Custom CLI Tools via brew install with GoReleaser Automation

Introduction
When you create your own CLI tool, have you ever worried about how to distribute it?
It's a hassle to explain the process of "downloading from GitHub Releases, setting up the path..." every single time, isn't it?
By using Homebrew Tap, users can install it with just the following commands:
brew tap your-name/tap
brew install your-name/tap/your-tool
In this article, I will explain the steps for beginners to enable the distribution of custom CLI tools via brew install.
Overview
The mechanism of Homebrew Tap is as follows:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Tool │ │ GitHub │ │ homebrew-tap │
│ Repository │ ──▶ │ Releases │ ◀── │ Repository │
│ (Source Code) │ │ (Binaries) │ │ (Formula File) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
brew tap & install
- Create a release in the tool's repository and upload the binaries.
- Place the Formula file in the Homebrew-tap repository.
- Users install via
brew tapandbrew install.
Step 1: Create a Homebrew-tap Repository
Create a repository named homebrew-tap on GitHub.
Directory Structure
homebrew-tap/
├── Formula/
│ └── your-tool.rb # Formula file
└── README.md
README.md Example
# Homebrew Tap
Homebrew formulae for your projects.
## Installation
\`\`\`bash
brew tap your-name/tap
\`\`\`
## Available Formulae
### your-tool
Your tool description here.
\`\`\`bash
brew install your-name/tap/your-tool
\`\`\`
Step 2: Write the Formula File
Create Formula/your-tool.rb. Here is an example based on actual usage.
class YourTool < Formula
desc "Your tool description"
homepage "https://github.com/your-name/your-tool"
license "MIT"
version "1.0.0"
on_macos do
on_intel do
url "https://github.com/your-name/your-tool/releases/download/v1.0.0/your-tool_1.0.0_darwin_amd64.tar.gz"
sha256 "sha256 hash here"
end
on_arm do
url "https://github.com/your-name/your-tool/releases/download/v1.0.0/your-tool_1.0.0_darwin_arm64.tar.gz"
sha256 "sha256 hash here"
end
end
on_linux do
on_intel do
url "https://github.com/your-name/your-tool/releases/download/v1.0.0/your-tool_1.0.0_linux_amd64.tar.gz"
sha256 "sha256 hash here"
end
on_arm do
url "https://github.com/your-name/your-tool/releases/download/v1.0.0/your-tool_1.0.0_linux_arm64.tar.gz"
sha256 "sha256 hash here"
end
end
def install
bin.install "your-tool"
end
test do
system "#{bin}/your-tool", "--version"
end
end
How to obtain the sha256 hash
You can obtain it by downloading the release tar.gz file and running the following command:
shasum -a 256 your-tool_1.0.0_darwin_arm64.tar.gz
Step 3: Automate with GoReleaser (Recommended)
It is tedious to update the Formula manually every time. By using GoReleaser, you can automatically update the Homebrew-tap during the release process.
.goreleaser.yaml Configuration
version: 2
builds:
- id: your-tool
main: ./cmd/your-tool
binary: your-tool
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
archives:
- id: your-tool
formats:
- tar.gz
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
brews:
- repository:
owner: your-name
name: homebrew-tap
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
directory: Formula
homepage: "https://github.com/your-name/your-tool"
description: "Your tool description"
license: "MIT"
install: |
bin.install "your-tool"
test: |
system "#{bin}/your-tool", "--version"
GitHub Actions Configuration
Create .github/workflows/release.yml.
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
Personal Access Token Configuration
- Create a new token from GitHub Settings > Developer settings > Personal access tokens.
- Grant the
reposcope. - Register it as
HOMEBREW_TAP_GITHUB_TOKENin the tool repository's Settings > Secrets > Actions.
Now, every time you push a tag, the Homebrew-tap will be updated automatically.
Step 4: Try it out
Once everything is set up, users can install it using the following commands:
# Add the tap (first time only)
brew tap your-name/tap
# Install
brew install your-name/tap/your-tool
# Or in one line
brew install your-name/tap/your-tool
Updating is also easy.
brew upgrade your-name/tap/your-tool
Actual Examples
In the Homebrew-tap I maintain, I distribute the following tools:
- glowm — A Markdown viewer with Mermaid support
- lazyccg — An AI coding session monitoring dashboard
- gh-attach — A tool for uploading images to GitHub Issues/PRs
Summary
- Create a
homebrew-taprepository and place the Formula file inFormula/. - Calculate the sha256 hash from the release binaries.
- Use GoReleaser to automate the process.
- Users can install your tool with just
brew tap+brew install.
Try using Homebrew Tap to make the distribution of your custom CLI tools more convenient!
Discussion