github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/www/docs/customization/build.md (about) 1 --- 2 title: Builds 3 --- 4 5 Builds can be customized in multiple ways. 6 You can specify for which `GOOS`, `GOARCH` and `GOARM` binaries are built 7 (goreleaser will generate a matrix of all combinations), and you can change 8 the name of the binary, flags, environment variables, hooks and etc. 9 10 Here is a commented `builds` section with all fields specified: 11 12 ```yaml 13 # .goreleaser.yml 14 builds: 15 # You can have multiple builds defined as a yaml list 16 - 17 # ID of the build. 18 # Defaults to the project name. 19 id: "my-build" 20 21 # Path to project's (sub)directory containing Go code. 22 # This is the working directory for the Go build command(s). 23 # Default is `.`. 24 dir: go 25 26 # Path to main.go file or main package. 27 # Notice: when used with `gomod.proxy`, this must be a package. 28 # 29 # Default is `.`. 30 main: ./cmd/my-app 31 32 # Binary name. 33 # Can be a path (e.g. `bin/app`) to wrap the binary in a directory. 34 # Default is the name of the project directory. 35 binary: program 36 37 # Custom flags templates. 38 # Default is empty. 39 flags: 40 - -tags=dev 41 - -v 42 43 # Custom asmflags templates. 44 # Default is empty. 45 asmflags: 46 - -D mysymbol 47 - all=-trimpath={{.Env.GOPATH}} 48 49 # Custom gcflags templates. 50 # Default is empty. 51 gcflags: 52 - all=-trimpath={{.Env.GOPATH}} 53 - ./dontoptimizeme=-N 54 55 # Custom ldflags templates. 56 # Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser`. 57 ldflags: 58 - -s -w -X main.build={{.Version}} 59 - ./usemsan=-msan 60 61 # Custom build tags templates. 62 # Default is empty. 63 tags: 64 - osusergo 65 - netgo 66 - static_build 67 - feature 68 69 # Custom environment variables to be set during the builds. 70 # Default is empty. 71 env: 72 - CGO_ENABLED=0 73 74 # GOOS list to build for. 75 # For more info refer to: https://golang.org/doc/install/source#environment 76 # Defaults are darwin and linux. 77 goos: 78 - freebsd 79 - windows 80 81 # GOARCH to build for. 82 # For more info refer to: https://golang.org/doc/install/source#environment 83 # Defaults are 386, amd64 and arm64. 84 goarch: 85 - amd64 86 - arm 87 - arm64 88 89 # GOARM to build for when GOARCH is arm. 90 # For more info refer to: https://golang.org/doc/install/source#environment 91 # Default is only 6. 92 goarm: 93 - 6 94 - 7 95 96 # GOMIPS and GOMIPS64 to build when GOARCH is mips, mips64, mipsle or mips64le. 97 # For more info refer to: https://golang.org/doc/install/source#environment 98 # Default is only hardfloat. 99 gomips: 100 - hardfloat 101 - softfloat 102 103 # List of combinations of GOOS + GOARCH + GOARM to ignore. 104 # Default is empty. 105 ignore: 106 - goos: darwin 107 goarch: 386 108 - goos: linux 109 goarch: arm 110 goarm: 7 111 - goarm: mips64 112 gomips: hardfloat 113 114 # Optionally override the matrix generation and specify only the final list of targets. 115 # Format is `{goos}_{goarch}` with optionally a suffix with `_{goarm}` or `_{gomips}`. 116 # This overrides `goos`, `goarch`, `goarm`, `gomips` and `ignores`. 117 targets: 118 - linux_amd64 119 - darwin_arm64 120 - linux_arm_6 121 122 # Set a specific go binary to use when building. It is safe to ignore 123 # this option in most cases. 124 # Default is "go" 125 gobinary: "go1.13.4" 126 127 # Set the modified timestamp on the output binary, typically 128 # you would do this to ensure a build was reproducible. Pass 129 # empty string to skip modifying the output. 130 # Default is empty string. 131 mod_timestamp: '{{ .CommitTimestamp }}' 132 133 # Hooks can be used to customize the final binary, 134 # for example, to run generators. 135 # Those fields allow templates. 136 # Default is both hooks empty. 137 hooks: 138 pre: rice embed-go 139 post: ./script.sh {{ .Path }} 140 141 # If true, skip the build. 142 # Useful for library projects. 143 # Default is false 144 skip: false 145 146 # By default, GoRelaser will create your binaries inside `dist/${BuildID}_${BuildTarget}`, which is an unique directory per build target in the matrix. 147 # You are able to set subdirs within that folder using the `binary` property. 148 # 149 # However, if for some reason you don't want that unique directory to be created, you can set this property. 150 # If you do, you are responsible of keeping different builds from overriding each other. 151 # 152 # Defaults to `false`. 153 no_unique_dist_dir: true 154 155 # Builder allows you to use a different build implementation. 156 # This is a GoReleaser Pro feature. 157 # Valid options are: `go` and `prebuilt`. 158 # Defaults to `go`. 159 builder: prebuilt 160 ``` 161 162 !!! tip 163 Learn more about the [name template engine](/customization/templates/). 164 165 Here is an example with multiple binaries: 166 167 ```yaml 168 # .goreleaser.yml 169 builds: 170 - main: ./cmd/cli 171 id: "cli" 172 binary: cli 173 goos: 174 - linux 175 - darwin 176 - windows 177 178 - main: ./cmd/worker 179 id: "worker" 180 binary: worker 181 goos: 182 - linux 183 - darwin 184 - windows 185 186 - main: ./cmd/tracker 187 id: "tracker" 188 binary: tracker 189 goos: 190 - linux 191 - darwin 192 - windows 193 ``` 194 195 The binary name field supports [templating](/customization/templates/). The following build details are exposed: 196 197 | Key | Description | 198 |---------|----------------------------------| 199 | .Os | `GOOS` | 200 | .Arch | `GOARCH` | 201 | .Arm | `GOARM` | 202 | .Ext | Extension, e.g. `.exe` | 203 | .Target | Build target, e.g. `darwin_amd64`| 204 205 ## Passing environment variables to ldflags 206 207 You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for 208 example: 209 210 ```yaml 211 # .goreleaser.yml 212 builds: 213 - ldflags: 214 - -s -w -X "main.goversion={{.Env.GOVERSION}}" 215 ``` 216 217 Then you can run: 218 219 ```sh 220 GOVERSION=$(go version) goreleaser 221 ``` 222 223 ## Build Hooks 224 225 Both pre and post hooks run **for each build target**, regardless of whether 226 these targets are generated via a matrix of OSes and architectures 227 or defined explicitly. 228 229 In addition to simple declarations as shown above _multiple_ hooks can be declared 230 to help retaining reusability of config between different build environments. 231 232 ```yaml 233 # .goreleaser.yml 234 builds: 235 - 236 id: "with-hooks" 237 targets: 238 - "darwin_amd64" 239 - "windows_amd64" 240 hooks: 241 pre: 242 - first-script.sh 243 - second-script.sh 244 post: 245 - upx "{{ .Path }}" 246 - codesign -project="{{ .ProjectName }}" "{{ .Path }}" 247 ``` 248 249 Each hook can also have its own work directory and environment variables: 250 251 ```yaml 252 # .goreleaser.yml 253 builds: 254 - 255 id: "with-hooks" 256 targets: 257 - "darwin_amd64" 258 - "windows_amd64" 259 hooks: 260 pre: 261 - cmd: first-script.sh 262 dir: "{{ dir .Dist}}" 263 env: 264 - HOOK_SPECIFIC_VAR={{ .Env.GLOBAL_VAR }} 265 - second-script.sh 266 ``` 267 268 All properties of a hook (`cmd`, `dir` and `env`) support [templating](/customization/templates/) 269 with `post` hooks having binary artifact available (as these run _after_ the build). 270 Additionally the following build details are exposed to both `pre` and `post` hooks: 271 272 | Key | Description | 273 |---------|----------------------------------------| 274 | .Name | Filename of the binary, e.g. `bin.exe` | 275 | .Ext | Extension, e.g. `.exe` | 276 | .Path | Absolute path to the binary | 277 | .Target | Build target, e.g. `darwin_amd64` | 278 279 Environment variables are inherited and overridden in the following order: 280 281 - global (`env`) 282 - build (`builds[].env`) 283 - hook (`builds[].hooks.pre[].env` and `builds[].hooks.post[].env`) 284 285 ## Go Modules 286 287 If you use Go 1.11+ with go modules or vgo, when GoReleaser runs it may 288 try to download the dependencies. Since several builds run in parallel, it is 289 very likely to fail. 290 291 You can solve this by running `go mod tidy` before calling `goreleaser` or 292 by adding a [hook][] doing that on your `.goreleaser.yml` file: 293 294 ```yaml 295 # .goreleaser.yml 296 before: 297 hooks: 298 - go mod tidy 299 # rest of the file... 300 ``` 301 302 [hook]: /customization/hooks 303 304 ## Define Build Tag 305 306 GoReleaser uses `git describe` to get the build tag. You can set 307 a different build tag using the environment variable `GORELEASER_CURRENT_TAG`. 308 This is useful in scenarios where two tags point to the same commit. 309 310 ## Reproducible Builds 311 312 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: 313 314 * 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. 315 * Modify `mod_timestamp`: by default this is empty string, set to `{{.CommitTimestamp}}` or a constant value instead. 316 * If you do not run your builds from a consistent directory structure, pass `-trimpath` to `flags`. 317 * Remove uses of the `time` template function. This function returns a new value on every call and is not deterministic. 318 319 ## Import pre-built binaries 320 321 !!! success "GoReleaser Pro" 322 The prebuilt builder is a [GoReleaser Pro feature](/pro/). 323 324 Since GoReleaser Pro v0.179.0, it is possible to import pre-built binaries into the GoReleaser lifecycle. 325 326 Reasons you might want to do that include: 327 328 - You want to build your binaries in different machines due to CGO 329 - You want to build using a pre-existing `Makefile` or other tool 330 - You want to speed up the build by running several builds in parallel in different machines 331 332 In any case, its pretty easy to do that now: 333 334 ```yaml 335 # .goreleaser.yml 336 builds: 337 - 338 # Set the builder to prebuilt 339 builder: prebuilt 340 341 # When builder is `prebuilt` there are no defaults for goos, goarch, 342 # goarm, gomips and targets. 343 goos: 344 - linux 345 - darwin 346 goarch: 347 - amd64 348 - arm64 349 350 # prebuilt specific options 351 prebuilt: 352 # Path must be the template path to the binaries. 353 # GoReleaser removes the `dist` folder before running, so you will likely 354 # want to put the binaries elsewhere. 355 # This field is required when using the `prebuilt` builder. 356 path: output/mybin_{{ .Os }}_{{ .Arch }} 357 ``` 358 359 This example config will import into your release pipeline the following binaries: 360 361 - `output/mybin_linux_amd64` 362 - `output/mybin_linux_arm64` 363 - `output/mybin_darwin_amd64` 364 - `output/mybin_darwin_arm64` 365 366 The other steps of the pipeline will act as if those were built by GoReleaser itself. 367 There is no difference in how the binaries are handled. 368 369 !!! tip 370 A cool tip here, specially when using CGO, is that you can have one 371 `.goreleaser.yml` file just for the builds, build each in its own machine 372 with [`goreleaser build --single-target`](/cmd/goreleaser_build/) and 373 have a second `.goreleaser.yml` file that imports those binaries 374 and release them. 375 This tip can also be used to speed up the build process if you run all the 376 builds in different machines in parallel. 377 378 !!! warning 379 GoReleaser will try to stat the final path, if any error happens while 380 doing that (e.g. file does not exist or permission issues), 381 GoReleaser will fail. 382 383 !!! warning 384 When using the `prebuilt` binary, there are no defaults for `goos` et al, 385 so you need to either provide those or the final `targets` matrix.