2017-09-10 22:07:28 +02:00
---
2017-10-01 18:57:52 +02:00
title: Builds
2017-09-10 22:07:28 +02:00
---
2018-09-20 22:44:25 +02:00
Builds can be customized in multiple ways.
You can specify for which `GOOS` , `GOARCH` and `GOARM` binaries are built
2020-05-21 14:33:11 +02:00
(goreleaser will generate a matrix of all combinations), and you can change
2018-09-05 15:38:33 +02:00
the name of the binary, flags, environment variables, hooks and etc.
2017-09-10 22:07:28 +02:00
2017-10-01 18:57:52 +02:00
Here is a commented `builds` section with all fields specified:
2017-09-10 22:07:28 +02:00
2020-05-10 23:59:21 +02:00
```yaml
2017-09-10 22:07:28 +02:00
# .goreleaser.yml
builds:
2017-10-01 18:57:52 +02:00
# You can have multiple builds defined as a yaml list
2017-09-10 22:07:28 +02:00
-
2019-04-14 20:16:01 +02:00
# ID of the build.
2019-06-28 14:09:19 +02:00
# Defaults to the project name.
2019-04-14 20:16:01 +02:00
id: "my-build"
2020-01-13 19:23:00 +02:00
# Path to project's (sub)directory containing Go code.
# This is the working directory for the Go build command(s).
# Default is `.` .
dir: go
2017-09-10 22:07:28 +02:00
# Path to main.go file or main package.
2021-04-19 13:54:55 +02:00
# Notice: when used with `gomod.proxy` , this must be a package.
#
2017-10-01 18:57:52 +02:00
# Default is `.` .
2021-04-19 13:54:55 +02:00
main: ./cmd/my-app
2017-09-10 22:07:28 +02:00
2019-02-04 13:42:13 +02:00
# Binary name.
2019-04-09 14:14:28 +02:00
# Can be a path (e.g. `bin/app` ) to wrap the binary in a directory.
2017-09-10 22:07:28 +02:00
# Default is the name of the project directory.
binary: program
2019-01-17 14:50:00 +02:00
# Custom flags templates.
2017-10-01 18:57:52 +02:00
# Default is empty.
2018-05-15 02:22:55 +02:00
flags:
2018-09-20 22:44:25 +02:00
- -tags=dev
2019-01-17 14:50:00 +02:00
- -v
2017-09-10 22:07:28 +02:00
2018-05-15 02:22:55 +02:00
# Custom asmflags templates.
2018-04-20 13:26:04 +02:00
# Default is empty.
2018-05-15 02:22:55 +02:00
asmflags:
- -D mysymbol
- all=-trimpath={{.Env.GOPATH}}
2018-04-20 13:26:04 +02:00
2018-05-15 02:22:55 +02:00
# Custom gcflags templates.
2018-04-20 13:26:04 +02:00
# Default is empty.
2018-05-15 02:22:55 +02:00
gcflags:
- all=-trimpath={{.Env.GOPATH}}
- ./dontoptimizeme=-N
2018-04-20 13:26:04 +02:00
2018-05-15 02:22:55 +02:00
# Custom ldflags templates.
2019-11-28 02:38:22 +02:00
# Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser` .
2018-05-15 02:22:55 +02:00
ldflags:
2021-05-31 18:47:39 +02:00
- -s -w -X main.build={{.Version}}
- ./usemsan=-msan
# Custom build tags templates.
# Default is empty.
tags:
- osusergo
- netgo
- static_build
- feature
2017-09-10 22:07:28 +02:00
2017-10-01 18:57:52 +02:00
# Custom environment variables to be set during the builds.
# Default is empty.
2017-09-10 22:07:28 +02:00
env:
- CGO_ENABLED=0
2017-10-01 18:57:52 +02:00
# GOOS list to build for.
# For more info refer to: https://golang.org/doc/install/source#environment
# Defaults are darwin and linux.
2017-09-10 22:07:28 +02:00
goos:
- freebsd
- windows
2017-10-01 18:57:52 +02:00
# GOARCH to build for.
# For more info refer to: https://golang.org/doc/install/source#environment
2021-01-07 14:25:52 +02:00
# Defaults are 386, amd64 and arm64.
2017-09-10 22:07:28 +02:00
goarch:
- amd64
- arm
- arm64
2017-10-01 18:57:52 +02:00
# GOARM to build for when GOARCH is arm.
# For more info refer to: https://golang.org/doc/install/source#environment
# Default is only 6.
2017-09-10 22:07:28 +02:00
goarm:
- 6
- 7
2020-01-26 19:36:00 +02:00
# GOMIPS and GOMIPS64 to build when GOARCH is mips, mips64, mipsle or mips64le.
# For more info refer to: https://golang.org/doc/install/source#environment
2021-03-20 20:17:19 +02:00
# Default is only hardfloat.
2020-01-26 19:36:00 +02:00
gomips:
- hardfloat
- softfloat
2017-09-10 22:07:28 +02:00
# List of combinations of GOOS + GOARCH + GOARM to ignore.
# Default is empty.
ignore:
- goos: darwin
goarch: 386
- goos: linux
goarch: arm
goarm: 7
2020-01-26 19:36:00 +02:00
- goarm: mips64
gomips: hardfloat
2017-09-10 22:07:28 +02:00
2020-08-30 15:15:33 +02:00
# Set a specific go binary to use when building. It is safe to ignore
# this option in most cases.
# Default is "go"
gobinary: "go1.13.4"
2020-07-06 22:09:22 +02:00
# Set the modified timestamp on the output binary, typically
# you would do this to ensure a build was reproducible. Pass
# empty string to skip modifying the output.
# Default is empty string.
mod_timestamp: '{{ .CommitTimestamp }}'
2017-10-01 18:57:52 +02:00
# Hooks can be used to customize the final binary,
# for example, to run generators.
2019-04-14 20:16:20 +02:00
# Those fields allow templates.
2017-09-10 22:07:28 +02:00
# Default is both hooks empty.
hooks:
pre: rice embed-go
2020-04-12 17:13:20 +02:00
post: ./script.sh {{ .Path }}
2020-04-02 15:18:05 +02:00
# If true, skip the build.
# Useful for library projects.
# Default is false
skip: false
2021-06-07 00:44:24 +02:00
# By default, GoRelaser will create your binaries inside `dist/${BuildID}_${BuildTarget}` , which is an unique directory per build target in the matrix.
# You are able to set subdirs within that folder using the `binary` property.
#
# However, if for some reason you don't want that unique directory to be created, you can set this property.
# If you do, you are responsible of keeping different builds from overriding each other.
#
# Defaults to `false` .
no_unique_dist_dir: true
2017-09-10 22:07:28 +02:00
```
2017-12-03 20:19:57 +02:00
2020-05-10 23:59:21 +02:00
!!! tip
2020-11-19 22:31:26 +02:00
Learn more about the [name template engine ](/customization/templates/ ).
2018-07-09 08:57:46 +02:00
2020-06-09 15:04:46 +02:00
Here is an example with multiple binaries:
```yaml
2020-12-20 15:56:00 +02:00
# .goreleaser.yml
2020-06-09 15:04:46 +02:00
builds:
2021-04-19 13:54:55 +02:00
- main: ./cmd/cli
2020-06-09 15:04:46 +02:00
id: "cli"
binary: cli
goos:
- linux
- darwin
- windows
2021-04-19 13:54:55 +02:00
- main: ./cmd/worker
2020-06-09 15:04:46 +02:00
id: "worker"
binary: worker
goos:
- linux
- darwin
- windows
2021-04-19 13:54:55 +02:00
- main: ./cmd/tracker
2020-06-09 15:04:46 +02:00
id: "tracker"
binary: tracker
goos:
- linux
- darwin
- windows
```
2021-01-12 22:27:46 +02:00
The binary name field supports [templating ](/customization/templates/ ). The following build details are exposed:
| Key | Description |
|---------|----------------------------------|
| .Os | `GOOS` |
| .Arch | `GOARCH` |
| .Arm | `GOARM` |
| .Ext | Extension, e.g. `.exe` |
| .Target | Build target, e.g. `darwin_amd64` |
2017-12-03 20:19:57 +02:00
## Passing environment variables to ldflags
You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
example:
```yaml
builds:
2018-05-15 02:22:55 +02:00
- ldflags:
- -s -w -X "main.goversion={{.Env.GOVERSION}}"
2017-12-03 20:19:57 +02:00
```
Then you can run:
2019-03-25 01:10:30 +02:00
```sh
2017-12-03 20:19:57 +02:00
GOVERSION=$(go version) goreleaser
```
2018-10-05 03:23:10 +02:00
2020-04-12 17:13:20 +02:00
## Build Hooks
Both pre and post hooks run **for each build target** , regardless of whether
these targets are generated via a matrix of OSes and architectures
or defined explicitly.
In addition to simple declarations as shown above _multiple_ hooks can be declared
to help retaining reusability of config between different build environments.
2020-05-10 23:59:21 +02:00
```yaml
2020-04-12 17:13:20 +02:00
builds:
-
id: "with-hooks"
targets:
- "darwin_amd64"
- "windows_amd64"
hooks:
pre:
- first-script.sh
- second-script.sh
post:
- upx "{{ .Path }}"
- codesign -project="{{ .ProjectName }}" "{{ .Path }}"
```
Each hook can also have its own work directory and environment variables:
2020-05-10 23:59:21 +02:00
```yaml
2020-04-12 17:13:20 +02:00
builds:
-
id: "with-hooks"
targets:
- "darwin_amd64"
- "windows_amd64"
hooks:
pre:
- cmd: first-script.sh
dir: "{{ dir .Dist}}"
env:
- HOOK_SPECIFIC_VAR={{ .Env.GLOBAL_VAR }}
- second-script.sh
```
2020-11-19 22:31:26 +02:00
All properties of a hook (`cmd`, `dir` and `env` ) support [templating ](/customization/templates/ )
2020-04-12 17:13:20 +02:00
with `post` hooks having binary artifact available (as these run _after_ the build).
Additionally the following build details are exposed to both `pre` and `post` hooks:
2020-05-26 18:24:59 +02:00
| Key | Description |
|---------|----------------------------------------|
| .Name | Filename of the binary, e.g. `bin.exe` |
| .Ext | Extension, e.g. `.exe` |
| .Path | Absolute path to the binary |
| .Target | Build target, e.g. `darwin_amd64` |
2020-04-12 17:13:20 +02:00
Environment variables are inherited and overridden in the following order:
- global (`env`)
- build (`builds[].env`)
- hook (`builds[].hooks.pre[].env` and `builds[].hooks.post[].env` )
2018-10-05 03:23:10 +02:00
## Go Modules
2019-02-26 22:17:30 +02:00
If you use Go 1.11+ with go modules or vgo, when GoReleaser runs it may
2018-10-05 03:23:10 +02:00
try to download the dependencies. Since several builds run in parallel, it is
very likely to fail.
2021-03-03 02:29:31 +02:00
You can solve this by running `go mod tidy` before calling `goreleaser` or
2020-12-20 15:56:00 +02:00
by adding a [hook][] doing that on your `.goreleaser.yml` file:
2018-10-05 03:23:10 +02:00
```yaml
before:
hooks:
2021-03-03 02:29:31 +02:00
- go mod tidy
2018-10-05 03:23:10 +02:00
# rest of the file...
```
2020-05-10 23:59:21 +02:00
[hook]: /customization/hooks
2020-01-31 20:38:56 +02:00
## Define Build Tag
GoReleaser uses `git describe` to get the build tag. You can set
a different build tag using the environment variable `GORELEASER_CURRENT_TAG` .
2020-05-10 21:57:11 +02:00
This is useful in scenarios where two tags point to the same commit.
2020-07-06 22:09:22 +02:00
## Reproducible Builds
To make your releases, checksums, and signatures reproducible, you will need to make some (if not all) of the following modifications to the build defaults in GoReleaser:
* Modify `ldflags` : by default `main.Date` is set to the time GoReleaser is run (`{{.Date}}`), you can set this to `{{.CommitDate}}` or just not pass the variable.
* Modify `mod_timestamp` : by default this is empty string, set to `{{.CommitTimestamp}}` or a constant value instead.
* If you do not run your builds from a consistent directory structure, pass `-trimpath` to `flags` .
* Remove uses of the `time` template function. This function returns a new value on every call and is not deterministic.