Skip to content

Commit

Permalink
Enable setting environment variables in .ko.yaml
Browse files Browse the repository at this point in the history
Matches the GoReleaser format.

Related: #340
  • Loading branch information
halvards committed Aug 22, 2021
1 parent 040b7c7 commit e865741
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 17 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ configuration section in your `.ko.yaml`.
builds:
- id: foo
main: ./foobar/foo
env:
- GOPRIVATE=git.internal.example.com,source.developers.google.com
flags:
- -tags
- netgo
Expand All @@ -144,6 +146,8 @@ builds:
- -X main.version={{.Env.VERSION}}
- id: bar
main: ./foobar/bar/main.go
env:
- CGO_ENABLED=1
ldflags:
- -s
- -w
Expand All @@ -156,7 +160,7 @@ with the intended import path.

_Please note:_ Even though the configuration section is similar to the
[GoReleaser `builds` section](https://goreleaser.com/customization/build/),
only the `flags` and `ldflags` fields are currently supported. Also, the
only the `env`, `flags` and `ldflags` fields are currently supported. Also, the
templating support is currently limited to environment variables only.

## Naming Images
Expand Down
4 changes: 3 additions & 1 deletion pkg/build/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ type Config struct {
Ldflags StringArray `yaml:",omitempty"`
Flags FlagArray `yaml:",omitempty"`

// Env allows setting environment variables for `go build`
Env []string `yaml:",omitempty"`

// Other GoReleaser fields that are not supported or do not make sense
// in the context of ko, for reference or for future use:
// Goos []string `yaml:",omitempty"`
Expand All @@ -87,7 +90,6 @@ type Config struct {
// Gomips []string `yaml:",omitempty"`
// Targets []string `yaml:",omitempty"`
// Binary string `yaml:",omitempty"`
// Env []string `yaml:",omitempty"`
// Lang string `yaml:",omitempty"`
// Asmflags StringArray `yaml:",omitempty"`
// Gcflags StringArray `yaml:",omitempty"`
Expand Down
42 changes: 27 additions & 15 deletions pkg/build/gobuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,29 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con
cmd := exec.CommandContext(ctx, "go", args...)
cmd.Dir = dir

// Last one wins
env, err := buildEnv(platform, config.Env)
if err != nil {
return "", fmt.Errorf("could not create env for %s: %v", ip, err)
}
cmd.Env = env

var output bytes.Buffer
cmd.Stderr = &output
cmd.Stdout = &output

log.Printf("Building %s for %s", ip, platformToString(platform))
if err := cmd.Run(); err != nil {
os.RemoveAll(tmpDir)
log.Printf("Unexpected error running \"go build\": %v\n%v", err, output.String())
return "", err
}
return file, nil
}

// buildEnv creates the environment variables used by the `go build` command.
// From `os/exec.Cmd`: If Env contains duplicate environment keys, only the last
// value in the slice for each duplicate key is used.
func buildEnv(platform v1.Platform, configEnv []string) ([]string, error) {
defaultEnv := []string{
"CGO_ENABLED=0",
"GOOS=" + platform.OS,
Expand All @@ -388,26 +410,16 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con
if strings.HasPrefix(platform.Architecture, "arm") && platform.Variant != "" {
goarm, err := getGoarm(platform)
if err != nil {
return "", fmt.Errorf("goarm failure for %s: %v", ip, err)
return nil, fmt.Errorf("goarm failure: %v", err)
}
if goarm != "" {
defaultEnv = append(defaultEnv, "GOARM="+goarm)
}
}

cmd.Env = append(defaultEnv, os.Environ()...)

var output bytes.Buffer
cmd.Stderr = &output
cmd.Stdout = &output

log.Printf("Building %s for %s", ip, platformToString(platform))
if err := cmd.Run(); err != nil {
os.RemoveAll(tmpDir)
log.Printf("Unexpected error running \"go build\": %v\n%v", err, output.String())
return "", err
}
return file, nil
env := append(defaultEnv, os.Environ()...)
env = append(env, configEnv...)
return env, nil
}

func appFilename(importpath string) string {
Expand Down
77 changes: 77 additions & 0 deletions pkg/build/gobuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,83 @@ func TestGoBuildIsSupportedRefWithModules(t *testing.T) {
}
}

func TestBuildEnv(t *testing.T) {
tests := []struct {
description string
platform v1.Platform
configEnv []string
expectedEnvs map[string]string
}{
{
description: "defaults",
platform: v1.Platform{
OS: "linux",
Architecture: "amd64",
},
expectedEnvs: map[string]string{
"GOOS": "linux",
"GOARCH": "amd64",
"CGO_ENABLED": "0",
},
},
{
description: "override a default value",
configEnv: []string{"CGO_ENABLED=1"},
expectedEnvs: map[string]string{
"CGO_ENABLED": "1",
},
},
{
description: "override an envvar and add an envvar",
configEnv: []string{"CGO_ENABLED=1", "GOPRIVATE=git.internal.example.com,source.developers.google.com"},
expectedEnvs: map[string]string{
"CGO_ENABLED": "1",
"GOPRIVATE": "git.internal.example.com,source.developers.google.com",
},
},
{
description: "arm variant",
platform: v1.Platform{
Architecture: "arm",
Variant: "v7",
},
expectedEnvs: map[string]string{
"GOARCH": "arm",
"GOARM": "7",
},
},
{
description: "arm64 variant",
platform: v1.Platform{
Architecture: "arm64",
Variant: "v8",
},
expectedEnvs: map[string]string{
"GOARCH": "arm64",
"GOARM": "7",
},
},
}
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
env, err := buildEnv(test.platform, test.configEnv)
if err != nil {
t.Fatalf("unexpected error running buildEnv(): %v", err)
}
envs := map[string]string{}
for _, e := range env {
split := strings.SplitN(e, "=", 2)
envs[split[0]] = split[1]
}
for key, val := range test.expectedEnvs {
if envs[key] != val {
t.Errorf("buildEnv(): expected %s=%s, got %s=%s", key, val, key, envs[key])
}
}
})
}
}

// A helper method we use to substitute for the default "build" method.
func writeTempFile(_ context.Context, s string, _ string, _ v1.Platform, _ Config) (string, error) {
tmpDir, err := ioutil.TempDir("", "ko")
Expand Down

0 comments on commit e865741

Please sign in to comment.