github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/build/build_test.go (about) 1 package build 2 3 import ( 4 "errors" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "testing" 9 10 "github.com/goreleaser/goreleaser/internal/artifact" 11 "github.com/goreleaser/goreleaser/internal/semerrgroup" 12 "github.com/goreleaser/goreleaser/internal/skips" 13 "github.com/goreleaser/goreleaser/internal/testctx" 14 "github.com/goreleaser/goreleaser/internal/testlib" 15 "github.com/goreleaser/goreleaser/internal/tmpl" 16 api "github.com/goreleaser/goreleaser/pkg/build" 17 "github.com/goreleaser/goreleaser/pkg/config" 18 "github.com/goreleaser/goreleaser/pkg/context" 19 "github.com/stretchr/testify/require" 20 ) 21 22 var ( 23 errFailedBuild = errors.New("fake builder failed") 24 errFailedDefault = errors.New("fake builder defaults failed") 25 ) 26 27 type fakeBuilder struct { 28 fail bool 29 failDefault bool 30 } 31 32 func (f *fakeBuilder) WithDefaults(build config.Build) (config.Build, error) { 33 if f.failDefault { 34 return build, errFailedDefault 35 } 36 return build, nil 37 } 38 39 func (f *fakeBuilder) Build(ctx *context.Context, _ config.Build, options api.Options) error { 40 if f.fail { 41 return errFailedBuild 42 } 43 if err := os.MkdirAll(filepath.Dir(options.Path), 0o755); err != nil { 44 return err 45 } 46 if err := os.WriteFile(options.Path, []byte("foo"), 0o755); err != nil { 47 return err 48 } 49 ctx.Artifacts.Add(&artifact.Artifact{ 50 Name: options.Name, 51 }) 52 return nil 53 } 54 55 func init() { 56 api.Register("fake", &fakeBuilder{}) 57 api.Register("fakeFail", &fakeBuilder{ 58 fail: true, 59 }) 60 api.Register("fakeFailDefault", &fakeBuilder{ 61 failDefault: true, 62 }) 63 } 64 65 func TestPipeDescription(t *testing.T) { 66 require.NotEmpty(t, Pipe{}.String()) 67 } 68 69 func TestBuild(t *testing.T) { 70 folder := testlib.Mktmp(t) 71 config := config.Project{ 72 Dist: folder, 73 Builds: []config.Build{ 74 { 75 Builder: "fake", 76 Binary: "testing.v{{.Version}}", 77 BuildDetails: config.BuildDetails{ 78 Flags: []string{"-n"}, 79 Env: []string{"BLAH=1"}, 80 }, 81 }, 82 }, 83 } 84 85 ctx := testctx.NewWithCfg( 86 config, 87 testctx.WithVersion("1.2.3"), 88 testctx.WithGitInfo(context.GitInfo{ 89 CurrentTag: "v1.2.3", 90 Commit: "123", 91 }), 92 ) 93 opts, err := buildOptionsForTarget(ctx, ctx.Config.Builds[0], "darwin_amd64") 94 require.NoError(t, err) 95 require.NoError(t, doBuild(ctx, ctx.Config.Builds[0], *opts)) 96 } 97 98 func TestRunPipe(t *testing.T) { 99 folder := testlib.Mktmp(t) 100 ctx := testctx.NewWithCfg(config.Project{ 101 Dist: folder, 102 Builds: []config.Build{ 103 { 104 Builder: "fake", 105 Binary: "testing", 106 BuildDetails: config.BuildDetails{ 107 Flags: []string{"-v"}, 108 Ldflags: []string{"-X main.test=testing"}, 109 }, 110 Targets: []string{"linux_amd64"}, 111 }, 112 }, 113 }, testctx.WithCurrentTag("2.4.5")) 114 require.NoError(t, Pipe{}.Run(ctx)) 115 require.Equal(t, []*artifact.Artifact{{ 116 Name: "testing", 117 }}, ctx.Artifacts.List()) 118 } 119 120 func TestRunFullPipe(t *testing.T) { 121 folder := testlib.Mktmp(t) 122 pre := filepath.Join(folder, "pre") 123 post := filepath.Join(folder, "post") 124 preOS := filepath.Join(folder, "pre_linux") 125 postOS := filepath.Join(folder, "post_linux") 126 config := config.Project{ 127 Builds: []config.Build{ 128 { 129 ID: "build1", 130 Builder: "fake", 131 Binary: "testing", 132 BuildDetails: config.BuildDetails{ 133 Flags: []string{"-v"}, 134 Ldflags: []string{"-X main.test=testing"}, 135 Env: []string{"THE_OS={{ .Os }}"}, 136 }, 137 Hooks: config.BuildHookConfig{ 138 Pre: []config.Hook{ 139 {Cmd: "touch " + pre}, 140 {Cmd: "touch pre_{{ .Env.THE_OS}}"}, 141 }, 142 Post: []config.Hook{ 143 {Cmd: "touch " + post}, 144 {Cmd: "touch post_{{ .Env.THE_OS}}"}, 145 }, 146 }, 147 Targets: []string{"linux_amd64"}, 148 }, 149 }, 150 Dist: folder, 151 } 152 ctx := testctx.NewWithCfg(config, testctx.WithCurrentTag("2.4.5")) 153 require.NoError(t, Pipe{}.Default(ctx)) 154 require.NoError(t, Pipe{}.Run(ctx)) 155 require.Equal(t, []*artifact.Artifact{{ 156 Name: "testing", 157 }}, ctx.Artifacts.List()) 158 require.FileExists(t, post) 159 require.FileExists(t, pre) 160 require.FileExists(t, postOS) 161 require.FileExists(t, preOS) 162 require.FileExists(t, filepath.Join(folder, "build1_linux_amd64", "testing")) 163 } 164 165 func TestRunFullPipeFail(t *testing.T) { 166 folder := testlib.Mktmp(t) 167 pre := filepath.Join(folder, "pre") 168 post := filepath.Join(folder, "post") 169 config := config.Project{ 170 Dist: folder, 171 Builds: []config.Build{ 172 { 173 Builder: "fakeFail", 174 Binary: "testing", 175 BuildDetails: config.BuildDetails{ 176 Flags: []string{"-v"}, 177 Ldflags: []string{"-X main.test=testing"}, 178 }, 179 Hooks: config.BuildHookConfig{ 180 Pre: []config.Hook{ 181 {Cmd: "touch " + pre}, 182 }, 183 Post: []config.Hook{ 184 {Cmd: "touch " + post}, 185 }, 186 }, 187 Targets: []string{"linux_amd64"}, 188 }, 189 }, 190 } 191 ctx := testctx.NewWithCfg(config, testctx.WithCurrentTag("2.4.5")) 192 require.EqualError(t, Pipe{}.Run(ctx), errFailedBuild.Error()) 193 require.Empty(t, ctx.Artifacts.List()) 194 require.FileExists(t, pre) 195 } 196 197 func TestRunPipeFailingHooks(t *testing.T) { 198 folder := testlib.Mktmp(t) 199 cfg := config.Project{ 200 Dist: folder, 201 Builds: []config.Build{ 202 { 203 Builder: "fake", 204 Binary: "hooks", 205 Hooks: config.BuildHookConfig{}, 206 Targets: []string{"linux_amd64"}, 207 }, 208 }, 209 } 210 t.Run("pre-hook", func(t *testing.T) { 211 ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) 212 ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} 213 ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "echo post"}} 214 215 err := Pipe{}.Run(ctx) 216 require.ErrorIs(t, err, exec.ErrNotFound) 217 require.ErrorContains(t, err, "pre hook failed") 218 }) 219 t.Run("post-hook", func(t *testing.T) { 220 ctx := testctx.NewWithCfg(cfg, testctx.WithCurrentTag("2.4.5")) 221 ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "echo pre"}} 222 ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} 223 err := Pipe{}.Run(ctx) 224 require.ErrorIs(t, err, exec.ErrNotFound) 225 require.ErrorContains(t, err, "post hook failed") 226 }) 227 228 t.Run("post-hook-skip", func(t *testing.T) { 229 ctx := testctx.NewWithCfg( 230 cfg, 231 testctx.WithCurrentTag("2.4.5"), 232 testctx.Skip(skips.PostBuildHooks), 233 ) 234 ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "echo pre"}} 235 ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "exit 1"}} 236 require.NoError(t, Pipe{}.Run(ctx)) 237 }) 238 239 t.Run("pre-hook-skip", func(t *testing.T) { 240 ctx := testctx.NewWithCfg( 241 cfg, 242 testctx.WithCurrentTag("2.4.5"), 243 testctx.Skip(skips.PreBuildHooks), 244 ) 245 ctx.Config.Builds[0].Hooks.Post = []config.Hook{{Cmd: "echo pre"}} 246 ctx.Config.Builds[0].Hooks.Pre = []config.Hook{{Cmd: "exit 1"}} 247 require.NoError(t, Pipe{}.Run(ctx)) 248 }) 249 } 250 251 func TestDefaultNoBuilds(t *testing.T) { 252 ctx := testctx.New() 253 require.NoError(t, Pipe{}.Default(ctx)) 254 } 255 256 func TestDefaultFail(t *testing.T) { 257 folder := testlib.Mktmp(t) 258 config := config.Project{ 259 Dist: folder, 260 Builds: []config.Build{ 261 { 262 Builder: "fakeFailDefault", 263 }, 264 }, 265 } 266 ctx := testctx.NewWithCfg(config) 267 require.EqualError(t, Pipe{}.Default(ctx), errFailedDefault.Error()) 268 require.Empty(t, ctx.Artifacts.List()) 269 } 270 271 func TestDefaultExpandEnv(t *testing.T) { 272 t.Setenv("XBAR", "FOOBAR") 273 ctx := testctx.NewWithCfg(config.Project{ 274 Builds: []config.Build{ 275 { 276 BuildDetails: config.BuildDetails{ 277 Env: []string{ 278 "XFOO=bar_$XBAR", 279 }, 280 }, 281 }, 282 }, 283 }) 284 require.NoError(t, Pipe{}.Default(ctx)) 285 env := ctx.Config.Builds[0].Env[0] 286 require.Equal(t, "XFOO=bar_FOOBAR", env) 287 } 288 289 func TestDefaultEmptyBuild(t *testing.T) { 290 ctx := testctx.NewWithCfg(config.Project{ 291 ProjectName: "foo", 292 Builds: []config.Build{ 293 {}, 294 }, 295 }) 296 require.NoError(t, Pipe{}.Default(ctx)) 297 build := ctx.Config.Builds[0] 298 require.Equal(t, ctx.Config.ProjectName, build.ID) 299 require.Equal(t, ctx.Config.ProjectName, build.Binary) 300 require.Equal(t, ".", build.Dir) 301 require.Equal(t, ".", build.Main) 302 require.Equal(t, []string{"linux", "darwin", "windows"}, build.Goos) 303 require.Equal(t, []string{"amd64", "arm64", "386"}, build.Goarch) 304 require.Equal(t, []string{"6"}, build.Goarm) 305 require.Equal(t, []string{"hardfloat"}, build.Gomips) 306 require.Equal(t, []string{"v1"}, build.Goamd64) 307 require.Len(t, build.Ldflags, 1) 308 require.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser", build.Ldflags[0]) 309 } 310 311 func TestDefaultBuildID(t *testing.T) { 312 ctx := testctx.NewWithCfg(config.Project{ 313 ProjectName: "foo", 314 Builds: []config.Build{ 315 { 316 Binary: "{{.Env.FOO}}", 317 }, 318 { 319 Binary: "bar", 320 }, 321 }, 322 }) 323 require.EqualError(t, Pipe{}.Default(ctx), "found 2 builds with the ID 'foo', please fix your config") 324 build1 := ctx.Config.Builds[0].ID 325 build2 := ctx.Config.Builds[1].ID 326 require.Equal(t, build1, build2) 327 require.Equal(t, "foo", build2) 328 } 329 330 func TestSeveralBuildsWithTheSameID(t *testing.T) { 331 ctx := testctx.NewWithCfg(config.Project{ 332 Builds: []config.Build{ 333 { 334 ID: "a", 335 Binary: "bar", 336 }, 337 { 338 ID: "a", 339 Binary: "foo", 340 }, 341 }, 342 }) 343 require.EqualError(t, Pipe{}.Default(ctx), "found 2 builds with the ID 'a', please fix your config") 344 } 345 346 func TestDefaultPartialBuilds(t *testing.T) { 347 ctx := testctx.NewWithCfg(config.Project{ 348 Builds: []config.Build{ 349 { 350 ID: "build1", 351 Binary: "bar", 352 Goos: []string{"linux"}, 353 Main: "./cmd/main.go", 354 }, 355 { 356 ID: "build2", 357 Binary: "foo", 358 Dir: "baz", 359 BuildDetails: config.BuildDetails{ 360 Ldflags: []string{"-s -w"}, 361 }, 362 Goarch: []string{"386"}, 363 }, 364 }, 365 }) 366 // Create any 'Dir' paths necessary for builds. 367 cwd, err := os.Getwd() 368 require.NoError(t, err) 369 t.Cleanup(func() { require.NoError(t, os.Chdir(cwd)) }) 370 require.NoError(t, os.Chdir(t.TempDir())) 371 for _, b := range ctx.Config.Builds { 372 if b.Dir != "" { 373 require.NoError(t, os.Mkdir(b.Dir, 0o755)) 374 } 375 } 376 require.NoError(t, Pipe{}.Default(ctx)) 377 378 t.Run("build0", func(t *testing.T) { 379 build := ctx.Config.Builds[0] 380 require.Equal(t, "bar", build.Binary) 381 require.Equal(t, ".", build.Dir) 382 require.Equal(t, "./cmd/main.go", build.Main) 383 require.Equal(t, []string{"linux"}, build.Goos) 384 require.Equal(t, []string{"amd64", "arm64", "386"}, build.Goarch) 385 require.Equal(t, []string{"6"}, build.Goarm) 386 require.Len(t, build.Ldflags, 1) 387 require.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser", build.Ldflags[0]) 388 }) 389 t.Run("build1", func(t *testing.T) { 390 build := ctx.Config.Builds[1] 391 require.Equal(t, "foo", build.Binary) 392 require.Equal(t, ".", build.Main) 393 require.Equal(t, "baz", build.Dir) 394 require.Equal(t, []string{"linux", "darwin", "windows"}, build.Goos) 395 require.Equal(t, []string{"386"}, build.Goarch) 396 require.Equal(t, []string{"6"}, build.Goarm) 397 require.Len(t, build.Ldflags, 1) 398 require.Equal(t, "-s -w", build.Ldflags[0]) 399 }) 400 } 401 402 func TestDefaultFillSingleBuild(t *testing.T) { 403 testlib.Mktmp(t) 404 405 ctx := testctx.NewWithCfg(config.Project{ 406 ProjectName: "foo", 407 SingleBuild: config.Build{ 408 Main: "testreleaser", 409 }, 410 }) 411 require.NoError(t, Pipe{}.Default(ctx)) 412 require.Len(t, ctx.Config.Builds, 1) 413 require.Equal(t, "foo", ctx.Config.Builds[0].Binary) 414 } 415 416 func TestDefaultFailSingleBuild(t *testing.T) { 417 folder := testlib.Mktmp(t) 418 config := config.Project{ 419 Dist: folder, 420 SingleBuild: config.Build{ 421 Builder: "fakeFailDefault", 422 }, 423 } 424 ctx := testctx.NewWithCfg(config) 425 require.EqualError(t, Pipe{}.Default(ctx), errFailedDefault.Error()) 426 require.Empty(t, ctx.Artifacts.List()) 427 } 428 429 func TestSkipBuild(t *testing.T) { 430 folder := testlib.Mktmp(t) 431 config := config.Project{ 432 Dist: folder, 433 Builds: []config.Build{ 434 { 435 Skip: true, 436 }, 437 }, 438 } 439 ctx := testctx.NewWithCfg(config, testctx.WithCurrentTag("2.4.5")) 440 require.NoError(t, Pipe{}.Run(ctx)) 441 require.Empty(t, ctx.Artifacts.List()) 442 } 443 444 func TestExtDarwin(t *testing.T) { 445 require.Equal(t, "", extFor("darwin_amd64", config.BuildDetails{})) 446 require.Equal(t, "", extFor("darwin_arm64", config.BuildDetails{})) 447 require.Equal(t, "", extFor("darwin_amd64", config.BuildDetails{})) 448 require.Equal(t, ".dylib", extFor("darwin_amd64", config.BuildDetails{Buildmode: "c-shared"})) 449 require.Equal(t, ".dylib", extFor("darwin_arm64", config.BuildDetails{Buildmode: "c-shared"})) 450 require.Equal(t, ".a", extFor("darwin_amd64", config.BuildDetails{Buildmode: "c-archive"})) 451 require.Equal(t, ".a", extFor("darwin_arm64", config.BuildDetails{Buildmode: "c-archive"})) 452 } 453 454 func TestExtLinux(t *testing.T) { 455 require.Equal(t, "", extFor("linux_amd64", config.BuildDetails{})) 456 require.Equal(t, "", extFor("linux_386", config.BuildDetails{})) 457 require.Equal(t, "", extFor("linux_amd64", config.BuildDetails{})) 458 require.Equal(t, ".so", extFor("linux_amd64", config.BuildDetails{Buildmode: "c-shared"})) 459 require.Equal(t, ".so", extFor("linux_386", config.BuildDetails{Buildmode: "c-shared"})) 460 require.Equal(t, ".a", extFor("linux_amd64", config.BuildDetails{Buildmode: "c-archive"})) 461 require.Equal(t, ".a", extFor("linux_386", config.BuildDetails{Buildmode: "c-archive"})) 462 } 463 464 func TestExtWindows(t *testing.T) { 465 require.Equal(t, ".exe", extFor("windows_amd64", config.BuildDetails{})) 466 require.Equal(t, ".exe", extFor("windows_386", config.BuildDetails{})) 467 require.Equal(t, ".exe", extFor("windows_amd64", config.BuildDetails{})) 468 require.Equal(t, ".dll", extFor("windows_amd64", config.BuildDetails{Buildmode: "c-shared"})) 469 require.Equal(t, ".dll", extFor("windows_386", config.BuildDetails{Buildmode: "c-shared"})) 470 require.Equal(t, ".lib", extFor("windows_amd64", config.BuildDetails{Buildmode: "c-archive"})) 471 require.Equal(t, ".lib", extFor("windows_386", config.BuildDetails{Buildmode: "c-archive"})) 472 } 473 474 func TestExtWasm(t *testing.T) { 475 require.Equal(t, ".wasm", extFor("js_wasm", config.BuildDetails{})) 476 } 477 478 func TestExtOthers(t *testing.T) { 479 require.Equal(t, "", extFor("linux_amd64", config.BuildDetails{})) 480 require.Equal(t, "", extFor("linuxwin_386", config.BuildDetails{})) 481 require.Equal(t, "", extFor("winasdasd_sad", config.BuildDetails{})) 482 require.Equal(t, ".so", extFor("aix_amd64", config.BuildDetails{Buildmode: "c-shared"})) 483 require.Equal(t, ".a", extFor("android_386", config.BuildDetails{Buildmode: "c-archive"})) 484 require.Equal(t, ".so", extFor("winasdasd_sad", config.BuildDetails{Buildmode: "c-shared"})) 485 } 486 487 func TestTemplate(t *testing.T) { 488 ctx := testctx.New( 489 testctx.WithEnv(map[string]string{"FOO": "123"}), 490 testctx.WithVersion("1.2.3"), 491 testctx.WithCurrentTag("v1.2.3"), 492 testctx.WithCommit("123"), 493 ) 494 binary, err := tmpl.New(ctx). 495 Apply(`-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}"`) 496 require.NoError(t, err) 497 require.Contains(t, binary, "-s -w") 498 require.Contains(t, binary, "-X main.version=1.2.3") 499 require.Contains(t, binary, "-X main.tag=v1.2.3") 500 require.Contains(t, binary, "-X main.commit=123") 501 require.Contains(t, binary, "-X main.date=") 502 require.Contains(t, binary, `-X "main.foo=123"`) 503 } 504 505 func TestBuild_hooksKnowGoosGoarch(t *testing.T) { 506 tmpDir := testlib.Mktmp(t) 507 build := config.Build{ 508 Builder: "fake", 509 Goarch: []string{"amd64"}, 510 Goos: []string{"linux"}, 511 Binary: "testing-goos-goarch.v{{.Version}}", 512 Targets: []string{ 513 "linux_amd64", 514 }, 515 Hooks: config.BuildHookConfig{ 516 Pre: []config.Hook{ 517 {Cmd: "touch pre-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, 518 }, 519 Post: config.Hooks{ 520 {Cmd: "touch post-hook-{{.Arch}}-{{.Os}}", Dir: tmpDir}, 521 }, 522 }, 523 } 524 525 ctx := testctx.NewWithCfg(config.Project{ 526 Builds: []config.Build{ 527 build, 528 }, 529 }) 530 g := semerrgroup.New(ctx.Parallelism) 531 runPipeOnBuild(ctx, g, build) 532 require.NoError(t, g.Wait()) 533 require.FileExists(t, filepath.Join(tmpDir, "pre-hook-amd64-linux")) 534 require.FileExists(t, filepath.Join(tmpDir, "post-hook-amd64-linux")) 535 } 536 537 func TestPipeOnBuild_hooksRunPerTarget(t *testing.T) { 538 tmpDir := testlib.Mktmp(t) 539 540 build := config.Build{ 541 Builder: "fake", 542 Binary: "testing.v{{.Version}}", 543 Targets: []string{ 544 "linux_amd64", 545 "darwin_amd64", 546 "windows_amd64", 547 }, 548 Hooks: config.BuildHookConfig{ 549 Pre: []config.Hook{ 550 {Cmd: "touch pre-hook-{{.Target}}", Dir: tmpDir}, 551 }, 552 Post: config.Hooks{ 553 {Cmd: "touch post-hook-{{.Target}}", Dir: tmpDir}, 554 }, 555 }, 556 } 557 ctx := testctx.NewWithCfg(config.Project{ 558 Builds: []config.Build{ 559 build, 560 }, 561 }) 562 g := semerrgroup.New(ctx.Parallelism) 563 runPipeOnBuild(ctx, g, build) 564 require.NoError(t, g.Wait()) 565 require.FileExists(t, filepath.Join(tmpDir, "pre-hook-linux_amd64")) 566 require.FileExists(t, filepath.Join(tmpDir, "pre-hook-darwin_amd64")) 567 require.FileExists(t, filepath.Join(tmpDir, "pre-hook-windows_amd64")) 568 require.FileExists(t, filepath.Join(tmpDir, "post-hook-linux_amd64")) 569 require.FileExists(t, filepath.Join(tmpDir, "post-hook-darwin_amd64")) 570 require.FileExists(t, filepath.Join(tmpDir, "post-hook-windows_amd64")) 571 } 572 573 func TestPipeOnBuild_invalidBinaryTpl(t *testing.T) { 574 build := config.Build{ 575 Builder: "fake", 576 Binary: "testing.v{{.XYZ}}", 577 Targets: []string{ 578 "linux_amd64", 579 }, 580 } 581 ctx := testctx.NewWithCfg(config.Project{ 582 Builds: []config.Build{ 583 build, 584 }, 585 }) 586 g := semerrgroup.New(ctx.Parallelism) 587 runPipeOnBuild(ctx, g, build) 588 testlib.RequireTemplateError(t, g.Wait()) 589 } 590 591 func TestBuildOptionsForTarget(t *testing.T) { 592 tmpDir := testlib.Mktmp(t) 593 594 testCases := []struct { 595 name string 596 build config.Build 597 expectedOpts *api.Options 598 expectedErr string 599 }{ 600 { 601 name: "simple options for target", 602 build: config.Build{ 603 ID: "testid", 604 Binary: "testbinary", 605 Targets: []string{ 606 "linux_amd64", 607 }, 608 }, 609 expectedOpts: &api.Options{ 610 Name: "testbinary", 611 Path: filepath.Join(tmpDir, "testid_linux_amd64_v1", "testbinary"), 612 Target: "linux_amd64_v1", 613 Goos: "linux", 614 Goarch: "amd64", 615 Goamd64: "v1", 616 }, 617 }, 618 { 619 name: "binary name with Os and Arch template variables", 620 build: config.Build{ 621 ID: "testid", 622 Binary: "testbinary_{{.Os}}_{{.Arch}}", 623 Targets: []string{ 624 "linux_amd64", 625 }, 626 }, 627 expectedOpts: &api.Options{ 628 Name: "testbinary_linux_amd64", 629 Path: filepath.Join(tmpDir, "testid_linux_amd64_v1", "testbinary_linux_amd64"), 630 Target: "linux_amd64_v1", 631 Goos: "linux", 632 Goarch: "amd64", 633 Goamd64: "v1", 634 }, 635 }, 636 { 637 name: "overriding dist path", 638 build: config.Build{ 639 ID: "testid", 640 Binary: "distpath/{{.Os}}/{{.Arch}}/testbinary_{{.Os}}_{{.Arch}}", 641 Targets: []string{ 642 "linux_amd64", 643 }, 644 NoUniqueDistDir: true, 645 }, 646 expectedOpts: &api.Options{ 647 Name: "distpath/linux/amd64/testbinary_linux_amd64", 648 Path: filepath.Join(tmpDir, "distpath", "linux", "amd64", "testbinary_linux_amd64"), 649 Target: "linux_amd64_v1", 650 Goos: "linux", 651 Goarch: "amd64", 652 Goamd64: "v1", 653 }, 654 }, 655 { 656 name: "with goarm", 657 build: config.Build{ 658 ID: "testid", 659 Binary: "testbinary", 660 Targets: []string{ 661 "linux_arm_6", 662 }, 663 }, 664 expectedOpts: &api.Options{ 665 Name: "testbinary", 666 Path: filepath.Join(tmpDir, "testid_linux_arm_6", "testbinary"), 667 Target: "linux_arm_6", 668 Goos: "linux", 669 Goarch: "arm", 670 Goarm: "6", 671 }, 672 }, 673 { 674 name: "with gomips", 675 build: config.Build{ 676 ID: "testid", 677 Binary: "testbinary", 678 Targets: []string{ 679 "linux_mips_softfloat", 680 }, 681 }, 682 expectedOpts: &api.Options{ 683 Name: "testbinary", 684 Path: filepath.Join(tmpDir, "testid_linux_mips_softfloat", "testbinary"), 685 Target: "linux_mips_softfloat", 686 Goos: "linux", 687 Goarch: "mips", 688 Gomips: "softfloat", 689 }, 690 }, 691 { 692 name: "with goamd64", 693 build: config.Build{ 694 ID: "testid", 695 Binary: "testbinary", 696 Targets: []string{ 697 "linux_amd64_v3", 698 }, 699 }, 700 expectedOpts: &api.Options{ 701 Name: "testbinary", 702 Path: filepath.Join(tmpDir, "testid_linux_amd64_v3", "testbinary"), 703 Target: "linux_amd64_v3", 704 Goos: "linux", 705 Goarch: "amd64", 706 Goamd64: "v3", 707 }, 708 }, 709 } 710 711 for _, tc := range testCases { 712 t.Run(tc.name, func(t *testing.T) { 713 ctx := testctx.NewWithCfg(config.Project{ 714 Dist: tmpDir, 715 Builds: []config.Build{tc.build}, 716 }) 717 require.NoError(t, Pipe{}.Default(ctx)) 718 opts, err := buildOptionsForTarget(ctx, ctx.Config.Builds[0], ctx.Config.Builds[0].Targets[0]) 719 if tc.expectedErr == "" { 720 require.NoError(t, err) 721 require.Equal(t, tc.expectedOpts, opts) 722 } else { 723 require.EqualError(t, err, tc.expectedErr) 724 } 725 }) 726 } 727 } 728 729 func TestRunHookFailWithLogs(t *testing.T) { 730 folder := testlib.Mktmp(t) 731 config := config.Project{ 732 Dist: folder, 733 Builds: []config.Build{ 734 { 735 Builder: "fakeFail", 736 Binary: "testing", 737 BuildDetails: config.BuildDetails{ 738 Flags: []string{"-v"}, 739 }, 740 Hooks: config.BuildHookConfig{ 741 Pre: []config.Hook{ 742 {Cmd: "sh -c 'echo foo; exit 1'"}, 743 }, 744 }, 745 Targets: []string{"linux_amd64"}, 746 }, 747 }, 748 } 749 ctx := testctx.NewWithCfg(config, testctx.WithCurrentTag("2.4.5")) 750 err := Pipe{}.Run(ctx) 751 require.ErrorContains(t, err, "pre hook failed") 752 require.Empty(t, ctx.Artifacts.List()) 753 }