1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-04-11 11:42:15 +02:00

fix(publishers): inherit some system variables (#2277)

This commit is contained in:
Carlos Alexandro Becker 2021-06-02 15:05:54 -03:00 committed by GitHub
parent 752d8653ff
commit aa518027b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 25 deletions

View File

@ -1,7 +1,9 @@
// Package exec can execute commands on the OS.
package exec
import (
"fmt"
"os"
"os/exec"
"github.com/apex/log"
@ -15,6 +17,10 @@ import (
"github.com/goreleaser/goreleaser/pkg/context"
)
// Environment variables to pass through to exec
var passthroughEnvVars = []string{"HOME", "USER", "USERPROFILE", "TMPDIR", "TMP", "TEMP", "PATH"}
// Execute the given publisher
func Execute(ctx *context.Context, publishers []config.Publisher) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
@ -59,7 +65,14 @@ func executeCommand(c *command) error {
// nolint: gosec
cmd := exec.CommandContext(c.Ctx, c.Args[0], c.Args[1:]...)
cmd.Env = c.Env
cmd.Env = []string{}
for _, key := range passthroughEnvVars {
if value := os.Getenv(key); value != "" {
cmd.Env = append(cmd.Env, key+"="+value)
}
}
cmd.Env = append(cmd.Env, c.Env...)
if c.Dir != "" {
cmd.Dir = c.Dir
}
@ -68,7 +81,7 @@ func executeCommand(c *command) error {
cmd.Stderr = logext.NewErrWriter(entry)
cmd.Stdout = logext.NewWriter(entry)
log.WithField("cmd", cmd.Args).Info("publishing")
entry.Info("publishing")
if err := cmd.Run(); err != nil {
return fmt.Errorf("publishing: %s failed: %w",
c.Args[0], err)

View File

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"reflect"
"sort"
"strings"
)
@ -81,6 +82,11 @@ func ExecuteMockData(jsonData string) int {
item.ExpectedEnv = []string{}
}
sort.Strings(givenEnv)
sort.Strings(item.ExpectedEnv)
sort.Strings(givenArgs)
sort.Strings(item.ExpectedArgs)
if reflect.DeepEqual(item.ExpectedArgs, givenArgs) &&
reflect.DeepEqual(item.ExpectedEnv, givenEnv) {
fmt.Fprint(os.Stdout, item.Stdout)

View File

@ -57,6 +57,22 @@ func TestExecute(t *testing.T) {
})
}
osEnv := func(ignores ...string) []string {
var result []string
outer:
for _, key := range passthroughEnvVars {
for _, ignore := range ignores {
if key == ignore {
continue outer
}
}
if value := os.Getenv(key); value != "" {
result = append(result, key+"="+value)
}
}
return result
}
testCases := []struct {
name string
publishers []config.Publisher
@ -72,7 +88,7 @@ func TestExecute(t *testing.T) {
Env: []string{
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
},
}),
},
@ -89,9 +105,9 @@ func TestExecute(t *testing.T) {
Env: []string{
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0},
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
},
}),
},
@ -109,10 +125,10 @@ func TestExecute(t *testing.T) {
Env: []string{
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0},
{ExpectedArgs: []string{"a.sum"}, ExitCode: 0},
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.sum"}, ExitCode: 0, ExpectedEnv: osEnv()},
},
}),
},
@ -130,10 +146,10 @@ func TestExecute(t *testing.T) {
Env: []string{
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0},
{ExpectedArgs: []string{"a.sig"}, ExitCode: 0},
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()},
{ExpectedArgs: []string{"a.sig"}, ExitCode: 0, ExpectedEnv: osEnv()},
},
}),
},
@ -153,7 +169,7 @@ func TestExecute(t *testing.T) {
Env: []string{
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0},
{ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()},
},
}),
},
@ -175,11 +191,35 @@ func TestExecute(t *testing.T) {
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{
ExpectedEnv: []string{
"PROJECT=blah",
"ARTIFACT=a.deb",
"SECRET=x",
},
ExpectedEnv: append(
[]string{"PROJECT=blah", "ARTIFACT=a.deb", "SECRET=x"},
osEnv()...,
),
ExitCode: 0,
},
},
}),
},
},
},
nil,
},
{
"override path",
[]config.Publisher{
{
Name: "test",
IDs: []string{"debpkg"},
Cmd: MockCmd,
Env: []string{
"PATH=/something-else",
MarshalMockEnv(&MockData{
AnyOf: []MockCall{
{
ExpectedEnv: append(
[]string{"PATH=/something-else"},
osEnv("PATH")...,
),
ExitCode: 0,
},
},

View File

@ -29,7 +29,7 @@ You can also go crazy with `sh -c "my commands"`, but it gets ugly real fast.
## Pro Features
With [GoReleaser Pro](/pro), things are a bit more flexible: you can specify the dir, enviroment variables and also global after hooks.
With [GoReleaser Pro](/pro), things are a bit more flexible: you can specify the dir, environment variables and also global after hooks.
```yaml
# .goreleaser.yml

View File

@ -26,10 +26,22 @@ publishers:
### Environment
Commands which are executed as custom publishers do not inherit any environment variables
(unlike existing hooks) as a precaution to avoid leaking sensitive data accidentally
and provide better control of the environment for each individual process
where variable names may overlap unintentionally.
Commands which are executed as custom publishers only inherit a subset of
the system environment variables (unlike existing hooks) as a precaution to
avoid leaking sensitive data accidentally and provide better control of the
environment for each individual process where variable names may overlap
unintentionally.
Environment variables that are kept:
- `HOME`
- `USER`
- `USERPROFILE`
- `TMPDIR`
- `TMP`
- `TEMP`
- `PATH`
You can however use `.Env.NAME` templating syntax which enables
more explicit inheritance.
@ -40,6 +52,9 @@ more explicit inheritance.
- SECRET_TOKEN={{ .Env.SECRET_TOKEN }}
```
The publisher explicit environment variables take precedence over the
inherited set of variables as well.
### Variables
Command (`cmd`), workdir (`dir`) and environment variables (`env`) support templating