diff --git a/internal/pipe/env/env.go b/internal/pipe/env/env.go index c34a80c9a..2664bd0fd 100644 --- a/internal/pipe/env/env.go +++ b/internal/pipe/env/env.go @@ -69,18 +69,30 @@ func (Pipe) Run(ctx *context.Context) error { gitlabToken, gitlabTokenErr := loadEnv("GITLAB_TOKEN", ctx.Config.EnvFiles.GitLabToken) giteaToken, giteaTokenErr := loadEnv("GITEA_TOKEN", ctx.Config.EnvFiles.GiteaToken) - var tokens []string - if githubToken != "" { - tokens = append(tokens, "GITHUB_TOKEN") - } - if gitlabToken != "" { - tokens = append(tokens, "GITLAB_TOKEN") - } - if giteaToken != "" { - tokens = append(tokens, "GITEA_TOKEN") - } - if len(tokens) > 1 { - return ErrMultipleTokens{tokens} + switch os.Getenv("GORELEASER_FORCE_TOKEN") { + case "github": + gitlabToken = "" + giteaToken = "" + case "gitlab": + githubToken = "" + giteaToken = "" + case "gitea": + githubToken = "" + gitlabToken = "" + default: + var tokens []string + if githubToken != "" { + tokens = append(tokens, "GITHUB_TOKEN") + } + if gitlabToken != "" { + tokens = append(tokens, "GITLAB_TOKEN") + } + if giteaToken != "" { + tokens = append(tokens, "GITEA_TOKEN") + } + if len(tokens) > 1 { + return ErrMultipleTokens{tokens} + } } noTokens := githubToken == "" && gitlabToken == "" && giteaToken == "" diff --git a/internal/pipe/env/env_test.go b/internal/pipe/env/env_test.go index a6731dbf7..83c04c128 100644 --- a/internal/pipe/env/env_test.go +++ b/internal/pipe/env/env_test.go @@ -12,6 +12,25 @@ import ( "github.com/stretchr/testify/require" ) +func TestMain(m *testing.M) { + restores := map[string]string{} + for _, key := range []string{"GITHUB_TOKEN", "GITEA_TOKEN", "GITLAB_TOKEN"} { + prevValue, ok := os.LookupEnv(key) + if ok { + _ = os.Unsetenv(key) + restores[key] = prevValue + } + } + + code := m.Run() + + for k, v := range restores { + _ = os.Setenv(k, v) + } + + os.Exit(code) +} + func TestDescription(t *testing.T) { require.NotEmpty(t, Pipe{}.String()) } @@ -44,8 +63,8 @@ func TestSetDefaultTokenFiles(t *testing.T) { }, }) ctx.Env["FOOBAR"] = "old foobar" - os.Setenv("BAR", "lebar") - os.Setenv("GITHUB_TOKEN", "fake") + t.Setenv("BAR", "lebar") + t.Setenv("GITHUB_TOKEN", "fake") require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "FOO_lebar", ctx.Env["FOO"]) require.Equal(t, "foobar", ctx.Env["FOOBAR"]) @@ -62,83 +81,99 @@ func TestSetDefaultTokenFiles(t *testing.T) { }) t.Run("no token", func(t *testing.T) { + ctx := testctx.New() + require.EqualError(t, Pipe{}.Run(ctx), ErrMissingToken.Error()) + }) +} + +func TestForceToken(t *testing.T) { + t.Run("github", func(t *testing.T) { + t.Setenv("GITHUB_TOKEN", "fake") + t.Setenv("GORELEASER_FORCE_TOKEN", "github") ctx := testctx.New() require.NoError(t, Pipe{}.Run(ctx)) - require.Equal(t, ctx.TokenType, context.TokenTypeGitHub) + require.Equal(t, context.TokenTypeGitHub, ctx.TokenType) + }) + t.Run("gitlab", func(t *testing.T) { + t.Setenv("GITLAB_TOKEN", "fake") + t.Setenv("GORELEASER_FORCE_TOKEN", "gitlab") + ctx := testctx.New() + require.NoError(t, Pipe{}.Run(ctx)) + require.Equal(t, context.TokenTypeGitLab, ctx.TokenType) + }) + t.Run("gitea", func(t *testing.T) { + t.Setenv("GITEA_TOKEN", "fake") + t.Setenv("GORELEASER_FORCE_TOKEN", "gitea") + ctx := testctx.New() + require.NoError(t, Pipe{}.Run(ctx)) + require.Equal(t, context.TokenTypeGitea, ctx.TokenType) }) } func TestValidGithubEnv(t *testing.T) { - require.NoError(t, os.Setenv("GITHUB_TOKEN", "asdf")) + t.Setenv("GITHUB_TOKEN", "asdf") ctx := testctx.New() require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "asdf", ctx.Token) require.Equal(t, context.TokenTypeGitHub, ctx.TokenType) - // so the tests do not depend on each other - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) } func TestValidGitlabEnv(t *testing.T) { - require.NoError(t, os.Setenv("GITLAB_TOKEN", "qwertz")) + t.Setenv("GITLAB_TOKEN", "qwertz") ctx := testctx.New() require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "qwertz", ctx.Token) require.Equal(t, context.TokenTypeGitLab, ctx.TokenType) - // so the tests do not depend on each other - require.NoError(t, os.Unsetenv("GITLAB_TOKEN")) } func TestValidGiteaEnv(t *testing.T) { - require.NoError(t, os.Setenv("GITEA_TOKEN", "token")) + t.Setenv("GITEA_TOKEN", "token") ctx := testctx.New() require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "token", ctx.Token) require.Equal(t, context.TokenTypeGitea, ctx.TokenType) - // so the tests do not depend on each other - require.NoError(t, os.Unsetenv("GITEA_TOKEN")) } func TestInvalidEnv(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) - require.NoError(t, os.Unsetenv("GITLAB_TOKEN")) ctx := testctx.New() require.Error(t, Pipe{}.Run(ctx)) require.EqualError(t, Pipe{}.Run(ctx), ErrMissingToken.Error()) } func TestMultipleEnvTokens(t *testing.T) { - require.NoError(t, os.Setenv("GITHUB_TOKEN", "asdf")) - require.NoError(t, os.Setenv("GITLAB_TOKEN", "qwertz")) - require.NoError(t, os.Setenv("GITEA_TOKEN", "token")) + t.Setenv("GITHUB_TOKEN", "asdf") + t.Setenv("GITLAB_TOKEN", "qwertz") + t.Setenv("GITEA_TOKEN", "token") + ctx := testctx.New() + require.Error(t, Pipe{}.Run(ctx)) + require.EqualError(t, Pipe{}.Run(ctx), "multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITLAB_TOKEN, GITEA_TOKEN\n\nLearn more at https://goreleaser.com/errors/multiple-tokens\n") +} + +func TestMultipleEnvTokensForce(t *testing.T) { + t.Setenv("GITHUB_TOKEN", "asdf") + t.Setenv("GITLAB_TOKEN", "qwertz") + t.Setenv("GITEA_TOKEN", "token") ctx := testctx.New() require.Error(t, Pipe{}.Run(ctx)) require.EqualError(t, Pipe{}.Run(ctx), "multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITLAB_TOKEN, GITEA_TOKEN\n\nLearn more at https://goreleaser.com/errors/multiple-tokens\n") - // so the tests do not depend on each other - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) - require.NoError(t, os.Unsetenv("GITLAB_TOKEN")) - require.NoError(t, os.Unsetenv("GITEA_TOKEN")) } func TestEmptyGithubFileEnv(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) ctx := testctx.New() require.Error(t, Pipe{}.Run(ctx)) } func TestEmptyGitlabFileEnv(t *testing.T) { - require.NoError(t, os.Unsetenv("GITLAB_TOKEN")) ctx := testctx.New() require.Error(t, Pipe{}.Run(ctx)) } func TestEmptyGiteaFileEnv(t *testing.T) { - require.NoError(t, os.Unsetenv("GITEA_TOKEN")) ctx := testctx.New() require.Error(t, Pipe{}.Run(ctx)) } func TestEmptyGithubEnvFile(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) require.NoError(t, f.Close()) @@ -152,7 +187,6 @@ func TestEmptyGithubEnvFile(t *testing.T) { } func TestEmptyGitlabEnvFile(t *testing.T) { - require.NoError(t, os.Unsetenv("GITLAB_TOKEN")) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) require.NoError(t, f.Close()) @@ -166,7 +200,6 @@ func TestEmptyGitlabEnvFile(t *testing.T) { } func TestEmptyGiteaEnvFile(t *testing.T) { - require.NoError(t, os.Unsetenv("GITEA_TOKEN")) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) require.NoError(t, f.Close()) @@ -180,14 +213,11 @@ func TestEmptyGiteaEnvFile(t *testing.T) { } func TestInvalidEnvChecksSkipped(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) ctx := testctx.New(testctx.SkipPublish) require.NoError(t, Pipe{}.Run(ctx)) } func TestInvalidEnvReleaseDisabled(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) - t.Run("true", func(t *testing.T) { ctx := testctx.NewWithCfg(config.Project{ Env: []string{}, @@ -228,21 +258,16 @@ func TestInvalidEnvReleaseDisabled(t *testing.T) { }) } -func TestInvalidEnvReleaseDisabledTmpl(t *testing.T) { - require.NoError(t, os.Unsetenv("GITHUB_TOKEN")) -} - func TestLoadEnv(t *testing.T) { + const env = "SUPER_SECRET_ENV_NOPE" + t.Run("env exists", func(t *testing.T) { - env := "SUPER_SECRET_ENV" - require.NoError(t, os.Setenv(env, "1")) + t.Setenv(env, "1") v, err := loadEnv(env, "nope") require.NoError(t, err) require.Equal(t, "1", v) }) t.Run("env file exists", func(t *testing.T) { - env := "SUPER_SECRET_ENV_NOPE" - require.NoError(t, os.Unsetenv(env)) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) fmt.Fprintf(f, "123") @@ -252,8 +277,6 @@ func TestLoadEnv(t *testing.T) { require.Equal(t, "123", v) }) t.Run("env file with an empty line at the end", func(t *testing.T) { - env := "SUPER_SECRET_ENV_NOPE" - require.NoError(t, os.Unsetenv(env)) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) fmt.Fprintf(f, "123\n") @@ -263,8 +286,6 @@ func TestLoadEnv(t *testing.T) { require.Equal(t, "123", v) }) t.Run("env file is not readable", func(t *testing.T) { - env := "SUPER_SECRET_ENV_NOPE" - require.NoError(t, os.Unsetenv(env)) f, err := os.CreateTemp(t.TempDir(), "token") require.NoError(t, err) fmt.Fprintf(f, "123") diff --git a/www/docs/errors/multiple-tokens.md b/www/docs/errors/multiple-tokens.md index 53392e11f..2eb127021 100644 --- a/www/docs/errors/multiple-tokens.md +++ b/www/docs/errors/multiple-tokens.md @@ -26,11 +26,21 @@ to force one of them, you can explicitly disable the others by setting them to a file you know won't exist: ```yaml - # .goreleaser.yaml env_files: gitlab_token: ~/nope gitea_token: ~/nope ``` +## Forcing a specific token + This will prevent using both GitLab and Gitea tokens. + +If GoReleaser is being run with more than one of the `*_TOKEN` environment +variables and you can't unset any of them, you can force GoReleaser to use a +specific one by exporting a `GORELEASER_FORCE_TOKEN` environment variable. + +So, for instance, if you have both `GITHUB_TOKEN` and `GITEA_TOKEN` set and want +GoReleaser to pick `GITEA_TOKEN`, you can set `GORELEASER_FORCE_TOKEN=gitea`. +GoReleaser will then unset `GITHUB_TOKEN` and proceed. +