diff --git a/internal/client/gitlab.go b/internal/client/gitlab.go index b664da1b82d..e10adb1e18a 100644 --- a/internal/client/gitlab.go +++ b/internal/client/gitlab.go @@ -47,7 +47,7 @@ func NewGitLab(ctx *context.Context, token string) (Client, error) { var client *gitlab.Client var err error - if ctx.Config.GitLabURLs.UseJobToken { + if checkUseJobToken(*ctx, token) { client, err = gitlab.NewJobClient(token, options...) } else { client, err = gitlab.NewClient(token, options...) @@ -495,3 +495,24 @@ func (c *gitlabClient) getMilestoneByTitle(repo Repo, title string) (*gitlab.Mil return nil, nil } + +// checkUseJobToken examines the context and given token, and determines if We should use NewJobClient vs NewClient +func checkUseJobToken(ctx context.Context, token string) bool { + // The CI_JOB_TOKEN env var is set automatically in all GitLab runners. + // If this comes back as empty, we aren't in a functional GitLab runner + ciToken := os.Getenv("CI_JOB_TOKEN") + if ciToken == "" { + return false + } + + // We only want to use the JobToken client if we have specified + // UseJobToken. Older versions of GitLab don't work with this, so we + // want to be specific + if ctx.Config.GitLabURLs.UseJobToken { + // We may be creating a new client with a non-CI_JOB_TOKEN, for + // things like Homebrew publishing. We can't use the + // CI_JOB_TOKEN there + return token == ciToken + } + return false +} diff --git a/internal/client/gitlab_test.go b/internal/client/gitlab_test.go index df06f9942c6..87fc12f1dc6 100644 --- a/internal/client/gitlab_test.go +++ b/internal/client/gitlab_test.go @@ -546,3 +546,58 @@ func TestCloseMileston(t *testing.T) { err = client.CloseMilestone(ctx, repo, "never-will-exist") require.Error(t, err) } + +func TestCheckUseJobToken(t *testing.T) { + tests := []struct { + ctx context.Context + token string + ciToken string + want bool + desc string + }{ + { + ctx: context.Context{ + Config: config.Project{ + GitLabURLs: config.GitLabURLs{ + UseJobToken: true, + }, + }, + }, + token: "real-ci-token", + ciToken: "real-ci-token", + desc: "token and CI_JOB_TOKEN match so should return true", + want: true, + }, + { + ctx: context.Context{ + Config: config.Project{ + GitLabURLs: config.GitLabURLs{ + UseJobToken: true, + }, + }, + }, + token: "some-random-token", + ciToken: "real-ci-token", + desc: "token and CI_JOB_TOKEN do NOT match so should return false", + want: false, + }, + { + ctx: context.Context{ + Config: config.Project{ + GitLabURLs: config.GitLabURLs{ + UseJobToken: false, + }, + }, + }, + token: "real-ci-token", + ciToken: "real-ci-token", + desc: "token and CI_JOB_TOKEN match, however UseJobToken is set to false, so return false", + want: false, + }, + } + for _, tt := range tests { + t.Setenv("CI_JOB_TOKEN", tt.ciToken) + got := checkUseJobToken(tt.ctx, tt.token) + require.Equal(t, tt.want, got, tt.desc) + } +}