Goreleaser is awesome. It's a simple tool that allows you to release your go packages. Recently, my team and I used it with a company-wide CLI tool that we built.
In this tutorial, we'll use goreleaser to automate the release of a simple go
package.
On macOS, to install goreleaser, we can install using:
go install github.com/goreleaser/goreleaser@latest
Or we use the popular homebrew package manager for macOS and Linux with:
brew install goreleaser/tap/goreleaser
On Ubuntu Linux, we can use apt
:
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
sudo apt update
sudo apt install goreleaser
More options can be found here.
Create a new folder to house our project. Then initialize the modules with:
go mod init main
Next, we create a file called main.go
. In main.go
, copy and paste the following code:
package main
func main() {
println("This is a tutorial about Goreleaser!")
}
The next step is to set up goreleaser. To do this, we run:
goreleaser init
This command creates the.goreleaser.yaml
file in our directory. We'll take a closer look at this file.
.goreleaser.yaml
I have added a few more fields to the generated .goreleaser.yaml
file. We'll go through the important parts.
release:
github:
owner: justdamilare
name: mytool
before:
hooks:
- go mod tidy
- go generate ./...
builds:
- env:
- GO_VERSION=1.19
goos:
- linux
- windows
- darwin
# replaces architecture naming in the archive name
archives:
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
# upload binaries to gcloud bucket called `mytool`
blobs:
- provider: gs
bucket: mytool
folder: "{{ .Version }}"
# generate homebrew-tap
brews:
- name: justdamilare
tap:
owner: mytool
name: homebrew-tap
folder: Formula
homepage: https://github.com/justdamilare/mytool
description: A simple go project
# use custom download strategy in case the Github repository is private
download_strategy: GitHubPrivateRepositoryReleaseDownloadStrategy
custom_require: "../custom_download_strategy"
test: |
system "#{bin}/mytool"
install: |
bin.install "mytool"
It should be noted that if homebrew-tap
and blobs
are not needed, the sections can be removed. If homebrew-tap
is needed, a GitHub repo called homebrew-tap
should be created also.
Finally, we can release our packages. To do that, we need to create a tag for our release on Git. For example, to create a tag for version 0.1.0
, we can run:
git tag v0.1.0
and
git push origin v0.1.0
Then in the directory with main.go
, run:
goreleaser release
Goreleaser will build all the binaries. These binaries will be uploaded automatically to Github using the local GitHub credentials. The builds will also be located in a /dist
folder in the home directory.
If the brew
publish method is included, a generated *.rb
file will also be in the /dist
folder. In case Goreleaser does not copy the generated Formula
to the homebrew-tap
repo automatically, it can be copied manually.
You can see how to publish the build to a private homebrew-tap here.
goreleaser init
.goreleaser.yaml
git tag vX.X.X
and then run goreleaser release
Photo by Leone Venter on Unsplash