Repository: goreleaser/goreleaser
Pull request #2277 (2021-06-02 14:26:59)

fix(publishers): inherit some system variables
closes https://github.com/goreleaser/goreleaser/issues/2201

vercel[bot]: This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).  
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: [https://vercel.com/goreleaser/goreleaser/3MsCXaf7Yntg2Pgk5jdrNY82WWps](https://vercel.com/goreleaser/goreleaser/3MsCXaf7Yntg2Pgk5jdrNY82WWps)  
✅ Preview: [https://goreleaser-git-publisher-goreleaser.vercel.app](https://goreleaser-git-publisher-goreleaser.vercel.app)


codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#2277](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (2973939) into [master](https://codecov.io/gh/goreleaser/goreleaser/commit/752d8653ffc98efec25145e1b4b802b4feed4bf1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (752d865) will **decrease** coverage by `0.06%`.
> The diff coverage is `55.55%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/2277/graphs/tree.svg?width=650&height=150&src=pr&token=3bJvv6b7hN&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)

```diff
@@            Coverage Diff             @@
##           master    #2277      +/-   ##
==========================================
- Coverage   82.67%   82.60%   -0.07%     
==========================================
  Files          79       79              
  Lines        4277     4284       +7     
==========================================
+ Hits         3536     3539       +3     
- Misses        601      605       +4     
  Partials      140      140              
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [internal/exec/exec\_mock.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2277/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvZXhlYy9leGVjX21vY2suZ28=) | `9.09% <0.00%> (-0.91%)` | :arrow_down: |
| [internal/exec/exec.go](https://codecov.io/gh/goreleaser/goreleaser/pull/2277/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvZXhlYy9leGVjLmdv) | `85.71% <100.00%> (+0.52%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [752d865...2973939](https://codecov.io/gh/goreleaser/goreleaser/pull/2277?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).


Patch:
diff --git a/internal/exec/exec.go b/internal/exec/exec.go
index f22ba30d..0db3dd9d 100644
--- a/internal/exec/exec.go
+++ b/internal/exec/exec.go
@@ -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)
diff --git a/internal/exec/exec_mock.go b/internal/exec/exec_mock.go
index b07ffdea..c1eb89ee 100644
--- a/internal/exec/exec_mock.go
+++ b/internal/exec/exec_mock.go
@@ -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)
diff --git a/www/docs/customization/hooks.md b/www/docs/customization/hooks.md
index 79ca6f14..b72c0b3a 100644
--- a/www/docs/customization/hooks.md
+++ b/www/docs/customization/hooks.md
@@ -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
diff --git a/www/docs/customization/publishers.md b/www/docs/customization/publishers.md
index a02d7f5e..bd69813e 100644
--- a/www/docs/customization/publishers.md
+++ b/www/docs/customization/publishers.md
@@ -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


Test patch:
diff --git a/internal/exec/exec_test.go b/internal/exec/exec_test.go
index f664bad4..c8773913 100644
--- a/internal/exec/exec_test.go
+++ b/internal/exec/exec_test.go
@@ -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,
 								},
 							},