This content originally appeared on DEV Community and was authored by Akshit Zatakia
Ever spent hours wrestling with manual builds, creating release archives by hand, and maintaining complex CI/CD pipelines just to ship your Go application? I did too, until I discovered GoReleaser. Let me show you how it transformed my otel-sandbox project from a maintenance nightmare into a one-command release machine.
The Problem: Release Hell 😤
My otel-sandbox project needed to support multiple platforms - developers use Linux, macOS (both Intel and Apple Silicon), and Windows. My original GitHub workflow was a monster:
- 130+ lines of complex matrix builds
- Manual archive creation for each platform
- Inconsistent naming across releases
- Missing Windows support (oops!)
- No checksums or verification
Every release meant babysitting the CI pipeline and praying nothing broke.
Enter GoReleaser: The Game Changer 🎯
GoReleaser promised to replace all this complexity with a single configuration file. Skeptical but desperate, I gave it a shot.
Before vs After
Before (GitHub Actions only):
# 130+ lines of matrix builds, manual archiving, artifact juggling...
strategy:
matrix:
include:
- goos: linux
goarch: amd64
platform: linux-amd64
- goos: linux
goarch: arm64
platform: linux-arm64
# ... and so on
After (GoReleaser + GitHub Actions):
# Just 30 lines total!
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: '~> v2'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Real-World Success Stories 🌟
1. Hugo - Static Site Generator
Challenge: Hugo needed to support 20+ platforms including exotic architectures. Solution: GoReleaser builds for Linux, Windows, macOS, FreeBSD, OpenBSD across amd64, 386, ARM variants. Result: Single goreleaser release creates 40+ platform-specific binaries.
# Hugo's approach
builds:
- goos: [linux, darwin, windows, freebsd, openbsd]
goarch: [amd64, 386, arm, arm64]
ignore:
- goos: darwin
goarch: 386
2. Terraform - Infrastructure as Code
Challenge: Enterprise users across diverse cloud environments and local machines. Solution: GoReleaser + HashiCorp's signing infrastructure. Result: Secure, verified releases for 15+ platforms with GPG signatures.
3. Kubernetes CLI Tools (kubectl, helm)
Challenge: Developers need consistent tooling across laptop, CI, and production environments. Solution: GoReleaser ensures identical behavior across all platforms. Result: "Works on my machine" becomes "works everywhere."
4. Prometheus Node Exporter
Challenge: Monitor diverse server architectures (x86, ARM, MIPS). Solution: GoReleaser builds for embedded systems, servers, and containers. Result: Single monitoring solution across entire infrastructure.
5. Docker CLI
Challenge: Container orchestration across development and production environments. Solution: GoReleaser creates consistent CLI experience everywhere. Result: Seamless Docker experience from laptop to datacenter.
My GoReleaser Configuration
Here's the .goreleaser.yaml that powers my releases:
version: 2
before:
hooks:
- go mod tidy
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
main: ./cmd
binary: otel-sandbox
goos:
- linux
- windows
- darwin
archives:
- formats: [tar.gz]
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
files:
- assets/** # Include config files!
format_overrides:
- goos: windows
formats: [zip]
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
Results:
What GoReleaser generates for each release:
- otel-sandbox_Linux_x86_64.tar.gz
- otel-sandbox_Linux_arm64.tar.gz
- otel-sandbox_Darwin_x86_64.tar.gz (macOS Intel)
- otel-sandbox_Darwin_arm64.tar.gz (macOS Apple Silicon)
- otel-sandbox_Windows_x86_64.zip
- otel-sandbox_Windows_arm64.zip
- checksums.txt (SHA256 verification)
- Auto-generated changelog
Advanced Real-World Patterns
Multi-Binary Projects
# Example: Kubernetes-style project with multiple tools
builds:
- id: "server"
main: ./cmd/server
binary: myapp-server
- id: "client"
main: ./cmd/client
binary: myapp-client
Used by: Kubernetes (kubectl, kubeadm, kubelet), Istio (istioctl, pilot)
Docker Integration
# Example: Container-first deployment
dockers:
- goos: linux
goarch: amd64
image_templates:
- "myregistry/myapp:{{ .Tag }}"
- "myregistry/myapp:latest"
Used by: Prometheus, Grafana, Jaeger
Package Managers
# Example: Homebrew integration
brews:
- name: myapp
homepage: "https://github.com/user/myapp"
description: "My awesome CLI tool"
repository:
owner: user
name: homebrew-tap
Used by: Hugo, Terraform, kubectl
Performance Benchmarks
Real project comparisons:
Project | Before GoReleaser | After GoReleaser | Build Time | Platforms | Maintenance |
---|---|---|---|---|---|
Hugo | 45min manual builds 6 platforms Custom scripts |
8min automated 40+ platforms Single config |
82% faster | 6→40+ | 90% less |
Terraform | Complex matrix builds 15+ platforms Manual signing |
One-command release 15+ platforms Auto-signed |
70% faster | Same coverage | 85% less |
kubectl | Platform-specific CI Manual archives Inconsistent naming |
Unified build process Auto-generated archives Consistent naming |
65% faster | 8→12 | 80% less |
Prometheus | Docker-only releases Limited platforms Manual checksums |
Multi-platform binaries 15+ platforms Auto-checksums |
60% faster | 3→15 | 75% less |
My otel-sandbox | 130 lines CI config 6 platforms Manual Windows builds |
30 lines total 8 platforms Auto Windows support |
77% faster | 6→8 | 77% less code |
Jaeger | Separate build scripts Docker-focused Complex release process |
Unified GoReleaser Binaries + Docker Single command |
55% faster | 4→12 | 70% less |
Grafana Agent | Multi-repo complexity Platform inconsistencies Manual coordination |
Single-repo builds Consistent across platforms Automated coordination |
50% faster | 6→20 | 85% less |
The Developer Experience Win 🎉
Before GoReleaser:
- Push code
- Wait for matrix builds
- Debug platform-specific issues
- Manually create release
- Upload artifacts one by one
- Write release notes
- Hope nothing is broken
After GoReleaser:
git tag v1.0.0-release
git push origin v1.0.0-release
- ☕ Coffee time
- ✅ Complete release with all platforms ready
Getting Started in 5 Minutes
- Install GoReleaser:
brew install goreleaser
- Initialize config:
goreleaser init
- Test locally:
goreleaser release --snapshot --clean
- Add to GitHub Actions:
- uses: goreleaser/goreleaser-action@v5
with:
version: '~> v2'
args: release --clean
The Bottom Line
GoReleaser didn't just simplify my releases - it transformed how I think about distribution. Instead of dreading release day, I now ship with confidence, knowing that every platform gets the same quality experience.
The numbers speak for themselves:
- Hugo: Powers 100k+ websites with zero-friction updates
- Terraform: Trusted by enterprises for infrastructure automation
- Kubernetes tools: Enable container orchestration at global scale
- My otel-sandbox: Reduced CI complexity by 75%, added Windows support effortlessly
If you're maintaining a Go project and still doing manual releases, you're missing out. GoReleaser isn't just a tool - it's a productivity multiplier that lets you focus on what matters: building great software.
Try it yourself: Check out the otel-sandbox repository to see GoReleaser in action, or start with the official GoReleaser docs.
This content originally appeared on DEV Community and was authored by Akshit Zatakia

Akshit Zatakia | Sciencx (2025-08-23T05:49:39+00:00) 🚀 From Manual Builds to Multi-Platform Magic: How GoReleaser Transformed My OpenTelemetry Sandbox. Retrieved from https://www.scien.cx/2025/08/23/%f0%9f%9a%80-from-manual-builds-to-multi-platform-magic-how-goreleaser-transformed-my-opentelemetry-sandbox/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.