diff --git a/internal/client/gitea.go b/internal/client/gitea.go index 601c5f8ebc2..fabfdc31a05 100644 --- a/internal/client/gitea.go +++ b/internal/client/gitea.go @@ -21,7 +21,12 @@ type giteaClient struct { client *gitea.Client } -func getInstanceURL(apiURL string) (string, error) { +func getInstanceURL(ctx *context.Context) (string, error) { + apiURL, err := tmpl.New(ctx).Apply(ctx.Config.GiteaURLs.API) + if err != nil { + return "", fmt.Errorf("templating Gitea API URL: %w", err) + } + u, err := url.Parse(apiURL) if err != nil { return "", err @@ -36,7 +41,7 @@ func getInstanceURL(apiURL string) (string, error) { // NewGitea returns a gitea client implementation. func NewGitea(ctx *context.Context, token string) (Client, error) { - instanceURL, err := getInstanceURL(ctx.Config.GiteaURLs.API) + instanceURL, err := getInstanceURL(ctx) if err != nil { return nil, err } @@ -231,9 +236,14 @@ func (c *giteaClient) CreateRelease(ctx *context.Context, body string) (string, } func (c *giteaClient) ReleaseURLTemplate(ctx *context.Context) (string, error) { + downloadURL, err := tmpl.New(ctx).Apply(ctx.Config.GiteaURLs.Download) + if err != nil { + return "", fmt.Errorf("templating Gitea download URL: %w", err) + } + return fmt.Sprintf( "%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}", - ctx.Config.GiteaURLs.Download, + downloadURL, ctx.Config.Release.Gitea.Owner, ctx.Config.Release.Gitea.Name, ), nil diff --git a/internal/client/gitea_test.go b/internal/client/gitea_test.go index 05a47079b12..b1037c779c4 100644 --- a/internal/client/gitea_test.go +++ b/internal/client/gitea_test.go @@ -6,6 +6,7 @@ import ( "os" "strings" "testing" + "text/template" "code.gitea.io/sdk/gitea" "github.com/goreleaser/goreleaser/internal/artifact" @@ -23,30 +24,95 @@ type GetInstanceURLSuite struct { func (s *GetInstanceURLSuite) TestWithScheme() { t := s.T() rootURL := "https://gitea.com" - result, err := getInstanceURL(rootURL + "/api/v1") + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: rootURL + "/api/v1", + }, + }) + + result, err := getInstanceURL(ctx) require.NoError(t, err) require.Equal(t, rootURL, result) } func (s *GetInstanceURLSuite) TestParseError() { t := s.T() - host := "://wrong.gitea.com" - result, err := getInstanceURL(host) + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: "://wrong.gitea.com", + }, + }) + + result, err := getInstanceURL(ctx) require.Error(t, err) require.Empty(t, result) } func (s *GetInstanceURLSuite) TestNoScheme() { t := s.T() - host := "gitea.com" - result, err := getInstanceURL(host) + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: "gitea.com", + }, + }) + + result, err := getInstanceURL(ctx) require.Error(t, err) require.Empty(t, result) } func (s *GetInstanceURLSuite) TestEmpty() { t := s.T() - result, err := getInstanceURL("") + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: "", + }, + }) + + result, err := getInstanceURL(ctx) + require.Error(t, err) + require.Empty(t, result) +} + +func (s *GetInstanceURLSuite) TestTemplate() { + t := s.T() + rootURL := "https://gitea.mycompany.com" + ctx := context.New(config.Project{ + Env: []string{ + fmt.Sprintf("GORELEASER_TEST_GITAEA_URLS_API=%s", rootURL), + }, + GiteaURLs: config.GiteaURLs{ + API: "{{ .Env.GORELEASER_TEST_GITAEA_URLS_API }}", + }, + }) + + result, err := getInstanceURL(ctx) + require.NoError(t, err) + require.Equal(t, rootURL, result) +} + +func (s *GetInstanceURLSuite) TestTemplateMissingValue() { + t := s.T() + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: "{{ .Env.GORELEASER_NOT_EXISTS }}", + }, + }) + + result, err := getInstanceURL(ctx) + require.ErrorAs(t, err, &template.ExecError{}) + require.Empty(t, result) +} + +func (s *GetInstanceURLSuite) TestTemplateInvalid() { + t := s.T() + ctx := context.New(config.Project{ + GiteaURLs: config.GiteaURLs{ + API: "{{.dddddddddd", + }, + }) + + result, err := getInstanceURL(ctx) require.Error(t, err) require.Empty(t, result) } @@ -408,24 +474,62 @@ func TestGiteaUploadSuite(t *testing.T) { } func TestGiteaReleaseURLTemplate(t *testing.T) { - ctx := context.New(config.Project{ - GiteaURLs: config.GiteaURLs{ - API: "https://gitea.com/api/v1", - Download: "https://gitea.com", + tests := []struct { + name string + downloadURL string + wantDownloadURL string + wantErr bool + }{ + { + name: "string_url", + downloadURL: "https://gitea.com", + wantDownloadURL: "https://gitea.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", }, - Release: config.Release{ - Gitea: config.Repo{ - Owner: "owner", - Name: "name", - }, + { + name: "download_url_template", + downloadURL: "{{ .Env.GORELEASER_TEST_GITEA_URLS_DOWNLOAD }}", + wantDownloadURL: "https://gitea.mycompany.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", }, - }) - client, err := NewGitea(ctx, ctx.Token) - require.NoError(t, err) - - urlTpl, err := client.ReleaseURLTemplate(ctx) - require.NoError(t, err) + { + name: "download_url_template_invalid_value", + downloadURL: "{{ .Env.GORELEASER_NOT_EXISTS }}", + wantErr: true, + }, + { + name: "download_url_template_invalid", + downloadURL: "{{.dddddddddd", + wantErr: true, + }, + } - expectedURL := "https://gitea.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}" - require.Equal(t, expectedURL, urlTpl) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.New(config.Project{ + Env: []string{ + "GORELEASER_TEST_GITEA_URLS_DOWNLOAD=https://gitea.mycompany.com", + }, + GiteaURLs: config.GiteaURLs{ + API: "https://gitea.com/api/v1", + Download: tt.downloadURL, + }, + Release: config.Release{ + Gitea: config.Repo{ + Owner: "owner", + Name: "name", + }, + }, + }) + client, err := NewGitea(ctx, ctx.Token) + require.NoError(t, err) + + urlTpl, err := client.ReleaseURLTemplate(ctx) + if tt.wantErr { + require.Error(t, err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.wantDownloadURL, urlTpl) + }) + } } diff --git a/internal/client/github.go b/internal/client/github.go index 40dd864c49f..d6da97c29dc 100644 --- a/internal/client/github.go +++ b/internal/client/github.go @@ -40,18 +40,11 @@ func NewGitHub(ctx *context.Context, token string) (Client, error) { } base.(*http.Transport).Proxy = http.ProxyFromEnvironment httpClient.Transport.(*oauth2.Transport).Base = base + client := github.NewClient(httpClient) - if ctx.Config.GitHubURLs.API != "" { - api, err := url.Parse(ctx.Config.GitHubURLs.API) - if err != nil { - return &githubClient{}, err - } - upload, err := url.Parse(ctx.Config.GitHubURLs.Upload) - if err != nil { - return &githubClient{}, err - } - client.BaseURL = api - client.UploadURL = upload + err := overrideGitHubClientAPI(ctx, client) + if err != nil { + return &githubClient{}, err } return &githubClient{client: client}, nil @@ -181,9 +174,14 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (string, } func (c *githubClient) ReleaseURLTemplate(ctx *context.Context) (string, error) { + downloadURL, err := tmpl.New(ctx).Apply(ctx.Config.GitHubURLs.Download) + if err != nil { + return "", fmt.Errorf("templating GitHub download URL: %w", err) + } + return fmt.Sprintf( "%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}", - ctx.Config.GitHubURLs.Download, + downloadURL, ctx.Config.Release.GitHub.Owner, ctx.Config.Release.GitHub.Name, ), nil @@ -251,3 +249,32 @@ func (c *githubClient) getMilestoneByTitle(ctx *context.Context, repo Repo, titl return nil, nil } + +func overrideGitHubClientAPI(ctx *context.Context, client *github.Client) error { + if ctx.Config.GitHubURLs.API == "" { + return nil + } + + apiURL, err := tmpl.New(ctx).Apply(ctx.Config.GitHubURLs.API) + if err != nil { + return fmt.Errorf("templating GitHub API URL: %w", err) + } + api, err := url.Parse(apiURL) + if err != nil { + return err + } + + uploadURL, err := tmpl.New(ctx).Apply(ctx.Config.GitHubURLs.Upload) + if err != nil { + return fmt.Errorf("templating GitHub upload URL: %w", err) + } + upload, err := url.Parse(uploadURL) + if err != nil { + return err + } + + client.BaseURL = api + client.UploadURL = upload + + return nil +} diff --git a/internal/client/github_test.go b/internal/client/github_test.go index 6069c8ca295..f0d3173d13c 100644 --- a/internal/client/github_test.go +++ b/internal/client/github_test.go @@ -1,7 +1,9 @@ package client import ( + "fmt" "testing" + "text/template" "github.com/goreleaser/goreleaser/internal/artifact" "github.com/goreleaser/goreleaser/pkg/config" @@ -11,15 +13,21 @@ import ( func TestNewGitHubClient(t *testing.T) { t.Run("good urls", func(t *testing.T) { + githubURL := "https://github.mycompany.com" ctx := context.New(config.Project{ GitHubURLs: config.GitHubURLs{ - API: "https://github.mycompany.com/api", - Upload: "https://github.mycompany.com/upload", + API: githubURL + "/api", + Upload: githubURL + "/upload", }, }) - _, err := NewGitHub(ctx, ctx.Token) + client, err := NewGitHub(ctx, ctx.Token) require.NoError(t, err) + + githubClient, ok := client.(*githubClient) + require.True(t, ok) + require.Equal(t, githubURL+"/api", githubClient.client.BaseURL.String()) + require.Equal(t, githubURL+"/upload", githubClient.client.UploadURL.String()) }) t.Run("bad api url", func(t *testing.T) { @@ -45,6 +53,62 @@ func TestNewGitHubClient(t *testing.T) { require.EqualError(t, err, `parse "not a url:4994": first path segment in URL cannot contain colon`) }) + + t.Run("template", func(t *testing.T) { + githubURL := "https://github.mycompany.com" + ctx := context.New(config.Project{ + Env: []string{ + fmt.Sprintf("GORELEASER_TEST_GITHUB_URLS_API=%s/api", githubURL), + fmt.Sprintf("GORELEASER_TEST_GITHUB_URLS_UPLOAD=%s/upload", githubURL), + }, + GitHubURLs: config.GitHubURLs{ + API: "{{ .Env.GORELEASER_TEST_GITHUB_URLS_API }}", + Upload: "{{ .Env.GORELEASER_TEST_GITHUB_URLS_UPLOAD }}", + }, + }) + + client, err := NewGitHub(ctx, ctx.Token) + require.NoError(t, err) + + githubClient, ok := client.(*githubClient) + require.True(t, ok) + require.Equal(t, githubURL+"/api", githubClient.client.BaseURL.String()) + require.Equal(t, githubURL+"/upload", githubClient.client.UploadURL.String()) + }) + + t.Run("template invalid api", func(t *testing.T) { + ctx := context.New(config.Project{ + GitHubURLs: config.GitHubURLs{ + API: "{{ .Env.GORELEASER_NOT_EXISTS }}", + }, + }) + + _, err := NewGitHub(ctx, ctx.Token) + require.ErrorAs(t, err, &template.ExecError{}) + }) + + t.Run("template invalid upload", func(t *testing.T) { + ctx := context.New(config.Project{ + GitHubURLs: config.GitHubURLs{ + API: "https://github.mycompany.com/api", + Upload: "{{ .Env.GORELEASER_NOT_EXISTS }}", + }, + }) + + _, err := NewGitHub(ctx, ctx.Token) + require.ErrorAs(t, err, &template.ExecError{}) + }) + + t.Run("template invalid", func(t *testing.T) { + ctx := context.New(config.Project{ + GitHubURLs: config.GitHubURLs{ + API: "{{.dddddddddd", + }, + }) + + _, err := NewGitHub(ctx, ctx.Token) + require.Error(t, err) + }) } func TestGitHubUploadReleaseIDNotInt(t *testing.T) { @@ -60,26 +124,63 @@ func TestGitHubUploadReleaseIDNotInt(t *testing.T) { } func TestGitHubReleaseURLTemplate(t *testing.T) { - ctx := context.New(config.Project{ - GitHubURLs: config.GitHubURLs{ - // default URL would otherwise be set via pipe/defaults - Download: DefaultGitHubDownloadURL, + tests := []struct { + name string + downloadURL string + wantDownloadURL string + wantErr bool + }{ + { + name: "default_download_url", + downloadURL: DefaultGitHubDownloadURL, + wantDownloadURL: "https://github.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", }, - Release: config.Release{ - GitHub: config.Repo{ - Owner: "owner", - Name: "name", - }, + { + name: "download_url_template", + downloadURL: "{{ .Env.GORELEASER_TEST_GITHUB_URLS_DOWNLOAD }}", + wantDownloadURL: "https://github.mycompany.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}", }, - }) - client, err := NewGitHub(ctx, ctx.Token) - require.NoError(t, err) + { + name: "download_url_template_invalid_value", + downloadURL: "{{ .Env.GORELEASER_NOT_EXISTS }}", + wantErr: true, + }, + { + name: "download_url_template_invalid", + downloadURL: "{{.dddddddddd", + wantErr: true, + }, + } - urlTpl, err := client.ReleaseURLTemplate(ctx) - require.NoError(t, err) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.New(config.Project{ + Env: []string{ + "GORELEASER_TEST_GITHUB_URLS_DOWNLOAD=https://github.mycompany.com", + }, + GitHubURLs: config.GitHubURLs{ + Download: tt.downloadURL, + }, + Release: config.Release{ + GitHub: config.Repo{ + Owner: "owner", + Name: "name", + }, + }, + }) + client, err := NewGitHub(ctx, ctx.Token) + require.NoError(t, err) + + urlTpl, err := client.ReleaseURLTemplate(ctx) + if tt.wantErr { + require.Error(t, err) + return + } - expectedURL := "https://github.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}" - require.Equal(t, expectedURL, urlTpl) + require.NoError(t, err) + require.Equal(t, tt.wantDownloadURL, urlTpl) + }) + } } func TestGitHubCreateReleaseWrongNameTemplate(t *testing.T) { diff --git a/internal/client/gitlab.go b/internal/client/gitlab.go index 02a819b34ad..67b9616179b 100644 --- a/internal/client/gitlab.go +++ b/internal/client/gitlab.go @@ -35,7 +35,12 @@ func NewGitLab(ctx *context.Context, token string) (Client, error) { }), } if ctx.Config.GitLabURLs.API != "" { - options = append(options, gitlab.WithBaseURL(ctx.Config.GitLabURLs.API)) + apiURL, err := tmpl.New(ctx).Apply(ctx.Config.GitLabURLs.API) + if err != nil { + return nil, fmt.Errorf("templating GitLab API URL: %w", err) + } + + options = append(options, gitlab.WithBaseURL(apiURL)) } client, err := gitlab.NewClient(token, options...) if err != nil { @@ -270,17 +275,22 @@ func (c *gitlabClient) ReleaseURLTemplate(ctx *context.Context) (string, error) if err != nil { return "", err } + downloadURL, err := tmpl.New(ctx).Apply(ctx.Config.GitLabURLs.Download) + if err != nil { + return "", err + } + if ctx.Config.Release.GitLab.Owner != "" { urlTemplate = fmt.Sprintf( "%s/%s/%s/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}", - ctx.Config.GitLabURLs.Download, + downloadURL, ctx.Config.Release.GitLab.Owner, gitlabName, ) } else { urlTemplate = fmt.Sprintf( "%s/%s/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}", - ctx.Config.GitLabURLs.Download, + downloadURL, gitlabName, ) } @@ -326,7 +336,11 @@ func (c *gitlabClient) Upload( return err } - gitlabBaseURL := ctx.Config.GitLabURLs.Download + gitlabBaseURL, err := tmpl.New(ctx).Apply(ctx.Config.GitLabURLs.Download) + if err != nil { + return fmt.Errorf("templating GitLab Download URL: %w", err) + } + linkURL := gitlabBaseURL + "/" + projectDetails.PathWithNamespace + projectFile.URL name := artifact.Name filename := "/" + name diff --git a/internal/client/gitlab_test.go b/internal/client/gitlab_test.go index 8c78914508d..6b06eacd045 100644 --- a/internal/client/gitlab_test.go +++ b/internal/client/gitlab_test.go @@ -1,32 +1,229 @@ package client import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "os" + "strings" "testing" + "text/template" + "github.com/goreleaser/goreleaser/internal/artifact" "github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/context" "github.com/stretchr/testify/require" ) func TestGitLabReleaseURLTemplate(t *testing.T) { - ctx := context.New(config.Project{ - GitLabURLs: config.GitLabURLs{ - // default URL would otherwise be set via pipe/defaults - Download: DefaultGitLabDownloadURL, - }, - Release: config.Release{ - GitLab: config.Repo{ - Owner: "owner", - Name: "name", + tests := []struct { + name string + downloadURL string + wantDownloadURL string + wantErr bool + }{ + { + name: "default_download_url", + downloadURL: DefaultGitLabDownloadURL, + wantDownloadURL: "https://gitlab.com/owner/name/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}", + }, + { + name: "download_url_template", + downloadURL: "{{ .Env.GORELEASER_TEST_GITLAB_URLS_DOWNLOAD }}", + wantDownloadURL: "https://gitlab.mycompany.com/owner/name/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}", + }, + { + name: "download_url_template_invalid_value", + downloadURL: "{{ .Env.GORELEASER_NOT_EXISTS }}", + wantErr: true, + }, + { + name: "download_url_template_invalid", + downloadURL: "{{.dddddddddd", + wantErr: true, + }, + } + + for _, tt := range tests { + ctx := context.New(config.Project{ + Env: []string{ + "GORELEASER_TEST_GITLAB_URLS_DOWNLOAD=https://gitlab.mycompany.com", }, + GitLabURLs: config.GitLabURLs{ + Download: tt.downloadURL, + }, + Release: config.Release{ + GitLab: config.Repo{ + Owner: "owner", + Name: "name", + }, + }, + }) + client, err := NewGitLab(ctx, ctx.Token) + require.NoError(t, err) + + urlTpl, err := client.ReleaseURLTemplate(ctx) + if tt.wantErr { + require.Error(t, err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.wantDownloadURL, urlTpl) + } +} + +func TestGitLabURLsAPITemplate(t *testing.T) { + tests := []struct { + name string + apiURL string + wantHost string + }{ + { + name: "default_values", + wantHost: "gitlab.com", + }, + { + name: "speicifed_api_env_key", + apiURL: "https://gitlab.mycompany.com", + wantHost: "gitlab.mycompany.com", }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + envs := []string{} + gitlabURLs := config.GitLabURLs{} + + if tt.apiURL != "" { + envs = append(envs, fmt.Sprintf("GORELEASER_TEST_GITLAB_URLS_API=%s", tt.apiURL)) + gitlabURLs.API = "{{ .Env.GORELEASER_TEST_GITLAB_URLS_API }}" + } + + ctx := context.New(config.Project{ + Env: envs, + GitLabURLs: gitlabURLs, + }) + + client, err := NewGitLab(ctx, ctx.Token) + require.NoError(t, err) + + gitlabClient, ok := client.(*gitlabClient) + require.True(t, ok) + + require.Equal(t, tt.wantHost, gitlabClient.client.BaseURL().Host) + }) + } + + t.Run("no_env_specified", func(t *testing.T) { + ctx := context.New(config.Project{ + GitLabURLs: config.GitLabURLs{ + API: "{{ .Env.GORELEASER_NOT_EXISTS }}", + }, + }) + + _, err := NewGitLab(ctx, ctx.Token) + require.ErrorAs(t, err, &template.ExecError{}) + }) + + t.Run("invalid_template", func(t *testing.T) { + ctx := context.New(config.Project{ + GitLabURLs: config.GitLabURLs{ + API: "{{.dddddddddd", + }, + }) + + _, err := NewGitLab(ctx, ctx.Token) + require.Error(t, err) }) - client, err := NewGitLab(ctx, ctx.Token) - require.NoError(t, err) +} + +func TestGitLabURLsDownloadTemplate(t *testing.T) { + tests := []struct { + name string + downloadURL string + wantURL string + wantErr bool + }{ + { + name: "empty_download_url", + wantURL: "/", + }, + { + name: "download_url_template", + downloadURL: "{{ .Env.GORELEASER_TEST_GITLAB_URLS_DOWNLOAD }}", + wantURL: "https://gitlab.mycompany.com/", + }, + { + name: "download_url_template_invalid_value", + downloadURL: "{{ .Eenv.GORELEASER_NOT_EXISTS }}", + wantErr: true, + }, + { + name: "download_url_template_invalid", + downloadURL: "{{.dddddddddd", + wantErr: true, + }, + { + name: "download_url_string", + downloadURL: "https://gitlab.mycompany.com", + wantURL: "https://gitlab.mycompany.com/", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer fmt.Fprint(w, "{}") + defer w.WriteHeader(http.StatusOK) + defer r.Body.Close() + + if !strings.Contains(r.URL.Path, "assets/links") { + _, _ = io.Copy(io.Discard, r.Body) + return + } + + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + + reqBody := map[string]interface{}{} + err = json.Unmarshal(b, &reqBody) + require.NoError(t, err) + + require.Equal(t, tt.wantURL, reqBody["url"]) + })) + defer srv.Close() + + ctx := context.New(config.Project{ + Env: []string{ + "GORELEASER_TEST_GITLAB_URLS_DOWNLOAD=https://gitlab.mycompany.com", + }, + Release: config.Release{ + GitLab: config.Repo{ + Owner: "test", + Name: "test", + }, + }, + GitLabURLs: config.GitLabURLs{ + API: srv.URL, + Download: tt.downloadURL, + }, + }) + + tmpFile, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) - urlTpl, err := client.ReleaseURLTemplate(ctx) - require.NoError(t, err) + client, err := NewGitLab(ctx, ctx.Token) + require.NoError(t, err) - expectedURL := "https://gitlab.com/owner/name/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}" - require.Equal(t, expectedURL, urlTpl) + err = client.Upload(ctx, "1234", &artifact.Artifact{Name: "test", Path: "some-path"}, tmpFile) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + }) + } } diff --git a/internal/pipe/defaults/defaults.go b/internal/pipe/defaults/defaults.go index 538700e22fd..4245c8de3f1 100644 --- a/internal/pipe/defaults/defaults.go +++ b/internal/pipe/defaults/defaults.go @@ -3,10 +3,12 @@ package defaults import ( + "fmt" "strings" "github.com/goreleaser/goreleaser/internal/client" "github.com/goreleaser/goreleaser/internal/middleware" + "github.com/goreleaser/goreleaser/internal/tmpl" "github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/defaults" ) @@ -30,7 +32,12 @@ func (Pipe) Run(ctx *context.Context) error { ctx.Config.GitLabURLs.Download = client.DefaultGitLabDownloadURL } if ctx.Config.GiteaURLs.Download == "" { - ctx.Config.GiteaURLs.Download = strings.ReplaceAll(ctx.Config.GiteaURLs.API, "/api/v1", "") + apiURL, err := tmpl.New(ctx).Apply(ctx.Config.GiteaURLs.API) + if err != nil { + return fmt.Errorf("templating Gitea API URL: %w", err) + } + + ctx.Config.GiteaURLs.Download = strings.ReplaceAll(apiURL, "/api/v1", "") } for _, defaulter := range defaults.Defaulters { if err := middleware.Logging( diff --git a/internal/pipe/defaults/defaults_test.go b/internal/pipe/defaults/defaults_test.go index 4880dec6147..c1f2c2f69f3 100644 --- a/internal/pipe/defaults/defaults_test.go +++ b/internal/pipe/defaults/defaults_test.go @@ -114,3 +114,53 @@ func TestFillPartial(t *testing.T) { require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "https://gitea.com", ctx.Config.GiteaURLs.Download) } + +func TestGiteaTemplateDownloadURL(t *testing.T) { + tests := []struct { + name string + apiURL string + wantErr bool + }{ + { + name: "string_url", + apiURL: "https://gitea.com/api/v1", + }, + { + name: "download_url_template", + apiURL: "{{ .Env.GORELEASER_TEST_GITEA_URLS_API }}", + }, + { + name: "download_url_template_invalid_value", + apiURL: "{{ .Env.GORELEASER_NOT_EXISTS }}", + wantErr: true, + }, + { + name: "download_url_template_invalid", + apiURL: "{{.dddddddddd", + wantErr: true, + }, + } + + for _, tt := range tests { + ctx := &context.Context{ + TokenType: context.TokenTypeGitea, + Env: context.Env{ + "GORELEASER_TEST_GITEA_URLS_API": "https://gitea.com/api/v1", + }, + Config: config.Project{ + GiteaURLs: config.GiteaURLs{ + API: tt.apiURL, + }, + }, + } + + err := Pipe{}.Run(ctx) + if tt.wantErr { + require.Error(t, err) + return + } + + require.NoError(t, err) + require.Equal(t, "https://gitea.com", ctx.Config.GiteaURLs.Download) + } +} diff --git a/www/docs/scm/gitea.md b/www/docs/scm/gitea.md index 12b6abd2c86..a0272e3a5a2 100644 --- a/www/docs/scm/gitea.md +++ b/www/docs/scm/gitea.md @@ -19,7 +19,7 @@ env_files: ## URLs You can use GoReleaser with Gitea by providing its URLs in -the `.goreleaser.yml` configuration file: +the `.goreleaser.yml` configuration file. This takes a normal string or a template value. ```yaml # .goreleaser.yml diff --git a/www/docs/scm/github.md b/www/docs/scm/github.md index cd6e85fb8c9..7b97df63ecc 100644 --- a/www/docs/scm/github.md +++ b/www/docs/scm/github.md @@ -18,7 +18,9 @@ env_files: ## GitHub Enterprise -You can use GoReleaser with GitHub Enterprise by providing its URLs in the `.goreleaser.yml` configuration file: +You can use GoReleaser with GitHub Enterprise by providing its URLs in the +`.goreleaser.yml` configuration file. This takes a normal string or a template +value. ```yaml # .goreleaser.yml diff --git a/www/docs/scm/gitlab.md b/www/docs/scm/gitlab.md index ed058e96994..5cfc47bd0fb 100644 --- a/www/docs/scm/gitlab.md +++ b/www/docs/scm/gitlab.md @@ -18,8 +18,8 @@ env_files: ## GitLab Enterprise or private hosted -You can use GoReleaser with GitLab Enterprise by providing its URLs in -the `.goreleaser.yml` configuration file: +You can use GoReleaser with GitLab Enterprise by providing its URLs in the +`.goreleaser.yml` configuration file. This takes a normal string or a template value. ```yaml # .goreleaser.yml