1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-12 03:51:10 +02:00

fix: improve goreleaser build --single-target (#5379)

- removed duplicate handling of default _extra bit of Go targets
- allow to set `TARGET` (esp for other builders)
This commit is contained in:
Carlos Alexandro Becker 2024-12-19 16:06:29 -03:00 committed by GitHub
parent 6109692be9
commit 0bc463dbec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 123 additions and 69 deletions

View File

@ -34,6 +34,7 @@ var Default = &Builder{}
var (
_ api.Builder = &Builder{}
_ api.DependingBuilder = &Builder{}
_ api.TargetFixer = &Builder{}
)
//nolint:gochecknoinits
@ -166,6 +167,11 @@ func (*Builder) WithDefaults(build config.Build) (config.Build, error) {
return build, nil
}
// FixTarget implements build.TargetFixer.
func (b *Builder) FixTarget(target string) string {
return fixTarget(target)
}
func fixTarget(target string) string {
if strings.HasSuffix(target, "_amd64") {
return target + "_v1"

View File

@ -122,7 +122,7 @@ func buildWithDefaults(ctx *context.Context, build config.Build) (config.Build,
}
func runPipeOnBuild(ctx *context.Context, g semerrgroup.Group, build config.Build) {
for _, target := range filter(ctx, build.Targets) {
for _, target := range filter(ctx, build) {
g.Go(func() error {
return buildTarget(ctx, build, target)
})

View File

@ -4,19 +4,24 @@ import (
"fmt"
"github.com/caarlos0/log"
builders "github.com/goreleaser/goreleaser/v2/pkg/build"
"github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/goreleaser/goreleaser/v2/pkg/context"
)
func filter(ctx *context.Context, targets []string) []string {
func filter(ctx *context.Context, build config.Build) []string {
if !ctx.Partial {
return targets
return build.Targets
}
target := ctx.PartialTarget
fixer, ok := builders.For(build.Builder).(builders.TargetFixer)
if ok {
target = fixer.FixTarget(target)
}
log.WithField("match", fmt.Sprintf("target=%s", target)).Infof("partial build")
var result []string
for _, t := range targets {
for _, t := range build.Targets {
if t != target {
continue
}

View File

@ -4,6 +4,7 @@ import (
"testing"
"github.com/goreleaser/goreleaser/v2/internal/testctx"
"github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/goreleaser/goreleaser/v2/pkg/context"
"github.com/stretchr/testify/require"
)
@ -21,7 +22,10 @@ var filterTestTargets = []string{
func TestFilter(t *testing.T) {
t.Run("none", func(t *testing.T) {
ctx := testctx.New()
require.Equal(t, filterTestTargets, filter(ctx, filterTestTargets))
require.Equal(t, filterTestTargets, filter(ctx, config.Build{
Builder: "go",
Targets: filterTestTargets,
}))
})
t.Run("target", func(t *testing.T) {
@ -31,7 +35,23 @@ func TestFilter(t *testing.T) {
})
require.Equal(t, []string{
"darwin_amd64_v1",
}, filter(ctx, filterTestTargets))
}, filter(ctx, config.Build{
Builder: "go",
Targets: filterTestTargets,
}))
})
t.Run("incomplete target", func(t *testing.T) {
ctx := testctx.New(func(ctx *context.Context) {
ctx.Partial = true
ctx.PartialTarget = "darwin_amd64"
})
require.Equal(t, []string{
"darwin_amd64_v1",
}, filter(ctx, config.Build{
Builder: "go",
Targets: filterTestTargets,
}))
})
t.Run("target no match", func(t *testing.T) {
@ -39,6 +59,9 @@ func TestFilter(t *testing.T) {
ctx.Partial = true
ctx.PartialTarget = "linux_amd64_v1"
})
require.Empty(t, filter(ctx, []string{"darwin_amd64_v1"}))
require.Empty(t, filter(ctx, config.Build{
Builder: "go",
Targets: []string{"darwin_amd64_v1"},
}))
})
}

View File

@ -2,11 +2,11 @@ package partial
import (
"cmp"
"errors"
"os"
"runtime"
"strings"
"github.com/goreleaser/goreleaser/v2/internal/experimental"
"github.com/goreleaser/goreleaser/v2/pkg/context"
)
@ -16,45 +16,51 @@ func (Pipe) String() string { return "partial" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Partial }
func (Pipe) Run(ctx *context.Context) error {
ctx.PartialTarget = getFilter()
if t := os.Getenv("TARGET"); t != "" {
ctx.PartialTarget = t
return nil
}
for _, b := range ctx.Config.Builds {
if b.Builder == "go" {
ctx.PartialTarget = getGoEnvFilter()
}
}
if ctx.PartialTarget == "" {
return errors.New("could not setup the target filter, maybe set TARGET=[something]")
}
return nil
}
func getFilter() string {
var archExtraEnvs = map[string][]string{
"386": {"GGO386", "GO386"},
"amd64": {"GGOAMD64", "GOAMD64"},
"arm": {"GGOARM", "GOARM"},
"arm64": {"GGOARM64", "GOARM64"},
"mips": {"GGOMIPS", "GOMIPS"},
"mips64": {"GGOMIPS", "GOMIPS"},
"mips64le": {"GGOMIPS", "GOMIPS"},
"mipsle": {"GGOMIPS", "GOMIPS"},
"ppc64": {"GGOPPC64", "GOPPC64"},
"riscv64": {"GGORISCV64", "GORISCV64"},
}
func getGoEnvFilter() string {
goos := cmp.Or(os.Getenv("GGOOS"), os.Getenv("GOOS"), runtime.GOOS)
goarch := cmp.Or(os.Getenv("GGOARCH"), os.Getenv("GOARCH"), runtime.GOARCH)
target := goos + "_" + goarch
if strings.HasSuffix(target, "_amd64") {
goamd64 := cmp.Or(os.Getenv("GGOAMD64"), os.Getenv("GOAMD64"), "v1")
target = target + "_" + goamd64
}
if strings.HasSuffix(target, "_arm") {
goarm := cmp.Or(os.Getenv("GGOARM"), os.Getenv("GOARM"), experimental.DefaultGOARM())
target = target + "_" + goarm
}
if strings.HasSuffix(target, "_arm64") {
goarm := cmp.Or(os.Getenv("GGOARM64"), os.Getenv("GOARM64"), "v8.0")
target = target + "_" + goarm
}
if strings.HasSuffix(target, "_386") {
goarm := cmp.Or(os.Getenv("GGO386"), os.Getenv("GO386"), "sse2")
target = target + "_" + goarm
}
if strings.HasSuffix(target, "_ppc64") {
goarm := cmp.Or(os.Getenv("GGOPPC64"), os.Getenv("GOPPC64"), "power8")
target = target + "_" + goarm
}
if strings.HasSuffix(target, "_riscv64") {
goarm := cmp.Or(os.Getenv("GGORISCV64"), os.Getenv("GORISCV64"), "rva20u64")
target = target + "_" + goarm
}
if strings.HasSuffix(target, "_mips") ||
strings.HasSuffix(target, "_mips64") ||
strings.HasSuffix(target, "_mipsle") ||
strings.HasSuffix(target, "_mips64le") {
gomips := cmp.Or(os.Getenv("GGOMIPS"), os.Getenv("GOMIPS"), "hardfloat")
target = target + "_" + gomips
target := goos + "_" + goarch
for suffix, keys := range archExtraEnvs {
if !strings.HasSuffix(target, "_"+suffix) {
continue
}
for _, key := range keys {
if env := os.Getenv(key); env != "" {
target += "_" + env
break
}
}
}
return target
}

View File

@ -32,29 +32,36 @@ func TestRun(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
}, testctx.Partial)
t.Setenv("GOOS", "windows")
t.Setenv("GOARCH", "arm64")
t.Setenv("TARGET", "windows_arm64")
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "windows_arm64_v8.0", ctx.PartialTarget)
require.Equal(t, "windows_arm64", ctx.PartialTarget)
})
t.Run("no target", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
}, testctx.Partial)
require.Error(t, pipe.Run(ctx))
})
t.Run("using GGOOS and GGOARCH", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "windows")
t.Setenv("GGOARCH", "arm64")
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "windows_arm64_v8.0", ctx.PartialTarget)
require.Equal(t, "windows_arm64", ctx.PartialTarget)
})
t.Run("custom GGOARM", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "arm")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_arm_6", ctx.PartialTarget)
require.Equal(t, "linux_arm", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGOARM", "7")
@ -64,13 +71,14 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGOARM64", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "arm64")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_arm64_v8.0", ctx.PartialTarget)
require.Equal(t, "linux_arm64", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGOARM64", "v9.0")
@ -80,13 +88,14 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGOAMD64", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "amd64")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_amd64_v1", ctx.PartialTarget)
require.Equal(t, "linux_amd64", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGOAMD64", "v4")
@ -96,7 +105,8 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGOMIPS", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
for _, mips := range []string{"mips", "mips64", "mipsle", "mips64le"} {
@ -104,7 +114,7 @@ func TestRun(t *testing.T) {
t.Setenv("GGOARCH", mips)
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_"+mips+"_hardfloat", ctx.PartialTarget)
require.Equal(t, "linux_"+mips, ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGOMIPS", "softfloat")
@ -116,13 +126,14 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGO386", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "386")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_386_sse2", ctx.PartialTarget)
require.Equal(t, "linux_386", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGO386", "softfloat")
@ -132,13 +143,14 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGOPPC64", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "ppc64")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_ppc64_power8", ctx.PartialTarget)
require.Equal(t, "linux_ppc64", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGOPPC64", "power9")
@ -148,13 +160,14 @@ func TestRun(t *testing.T) {
})
t.Run("custom GGORISCV64", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
t.Setenv("GGOOS", "linux")
t.Setenv("GGOARCH", "riscv64")
t.Run("default", func(t *testing.T) {
require.NoError(t, pipe.Run(ctx))
require.Equal(t, "linux_riscv64_rva20u64", ctx.PartialTarget)
require.Equal(t, "linux_riscv64", ctx.PartialTarget)
})
t.Run("default", func(t *testing.T) {
t.Setenv("GGORISCV64", "rva22u64")
@ -164,17 +177,11 @@ func TestRun(t *testing.T) {
})
t.Run("using runtime", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Dist: "dist",
Dist: "dist",
Builds: []config.Build{{Builder: "go"}},
}, testctx.Partial)
require.NoError(t, pipe.Run(ctx))
target := fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH)
// commonly tests will run on either arm64 or amd64.
switch runtime.GOARCH {
case "amd64":
target += "_v1"
case "arm64":
target += "_v8.0"
}
require.Equal(t, target, ctx.PartialTarget)
})
}

View File

@ -82,3 +82,10 @@ type PreparedBuilder interface {
type ConcurrentBuilder interface {
AllowConcurrentBuilds() bool
}
// TargetFixer allows the builder to provide a way to "default" an incomplete
// target, e.g., on Go, 'darwin_arm64' would need to be defaulted to
// 'darwin_arm64_v8.0'.
type TargetFixer interface {
FixTarget(target string) string
}