goreleaser: Deliver Go binaries as fast and easily as possible
https://goreleaser.com| Installer Source| Releases (json) (tab)
goreleaser: Deliver Go binaries as fast and easily as possible
https://goreleaser.com| Installer Source| Releases (json) (tab)
To update or switch versions, run webi goreleaser@stable
(or @v0.174
,
@beta
, etc).
goreleaser
makes it easy to build versioned Go binaries for Mac, Linux, Windows, and Raspberry Pi, and to publish the ChangeLog and binaries to common release platforms including GitHub, Gitea, Gitlab, and Homebrew.
There's a lot that you can do with GoReleaser. These are the things that we've found the most useful for the majority of projects:
cmd/
s.goreleaser.yml
exampleThese are the files / directories that are created and/or modified with this install:
~/.config/envman/PATH.env
~/.config/goreleaser/github_token
~/.local/bin/goreleaser
<PROJECT-DIR>/.goreleaser.yaml
To create an example .goreleaser.yaml
file, and test the configuration:
goreleaser init
# dry run
goreleaser --snapshot --skip=publish --clean
--snapshot
allows "dirty" builds (when the repo has uncommitted changes)--skip=publish
will NOT publish to GitHub, etc--clean
will automatically remove the ./dist/
directoryThe default .goreleaser.yml
works well for projects for which package main
is at the root.
GoReleaser provides version information. Here's a good, generic way to print it out:
package main
var (
// these will be replaced by goreleaser
version = "0.0.0"
date = "0001-01-01T00:00:00Z"
commit = "0000000"
)
func main() {
if len(os.Args) >= 2 {
if os.Args[1] == "-V" || strings.TrimPrefix(os.Args[1]) == "version" {
fmt.Printf("CHANGE_ME v%s %s (%s)\n", version, commit[:7], date)
os.Exit(0)
}
}
// ...
}
You'll need a Personal Access Token with the repo
scope.
You can get one at https://github.com/settings/tokens/new.
You can export the environment variable:
export GITHUB_TOKEN="YOUR_GITHUB_TOKEN"
Or place the token in the default config location:
~/.config/goreleaser/github_token
You can also set env_files
in .goreleaser.yml
:
env_files:
github_token: ~/.config/goreleaser/github_token
Running GoReleaser without --snapshot
must use the latest
Git tag of your repository.
Create a tag and push it to Git:
git tag -a v1.0.0 -m "First release"
git push origin v1.0.0
Running GoReleaser without --skip=publish
will publish the builds:
goreleaser --clean
Check the console output to make sure that there are no messages about a failed
publish.
If all is well you should the git tag on the releases page updated with a ChangeLog
and the published binaries.
Gitea Token: https://try.gitea.io/user/settings/applications
env_files:
gitea_token: ~/.config/goreleaser/gitea_token
gitea_urls:
api: https://try.gitea.io/api/v1/
GitLab Token: https://gitlab.com/profile/personal_access_tokens
env_files:
gitlab_token: ~/.config/goreleaser/gitlab_token
gitlab_urls:
api: https://gitlab.com/api/v1/
Also see https://goreleaser.com/environment/
All of the Raspberry Pis are ARM processors and can run Linux. Most can run Windows as well.
aarch64
, arm64
, and armv8
.armv7
and arm64
.armv6
or armv7
.To build Go binaries for ARM, you'll need to update the build
section of your
.goreleases.yml
.
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- 386
- amd64
- arm
- arm64
goarm:
- 6
- 7
For information on other supported build options, such as BSD and ppc, see Go (Golang) GOOS and GOARCH.
cmd
DirectoryBy default GoReleaser assumes that the root of your package is package main
.
If your package main
is in a cmd/
directory or you have multiple commands,
you should update your builds
directive accordingly.
- builds:
- id: command123
main: ./cmd/command123/command123.go
binary: command123
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
- id: other321
main: ./cmd/other321/other321.go
binary: other123
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
cgo is not Go - Dave Cheney
Most Go programs are "pure Go" and will cross-compile CGO_ENABLED=0
without
any special configuration.
Some programs include C libraries, especially SQLite3 or 7z, and require integration with C libraries.
From macOS you can easily cross-compile cgo for Windows and Linux.
Install brew, if needed:
curl -sS https://webi.sh/brew | sh
Install mingw and musl-cross:
(this may take hours if pre-built binaries are not available)
brew install mingw-w64
brew install FiloSottile/musl-cross/musl-cross --with-aarch64 --with-arm # --with-mips --with-486
You may want to manually test compiling for multiple platforms before automating it:
GOARCH=amd64 GOOS=darwin go build -o unarr_darwin cmd/unarr/unarr.go
GOARCH=amd64 GOOS=windows CC=x86_64-w64-mingw32-gcc go build -o unarr.exe cmd/unarr/unarr.go
GOARCH=amd64 GOOS=linux CC=x86_64-linux-musl-gcc go build -o unarr_linux_amd64 cmd/unarr/unarr.go
GOARCH=arm64 GOOS=linux CC=aarch64-linux-musl-gcc go build -o unarr_linux_arm64 cmd/unarr/unarr.go
GOARCH=arm GOOS=linux CC=arm-linux-musl-gcc go build -o unarr_linux_armv7 cmd/unarr/unarr.go
If you have simple instructions for how to set up cross-compiling from Windows or Linux, please let us know.
You'll need to manually create a different builds
item for each unique id
:
- builds:
- id: unarr-linux-x64
main: ./cmd/unarr/unarr.go
env:
- CGO_ENABLED=1
- CC=x86_64-linux-musl-gcc
flags:
- '-ldflags'
- '-extldflags "-static"'
goos:
- linux
goarch:
- amd64
- id: unarr-linux-aarch64
main: ./cmd/unarr/unarr.go
env:
- CGO_ENABLED=1
- CC=aarch64-linux-musl-gcc
flags:
- '-ldflags'
- '-extldflags "-static"'
goos:
- linux
goarch:
- arm64
- id: unarr-linux-armv7
main: ./cmd/unarr/unarr.go
env:
- CGO_ENABLED=1
- CC=arm-linux-musleabi-gcc
flags:
- '-ldflags'
- '-extldflags "-static"'
goos:
- linux
goarch:
- arm
goarm:
- 7
- id: unarr-windows-x64
main: ./cmd/unarr/unarr.go
env:
- CGO_ENABLED=1
- CC=x86_64-w64-mingw32-gcc
flags:
- '-ldflags'
- '-extldflags "-static"'
goos:
- linux
goarch:
- amd64
If you compile without -static
, you will need the musl
libraries to run on
(non-Alpine) Linuxes:
sudo apt-get install -y musl
The full file will look something like this:
.goreleaser.yml
project_name: exampleproject
before:
hooks:
- go mod download
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
- freebsd
- js
goarch:
- 386
- amd64
- arm
- arm64
- wasm
goarm:
- 7
archives:
- id: my-binary
format: tar.xz
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: '{{ .Tag }}-next'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'