Stage 3 · Build
Building CLI Tools
Distribution & Installation
Homebrew, Scoop, apt/yum repos, and curl | bash installers for reaching users.
Distribution Channels
Distribution is how users get your tool. The best tools are available through multiple channels — package managers for convenience, direct downloads for automation, and container images for server deployments.
- Homebrew — macOS and Linux (most popular for developer tools)
- Scoop — Windows
- apt/yum — Server Linux distributions
- GitHub Releases — Direct binary downloads
- Docker — Container images
- curl | bash — Quick installation scripts
GoReleaser Packages
GoReleaser generates packages for Homebrew, Scoop, nfpm (deb/rpm), Docker, and more. A single configuration handles all distribution channels.
brews:
- repository:
owner: myorg
name: homebrew-tap
homepage: "https://github.com/myorg/kube-guard"
description: "Kubernetes cluster guardian"
license: "MIT"
install: |
bin.install "kube-guard"
scoops:
- repository:
owner: myorg
name: scoop-bucket
homepage: "https://github.com/myorg/kube-guard"
description: "Kubernetes cluster guardian"
nfpms:
- package_name: kube-guard
homepage: "https://github.com/myorg/kube-guard"
maintainer: "team@myorg.com"
description: "Kubernetes cluster guardian"
license: MIT
formats:
- deb
- rpmGoReleaser creates a tap formula, a scoop manifest, and deb/rpm packages automatically. It reads the binary metadata and generates all packaging files from the configuration.
Homebrew Taps
Homebrew taps are third-party repositories. Users add your tap and install your tool with brew install. This is the standard distribution method for macOS developer tools.
# Users install with:
brew tap myorg/tap
brew install kube-guard
# Or directly:
brew install myorg/tap/kube-guard
# GoReleaser generates the formula automatically
# The formula lives in your homebrew-tap repoHomebrew handles downloading, installing, and updating your tool. The tap repository contains only the formula file. GoReleaser updates the formula with each release.
Linux Package Managers
For server deployments, apt and yum packages are the standard. nfpm creates deb and rpm packages from GoReleaser configuration.
# nfpm.yml for custom packaging
name: kube-guard
arch: amd64
platform: linux
version: v1.2.0
maintainer: "team@myorg.com"
description: "Kubernetes cluster guardian"
homepage: "https://github.com/myorg/kube-guard"
license: MIT
contents:
- src: ./kube-guard
dst: /usr/local/bin/kube-guard
type: binary
- src: ./deploy/kube-guard.service
dst: /etc/systemd/system/kube-guard.service
scripts:
postinstall: scripts/post-install.sh
preremove: scripts/pre-remove.shnfpm generates deb and rpm packages. The contents section maps source files to destination paths. Scripts run during installation and removal. This is how you ship systemd units with your package.
curl | bash Installers
A curl installer downloads the latest binary for the user's platform. It is the quickest path from README to running tool.
#!/usr/bin/env bash
set -euo pipefail
REPO="myorg/kube-guard"
INSTALL_DIR="/usr/local/bin"
# Detect OS and architecture
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case $ARCH in
x86_64) ARCH="amd64" ;;
aarch64) ARCH="arm64" ;;
esac
# Get latest release
LATEST=$(curl -sL "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | cut -d'"' -f4)
# Download and install
URL="https://github.com/$REPO/releases/download/$LATEST/kube-guard_${LATEST#v}_${OS}_${ARCH}.tar.gz"
curl -sL "$URL" | tar xz -C "$INSTALL_DIR" kube-guard
echo "Installed kube-guard $LATEST"The script detects the platform, fetches the latest release tag, downloads the correct binary, and installs it. Users run: curl -sL https://get.kubeguard.dev | bash. This is the standard installation method for developer tools.
GitHub Releases
GitHub releases are the foundation of all other distribution methods. GoReleaser creates releases with binaries, archives, checksums, and changelogs automatically.
release:
github:
owner: myorg
name: kube-guard
draft: false
prerelease: auto
name_template: "v{{ .Version }}"
header: |
## kube-guard {{ .Version }}
### Changes
footer: |
**Full Changelog**: https://github.com/myorg/kube-guard/compare/{{ .PreviousTag }}...{{ .Tag }}
extra_files:
- glob: checksums.txtGoReleaser creates the release, uploads binaries and archives, attaches checksums, and generates the changelog. The release appears on GitHub immediately. Homebrew, Scoop, and apt formulas are updated automatically.
Tag a release and push — GoReleaser handles everything else. Use GitHub Actions to run GoReleaser on tag push. This gives you a one-command release: git tag v1.2.0 && git push origin v1.2.0.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.