1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2024-12-29 01:44:39 +02:00

feat: support templates for scm urls (#2465)

Background
---
When a git repository is hosted in multiple GitLab instances the
`.goreleaser.yml` needs to take in consideration both APIs endpoints. At
the moment it defaults to GitLab.com and you can override it with
`gitlab_urls` however this forces you to only support 1 GitLab instance.

We need this for
https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/14122
where we have a tool that is developed on GitLab.com but then mirrored
to an internal GitLab instance since we need it to operate GitLab.com
even when it's down.

Solution
---
Support templates like `{{ .Env.CI_SERVER_URL }}` for the
`gitlab_urls`, `github_urls`  and `gitea_urls` so it can use environment
variables and the same `.goreleaser` file can be used in multiple SCM
instances.

Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Steve Azzopardi 2021-09-09 03:42:13 +02:00 committed by GitHub
parent 717051d70f
commit 68ff8e996f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 593 additions and 81 deletions

View File

@ -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

View File

@ -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)
{
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_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)
expectedURL := "https://gitea.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
require.Equal(t, expectedURL, urlTpl)
urlTpl, err := client.ReleaseURLTemplate(ctx)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.wantDownloadURL, urlTpl)
})
}
}

View File

@ -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
}

View File

@ -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)
expectedURL := "https://github.com/owner/name/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
require.Equal(t, expectedURL, urlTpl)
urlTpl, err := client.ReleaseURLTemplate(ctx)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.wantDownloadURL, urlTpl)
})
}
}
func TestGitHubCreateReleaseWrongNameTemplate(t *testing.T) {

View File

@ -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

View File

@ -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,
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 }}",
},
Release: config.Release{
GitLab: config.Repo{
Owner: "owner",
Name: "name",
{
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",
},
},
})
client, err := NewGitLab(ctx, ctx.Token)
require.NoError(t, err)
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)
require.NoError(t, err)
urlTpl, err := client.ReleaseURLTemplate(ctx)
if tt.wantErr {
require.Error(t, err)
return
}
expectedURL := "https://gitlab.com/owner/name/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}"
require.Equal(t, expectedURL, urlTpl)
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)
})
}
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)
client, err := NewGitLab(ctx, ctx.Token)
require.NoError(t, err)
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)
})
}
}

View File

@ -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(

View File

@ -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)
}
}

View File

@ -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

View File

@ -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

View File

@ -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