mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-17 20:47:50 +02:00
feat(build): allow to template env (#3592)
GoReleaser evolved a lot since the last time I tried to implement this >1 year ago. Now its 100% possible, and way simpler to do it! closes #3580 refs #2583 Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
e54656438b
commit
1b8395d6b6
@ -165,7 +165,23 @@ func (*Builder) Build(ctx *context.Context, build config.Build, options api.Opti
|
||||
return err
|
||||
}
|
||||
|
||||
env := append(ctx.Env.Strings(), details.Env...)
|
||||
env := []string{}
|
||||
// used for unit testing only
|
||||
testEnvs := []string{}
|
||||
env = append(env, ctx.Env.Strings()...)
|
||||
for _, e := range details.Env {
|
||||
ee, err := tmpl.New(ctx).WithEnvS(env).WithArtifact(a, nil).Apply(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("env %q evaluated to %q", e, ee)
|
||||
if ee != "" {
|
||||
env = append(env, ee)
|
||||
if strings.HasPrefix(e, "TEST_") {
|
||||
testEnvs = append(testEnvs, ee)
|
||||
}
|
||||
}
|
||||
}
|
||||
env = append(
|
||||
env,
|
||||
"GOOS="+options.Goos,
|
||||
@ -176,6 +192,10 @@ func (*Builder) Build(ctx *context.Context, build config.Build, options api.Opti
|
||||
"GOAMD64="+options.Goamd64,
|
||||
)
|
||||
|
||||
if len(testEnvs) > 0 {
|
||||
a.Extra["testEnvs"] = testEnvs
|
||||
}
|
||||
|
||||
cmd, err := buildGoBuildLine(ctx, build, details, options, a, env)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -363,7 +363,16 @@ func TestBuild(t *testing.T) {
|
||||
GoBinary: "go",
|
||||
Command: "build",
|
||||
BuildDetails: config.BuildDetails{
|
||||
Env: []string{"GO111MODULE=off"},
|
||||
Env: []string{
|
||||
"GO111MODULE=off",
|
||||
`TEST_T={{- if eq .Os "windows" -}}
|
||||
w
|
||||
{{- else if eq .Os "darwin" -}}
|
||||
d
|
||||
{{- else if eq .Os "linux" -}}
|
||||
l
|
||||
{{- end -}}`,
|
||||
},
|
||||
Asmflags: []string{".=", "all="},
|
||||
Gcflags: []string{"all="},
|
||||
Flags: []string{"{{.Env.GO_FLAGS}}"},
|
||||
@ -426,6 +435,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: "",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=l"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -439,6 +449,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: "",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=l"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -452,6 +463,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: "",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=l"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -464,6 +476,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: "",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=d"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -477,6 +490,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: "",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=l"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -489,6 +503,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: ".exe",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T=w"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -501,6 +516,7 @@ func TestBuild(t *testing.T) {
|
||||
artifact.ExtraExt: ".wasm",
|
||||
artifact.ExtraBinary: "foo-v5.6.7",
|
||||
artifact.ExtraID: "foo",
|
||||
"testEnvs": []string{"TEST_T="},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -524,6 +540,37 @@ func TestBuild(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildInvalidEnv(t *testing.T) {
|
||||
folder := testlib.Mktmp(t)
|
||||
writeGoodMain(t, folder)
|
||||
config := config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
ID: "foo",
|
||||
Dir: ".",
|
||||
Binary: "foo",
|
||||
Targets: []string{
|
||||
runtimeTarget,
|
||||
},
|
||||
GoBinary: "go",
|
||||
BuildDetails: config.BuildDetails{
|
||||
Env: []string{"GO111MODULE={{ .Nope }}"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := context.New(config)
|
||||
ctx.Git.CurrentTag = "5.6.7"
|
||||
build := ctx.Config.Builds[0]
|
||||
err := Default.Build(ctx, build, api.Options{
|
||||
Target: runtimeTarget,
|
||||
Name: build.Binary,
|
||||
Path: filepath.Join(folder, "dist", runtimeTarget, build.Binary),
|
||||
Ext: "",
|
||||
})
|
||||
testlib.RequireTemplateError(t, err)
|
||||
}
|
||||
|
||||
func TestBuildCodeInSubdir(t *testing.T) {
|
||||
folder := testlib.Mktmp(t)
|
||||
subdir := filepath.Join(folder, "bar")
|
||||
|
@ -115,9 +115,7 @@ func runHook(ctx *context.Context, opts builders.Options, buildEnv []string, hoo
|
||||
var env []string
|
||||
|
||||
env = append(env, ctx.Env.Strings()...)
|
||||
env = append(env, buildEnv...)
|
||||
|
||||
for _, rawEnv := range hook.Env {
|
||||
for _, rawEnv := range append(buildEnv, hook.Env...) {
|
||||
e, err := tmpl.New(ctx).WithBuildOptions(opts).Apply(rawEnv)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -121,6 +121,8 @@ func TestRunFullPipe(t *testing.T) {
|
||||
folder := testlib.Mktmp(t)
|
||||
pre := filepath.Join(folder, "pre")
|
||||
post := filepath.Join(folder, "post")
|
||||
preOS := filepath.Join(folder, "pre_linux")
|
||||
postOS := filepath.Join(folder, "post_linux")
|
||||
config := config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
@ -130,13 +132,16 @@ func TestRunFullPipe(t *testing.T) {
|
||||
BuildDetails: config.BuildDetails{
|
||||
Flags: []string{"-v"},
|
||||
Ldflags: []string{"-X main.test=testing"},
|
||||
Env: []string{"THE_OS={{ .Os }}"},
|
||||
},
|
||||
Hooks: config.BuildHookConfig{
|
||||
Pre: []config.Hook{
|
||||
{Cmd: "touch " + pre},
|
||||
{Cmd: "touch pre_{{ .Env.THE_OS}}"},
|
||||
},
|
||||
Post: []config.Hook{
|
||||
{Cmd: "touch " + post},
|
||||
{Cmd: "touch post_{{ .Env.THE_OS}}"},
|
||||
},
|
||||
},
|
||||
Targets: []string{"linux_amd64"},
|
||||
@ -153,6 +158,8 @@ func TestRunFullPipe(t *testing.T) {
|
||||
}})
|
||||
require.FileExists(t, post)
|
||||
require.FileExists(t, pre)
|
||||
require.FileExists(t, postOS)
|
||||
require.FileExists(t, preOS)
|
||||
require.FileExists(t, filepath.Join(folder, "build1_linux_amd64", "testing"))
|
||||
}
|
||||
|
||||
|
@ -71,11 +71,22 @@ builds:
|
||||
|
||||
# Custom environment variables to be set during the builds.
|
||||
#
|
||||
# This field is templateable. Since v1.14.
|
||||
#
|
||||
# Invalid environment variables will be ignored.
|
||||
#
|
||||
# Default: `os.Environ()` merged with what you set the root `env` section.
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
# complex, templated envs (v1.14+):
|
||||
- >-
|
||||
{{- if eq .Os "darwin" }}
|
||||
{{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
|
||||
{{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .Os "windows" }}
|
||||
{{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
|
||||
{{- end }}
|
||||
|
||||
# GOOS list to build for.
|
||||
# For more info refer to: https://golang.org/doc/install/source#environment
|
||||
@ -558,3 +569,83 @@ builds:
|
||||
# Configure the buildmode flag to output a shared library
|
||||
buildmode: "c-shared" # or "c-archive" for a static library
|
||||
```
|
||||
|
||||
## Complex templated environment variables
|
||||
|
||||
> Since v1.14.
|
||||
|
||||
Builds environment variables are templateable.
|
||||
|
||||
You can leverage that to have a single build configuration with different
|
||||
environment variables for each platform, for example.
|
||||
|
||||
A common example of this is the variables `CC` and `CCX`.
|
||||
|
||||
Here are two different examples:
|
||||
|
||||
### Using multiple envs
|
||||
|
||||
This example creates once `CC_` and `CCX_` variable for each platform, and then
|
||||
set `CC` and `CCX` to the right one:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yml
|
||||
builds:
|
||||
- id: mybin
|
||||
binary: mybin
|
||||
main: .
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- CC_darwin_amd64=o64-clang
|
||||
- CCX_darwin_amd64=o64-clang+
|
||||
- CC_darwin_arm64=aarch64-apple-darwin20.2-clang
|
||||
- CCX_darwin_arm64=aarch64-apple-darwin20.2-clang++
|
||||
- CC_windows_amd64=x86_64-w64-mingw32-gc
|
||||
- CCX_windows_amd64=x86_64-w64-mingw32-g++
|
||||
- 'CC={{ index .Env (print "CC_" .Os "_" .Arch) }}'
|
||||
- 'CCX={{ index .Env (print "CCX_" .Os "_" .Arch) }}'
|
||||
```
|
||||
|
||||
### Using `if` statements
|
||||
|
||||
This example uses `if` statements to set `CC` and `CCX`:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yml
|
||||
builds:
|
||||
- id: mybin
|
||||
binary: mybin
|
||||
main: .
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- >-
|
||||
{{- if eq .Os "darwin" }}
|
||||
{{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
|
||||
{{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .Os "windows" }}
|
||||
{{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
|
||||
{{- end }}
|
||||
- >-
|
||||
{{- if eq .Os "darwin" }}
|
||||
{{- if eq .Arch "amd64"}}CXX=o64-clang+{{- end }}
|
||||
{{- if eq .Arch "arm64"}}CXX=aarch64-apple-darwin20.2-clang++{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .Os "windows" }}
|
||||
{{- if eq .Arch "amd64" }}CXX=x86_64-w64-mingw32-g++{{- end }}
|
||||
{{- end }}
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user