Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support templates for scm urls #2465

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 13 additions & 3 deletions internal/client/gitea.go
Expand Up @@ -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
Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand Down
150 changes: 127 additions & 23 deletions internal/client/gitea_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"strings"
"testing"
"text/template"

"code.gitea.io/sdk/gitea"
"github.com/goreleaser/goreleaser/internal/artifact"
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
})
}
}
51 changes: 39 additions & 12 deletions internal/client/github.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}