1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-01 13:07:49 +02:00

feat: full gitlab support for brew and scoop (#1084)

* makes context tokentype a public var

* passes artifacts object into client upload function. extracts gitlab upload hash from url

* adds gitlab url to brew config

* build brew formula depending on token type

* fixes client for release tests

* fixes exiting brew tests

* fixes scoop test with dummy client adaption

* uses new artifact upload hash

* fixes brew usage

* updates gitlab createFile for brew

* fixes logging for non-existing file in gitlab logging

* fix: gitlab createFile

* fix: removes encoding from gitlab create and update file opts

* fix: gitlab upload and artifact set upload hash

* fix: linter

* changed artifact item to a pointer in ctx

* docs: updates homebrew

* feat: enables scoop for gitlab release

* fix: scoop panic for pointer access

* chore: rename formula build func for brew

* chore: brew removes comments

* fix: brew tests

* test: updates brew tests

* docs: updates homebrew

* test: for token type not implemented for brew

* tests: for multiple linux builds

* fix: build artifacts are pointer in scoop

* test: for scoop and gitlab

* test: for artifacts set upload hash

* adds missing files after adaption

* chore: removes and clarifies comments

* fix: moves artifact upload hash to extra map

* adds comment why we initialize the extra map
This commit is contained in:
Manuel Vogel 2019-08-13 20:28:03 +02:00 committed by Carlos Alexandro Becker
parent 23e275e946
commit e92bbe32ce
20 changed files with 787 additions and 168 deletions

View File

@ -4,6 +4,7 @@ package client
import (
"os"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
@ -19,7 +20,7 @@ type Info struct {
type Client interface {
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
CreateFile(ctx *context.Context, commitAuthor config.CommitAuthor, repo config.Repo, content []byte, path, message string) (err error)
Upload(ctx *context.Context, releaseID string, name string, file *os.File) (err error)
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
}
// New creates a new client depending on the token type

View File

@ -10,6 +10,7 @@ import (
"github.com/apex/log"
"github.com/google/go-github/v25/github"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
@ -150,7 +151,7 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (string,
func (c *githubClient) Upload(
ctx *context.Context,
releaseID string,
name string,
artifact *artifact.Artifact,
file *os.File,
) error {
githubReleaseID, err := strconv.ParseInt(releaseID, 10, 64)
@ -163,7 +164,7 @@ func (c *githubClient) Upload(
ctx.Config.Release.GitHub.Name,
githubReleaseID,
&github.UploadOptions{
Name: name,
Name: artifact.Name,
},
file,
)

View File

@ -2,16 +2,22 @@ package client
import (
"crypto/tls"
"errors"
"net/http"
"os"
"strings"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/xanzy/go-gitlab"
)
// ErrExtractHashFromFileUploadURL indicates the file upload hash could not ne extracted from the url
var ErrExtractHashFromFileUploadURL = errors.New("could not extract hash from gitlab file upload url")
type gitlabClient struct {
client *gitlab.Client
}
@ -36,18 +42,113 @@ func NewGitLab(ctx *context.Context) (Client, error) {
return &gitlabClient{client: client}, nil
}
// CreateFile creates a file in the repository at a given path
// or updates the file if it exists
// CreateFile gets a file in the repository at a given path
// and updates if it exists or creates it for later pipes in the pipeline
func (c *gitlabClient) CreateFile(
ctx *context.Context,
commitAuthor config.CommitAuthor,
repo config.Repo,
content []byte,
path,
message string,
content []byte, // the content of the formula.rb
path, // the path to the formula.rb
message string, // the commit msg
) error {
// Used by brew and scoop, hence those two pipes are
// only supported for github atm. So we disable it for now.
fileName := path
// we assume having the formula in the master branch only
ref := "master"
branch := "master"
opts := &gitlab.GetFileOptions{Ref: &ref}
castedContent := string(content)
projectID := repo.Owner + "/" + repo.Name
log.WithFields(log.Fields{
"owner": repo.Owner,
"name": repo.Name,
}).Debug("projectID at brew")
_, res, err := c.client.RepositoryFiles.GetFile(projectID, fileName, opts)
if err != nil && (res == nil || res.StatusCode != 404) {
log.WithFields(log.Fields{
"fileName": fileName,
"ref": ref,
"projectID": projectID,
"statusCode": res.StatusCode,
"err": err.Error(),
}).Error("error getting file for brew formula")
return err
}
log.WithFields(log.Fields{
"fileName": fileName,
"branch": branch,
"projectID": projectID,
}).Debug("found already existing brew formula file")
if res.StatusCode == 404 {
log.WithFields(log.Fields{
"fileName": fileName,
"ref": ref,
"projectID": projectID,
}).Debug("creating brew formula")
createOpts := &gitlab.CreateFileOptions{
AuthorName: &commitAuthor.Name,
AuthorEmail: &commitAuthor.Email,
Content: &castedContent,
Branch: &branch,
CommitMessage: &message,
}
fileInfo, res, err := c.client.RepositoryFiles.CreateFile(projectID, fileName, createOpts)
if err != nil {
log.WithFields(log.Fields{
"fileName": fileName,
"branch": branch,
"projectID": projectID,
"statusCode": res.StatusCode,
"err": err.Error(),
}).Error("error creating brew formula file")
return err
}
log.WithFields(log.Fields{
"fileName": fileName,
"branch": branch,
"projectID": projectID,
"filePath": fileInfo.FilePath,
}).Debug("created brew formula file")
return nil
}
log.WithFields(log.Fields{
"fileName": fileName,
"ref": ref,
"projectID": projectID,
}).Debug("updating brew formula")
updateOpts := &gitlab.UpdateFileOptions{
AuthorName: &commitAuthor.Name,
AuthorEmail: &commitAuthor.Email,
Content: &castedContent,
Branch: &branch,
CommitMessage: &message,
}
updateFileInfo, res, err := c.client.RepositoryFiles.UpdateFile(projectID, fileName, updateOpts)
if err != nil {
log.WithFields(log.Fields{
"fileName": fileName,
"branch": branch,
"projectID": projectID,
"statusCode": res.StatusCode,
"err": err.Error(),
}).Error("error updating brew formula file")
return err
}
log.WithFields(log.Fields{
"fileName": fileName,
"branch": branch,
"projectID": projectID,
"filePath": updateFileInfo.FilePath,
"statusCode": res.StatusCode,
}).Debug("updated brew formula file")
return nil
}
@ -128,7 +229,7 @@ func (c *gitlabClient) CreateRelease(ctx *context.Context, body string) (release
func (c *gitlabClient) Upload(
ctx *context.Context,
releaseID string,
name string,
artifact *artifact.Artifact,
file *os.File,
) error {
projectID := ctx.Config.Release.GitLab.Owner + "/" + ctx.Config.Release.GitLab.Name
@ -150,9 +251,9 @@ func (c *gitlabClient) Upload(
}).Debug("uploaded file")
gitlabBaseURL := ctx.Config.GitLabURLs.Download
// projectFile from upload: /uploads/<sha>/filename.txt
relativeUploadURL := projectFile.URL
linkURL := gitlabBaseURL + "/" + projectID + relativeUploadURL
// projectFile.URL from upload: /uploads/<hash>/filename.txt
linkURL := gitlabBaseURL + "/" + projectID + projectFile.URL
name := artifact.Name
releaseLink, _, err := c.client.ReleaseLinks.CreateReleaseLink(
projectID,
releaseID,
@ -170,5 +271,36 @@ func (c *gitlabClient) Upload(
"url": releaseLink.URL,
}).Debug("created release link")
fileUploadHash, err := extractProjectFileHashFrom(projectFile.URL)
if err != nil {
return err
}
// for checksums.txt the field is nil, so we initialize it
if artifact.Extra == nil {
artifact.Extra = make(map[string]interface{})
}
// we set this hash to be able to download the file
// in following publish pipes like brew, scoop
artifact.Extra["ArtifactUploadHash"] = fileUploadHash
return err
}
// extractProjectFileHashFrom extracts the hash from the
// relative project file url of the format '/uploads/<hash>/filename.ext'
func extractProjectFileHashFrom(projectFileURL string) (string, error) {
log.WithField("projectFileURL", projectFileURL).Debug("extract file hash from")
splittedProjectFileURL := strings.Split(projectFileURL, "/")
if len(splittedProjectFileURL) != 4 {
log.WithField("projectFileURL", projectFileURL).Debug("could not extract file hash")
return "", ErrExtractHashFromFileUploadURL
}
fileHash := splittedProjectFileURL[2]
log.WithFields(log.Fields{
"projectFileURL": projectFileURL,
"fileHash": fileHash,
}).Debug("extracted file hash")
return fileHash, nil
}

View File

@ -0,0 +1,33 @@
package client
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestExtractHashFromProjectFileURL(t *testing.T) {
givenHash := "22e8b1508b0f28433b94754a5ea2f4aa"
projectFileURL := fmt.Sprintf("/uploads/%s/release-testing_0.3.7_Darwin_x86_64.tar.gz", givenHash)
extractedHash, err := extractProjectFileHashFrom(projectFileURL)
if err != nil {
t.Errorf("expexted no error but got: %v", err)
}
assert.Equal(t, givenHash, extractedHash)
}
func TestFailToExtractHashFromProjectFileURL(t *testing.T) {
givenHash := "22e8b1508b0f28433b94754a5ea2f4aa"
projectFileURL := fmt.Sprintf("/uploads/%s/new-path/file.ext", givenHash)
_, err := extractProjectFileHashFrom(projectFileURL)
if err == nil {
t.Errorf("expected an error but got none for new-path in url")
}
projectFileURL = fmt.Sprintf("/%s/file.ext", givenHash)
_, err = extractProjectFileHashFrom(projectFileURL)
if err == nil {
t.Errorf("expected an error but got none for path-too-small in url")
}
}

View File

@ -30,6 +30,9 @@ var ErrNoArchivesFound = errors.New("brew tap: no archives found matching criter
// TODO: improve this confusing error message
var ErrMultipleArchivesSameOS = errors.New("brew tap: one tap can handle only 1 linux and 1 macos archive")
// ErrTokenTypeNotImplementedForBrew indicates that a new token type was not implemented for this pipe
var ErrTokenTypeNotImplementedForBrew = errors.New("token type not implemented for brew pipe")
// Pipe for brew deployment
type Pipe struct{}
@ -39,7 +42,7 @@ func (Pipe) String() string {
// Publish brew formula
func (Pipe) Publish(ctx *context.Context) error {
client, err := client.NewGitHub(ctx)
client, err := client.New(ctx)
if err != nil {
return err
}
@ -112,15 +115,14 @@ func contains(ss []string, s string) bool {
}
func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) error {
if brew.GitHub.Name == "" {
if brew.GitHub.Name == "" && brew.GitLab.Name == "" {
return pipe.Skip("brew section is not configured")
}
// If we'd use 'ctx.TokenType != context.TokenTypeGitHub' we'd have to adapt all the tests
// For simplicity we use this check because the functionality will be implemented later for
// all types of releases. See https://github.com/goreleaser/goreleaser/pull/1038#issuecomment-498891464
if ctx.TokenType == context.TokenTypeGitLab {
return pipe.Skip("brew pipe is only configured for github releases")
}
// TODO mavogel: in another PR
// check if release pipe is not configured!
// if ctx.Config.Release.Disable {
// }
var filters = []artifact.Filter{
artifact.Or(
@ -140,7 +142,7 @@ func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) err
return ErrNoArchivesFound
}
content, err := buildFormula(ctx, brew, archives)
content, err := buildFormula(ctx, brew, ctx.TokenType, archives)
if err != nil {
return err
}
@ -165,21 +167,31 @@ func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) err
return pipe.Skip("prerelease detected with 'auto' upload, skipping homebrew publish")
}
var gpath = ghFormulaPath(brew.Folder, filename)
var repo config.Repo
switch ctx.TokenType {
case context.TokenTypeGitHub:
repo = brew.GitHub
case context.TokenTypeGitLab:
repo = brew.GitLab
default:
return ErrTokenTypeNotImplementedForBrew
}
var gpath = buildFormulaPath(brew.Folder, filename)
log.WithField("formula", gpath).
WithField("repo", brew.GitHub.String()).
WithField("repo", repo.String()).
Info("pushing")
var msg = fmt.Sprintf("Brew formula update for %s version %s", ctx.Config.ProjectName, ctx.Git.CurrentTag)
return client.CreateFile(ctx, brew.CommitAuthor, brew.GitHub, []byte(content), gpath, msg)
return client.CreateFile(ctx, brew.CommitAuthor, repo, []byte(content), gpath, msg)
}
func ghFormulaPath(folder, filename string) string {
func buildFormulaPath(folder, filename string) string {
return path.Join(folder, filename)
}
func buildFormula(ctx *context.Context, brew config.Homebrew, artifacts []*artifact.Artifact) (string, error) {
data, err := dataFor(ctx, brew, artifacts)
func buildFormula(ctx *context.Context, brew config.Homebrew, tokenType context.TokenType, artifacts []*artifact.Artifact) (string, error) {
data, err := dataFor(ctx, brew, tokenType, artifacts)
if err != nil {
return "", err
}
@ -198,7 +210,7 @@ func doBuildFormula(ctx *context.Context, data templateData) (string, error) {
return tmpl.New(ctx).Apply(out.String())
}
func dataFor(ctx *context.Context, cfg config.Homebrew, artifacts []*artifact.Artifact) (templateData, error) {
func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenType, artifacts []*artifact.Artifact) (templateData, error) {
var result = templateData{
Name: formulaNameFor(cfg.Name),
Desc: cfg.Description,
@ -222,12 +234,24 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, artifacts []*artifact.Ar
}
if cfg.URLTemplate == "" {
cfg.URLTemplate = fmt.Sprintf(
"%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}",
ctx.Config.GitHubURLs.Download,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
)
switch tokenType {
case context.TokenTypeGitHub:
cfg.URLTemplate = fmt.Sprintf(
"%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}",
ctx.Config.GitHubURLs.Download,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
)
case context.TokenTypeGitLab:
cfg.URLTemplate = fmt.Sprintf(
"%s/%s/%s/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}",
ctx.Config.GitLabURLs.Download,
ctx.Config.Release.GitLab.Owner,
ctx.Config.Release.GitLab.Name,
)
default:
return result, ErrTokenTypeNotImplementedForBrew
}
}
url, err := tmpl.New(ctx).WithArtifact(artifact, map[string]string{}).Apply(cfg.URLTemplate)
if err != nil {

View File

@ -109,20 +109,80 @@ func TestSplit(t *testing.T) {
func TestRunPipe(t *testing.T) {
for name, fn := range map[string]func(ctx *context.Context){
"default": func(ctx *context.Context) {},
"default": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitHub
ctx.Config.GitHubURLs.Download = "https://github.com"
ctx.Config.Release.GitHub.Owner = "test"
ctx.Config.Release.GitHub.Name = "test"
ctx.Config.Brews[0].GitHub.Owner = "test"
ctx.Config.Brews[0].GitHub.Name = "test"
ctx.Config.Brews[0].Homepage = "https://github.com/goreleaser"
},
"github_enterprise_url": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitHub
ctx.Config.GitHubURLs.Download = "https://github.com"
ctx.Config.Release.GitHub.Owner = "test"
ctx.Config.Release.GitHub.Name = "test"
ctx.Config.Brews[0].GitHub.Owner = "test"
ctx.Config.Brews[0].GitHub.Name = "test"
ctx.Config.Brews[0].Homepage = "https://github.com/goreleaser"
ctx.Config.GitHubURLs.Download = "http://github.example.org"
},
"custom_download_strategy": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitHub
ctx.Config.GitHubURLs.Download = "https://github.com"
ctx.Config.Release.GitHub.Owner = "test"
ctx.Config.Release.GitHub.Name = "test"
ctx.Config.Brews[0].GitHub.Owner = "test"
ctx.Config.Brews[0].GitHub.Name = "test"
ctx.Config.Brews[0].Homepage = "https://github.com/goreleaser"
ctx.Config.Brews[0].DownloadStrategy = "GitHubPrivateRepositoryReleaseDownloadStrategy"
},
"custom_require": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitHub
ctx.Config.GitHubURLs.Download = "https://github.com"
ctx.Config.Release.GitHub.Owner = "test"
ctx.Config.Release.GitHub.Name = "test"
ctx.Config.Brews[0].GitHub.Owner = "test"
ctx.Config.Brews[0].GitHub.Name = "test"
ctx.Config.Brews[0].Homepage = "https://github.com/goreleaser"
ctx.Config.Brews[0].DownloadStrategy = "CustomDownloadStrategy"
ctx.Config.Brews[0].CustomRequire = "custom_download_strategy"
},
"custom_block": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitHub
ctx.Config.GitHubURLs.Download = "https://github.com"
ctx.Config.Release.GitHub.Owner = "test"
ctx.Config.Release.GitHub.Name = "test"
ctx.Config.Brews[0].GitHub.Owner = "test"
ctx.Config.Brews[0].GitHub.Name = "test"
ctx.Config.Brews[0].Homepage = "https://github.com/goreleaser"
ctx.Config.Brews[0].CustomBlock = `head "https://github.com/caarlos0/test.git"`
},
"default_gitlab": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitLab
ctx.Config.GitLabURLs.Download = "https://gitlab.com"
ctx.Config.Release.GitLab.Owner = "test"
ctx.Config.Release.GitLab.Name = "test"
ctx.Config.Brews[0].GitLab.Owner = "test"
ctx.Config.Brews[0].GitLab.Name = "test"
ctx.Config.Brews[0].Homepage = "https://gitlab.com/goreleaser"
},
"gitlab_enterprise_url": func(ctx *context.Context) {
ctx.TokenType = context.TokenTypeGitLab
ctx.Config.GitLabURLs.Download = "https://gitlab.com"
ctx.Config.Release.GitLab.Owner = "test"
ctx.Config.Release.GitLab.Name = "test"
ctx.Config.Brews[0].GitLab.Owner = "test"
ctx.Config.Brews[0].GitLab.Name = "test"
ctx.Config.Brews[0].Homepage = "https://gitlab.com/goreleaser"
ctx.Config.GitLabURLs.Download = "https://gitlab.my-company.org"
},
} {
t.Run(name, func(t *testing.T) {
folder, err := ioutil.TempDir("", "goreleasertest")
@ -139,27 +199,13 @@ func TestRunPipe(t *testing.T) {
Config: config.Project{
Dist: folder,
ProjectName: name,
GitHubURLs: config.GitHubURLs{
Download: "https://github.com",
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
Brews: []config.Homebrew{
{
Name: name,
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
IDs: []string{
"foo",
},
Description: "A run pipe test formula and FOO={{ .Env.FOO }}",
Homepage: "https://github.com/goreleaser",
Caveats: "don't do this {{ .ProjectName }}",
Test: "system \"true\"\nsystem \"#{bin}/foo -h\"",
Plist: `<xml>whatever</xml>`,
@ -178,8 +224,9 @@ func TestRunPipe(t *testing.T) {
Goarch: "amd64",
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "bar",
"Format": "tar.gz",
"ID": "bar",
"Format": "tar.gz",
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
})
var path = filepath.Join(folder, "bin.tar.gz")
@ -190,8 +237,9 @@ func TestRunPipe(t *testing.T) {
Goarch: "amd64",
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "foo",
"Format": "tar.gz",
"ID": "foo",
"Format": "tar.gz",
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
})
@ -219,6 +267,7 @@ func TestRunPipe(t *testing.T) {
func TestRunPipeNoDarwin64Build(t *testing.T) {
var ctx = &context.Context{
TokenType: context.TokenTypeGitHub,
Config: config.Project{
Brews: []config.Homebrew{
{
@ -235,7 +284,7 @@ func TestRunPipeNoDarwin64Build(t *testing.T) {
assert.False(t, client.CreatedFile)
}
func TestRunPipeMultipleDarwin64Build(t *testing.T) {
func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
var ctx = context.New(
config.Project{
Brews: []config.Homebrew{
@ -249,34 +298,50 @@ func TestRunPipeMultipleDarwin64Build(t *testing.T) {
},
)
ctx.TokenType = context.TokenTypeGitHub
f, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer f.Close()
ctx.Artifacts.Add(&artifact.Artifact{
Name: "bin1",
Path: f.Name(),
Goos: "darwin",
Goarch: "amd64",
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "foo",
"Format": "tar.gz",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "bin2",
Path: f.Name(),
Goos: "darwin",
Goarch: "amd64",
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "bar",
"Format": "tar.gz",
},
})
client := &DummyClient{}
assert.Equal(t, ErrMultipleArchivesSameOS, doRun(ctx, ctx.Config.Brews[0], client))
assert.False(t, client.CreatedFile)
osarchs := []struct {
goos string
goarch string
}{
{goos: "darwin", goarch: "amd64"},
{goos: "linux", goarch: "amd64"},
}
for idx, ttt := range osarchs {
t.Run(ttt.goos, func(tt *testing.T) {
ctx.Artifacts.Add(&artifact.Artifact{
Name: fmt.Sprintf("bin%d", idx),
Path: f.Name(),
Goos: ttt.goos,
Goarch: ttt.goarch,
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "foo",
"Format": "tar.gz",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: fmt.Sprintf("bin%d", idx),
Path: f.Name(),
Goos: ttt.goos,
Goarch: ttt.goarch,
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "bar",
"Format": "tar.gz",
},
})
client := &DummyClient{}
assert.Equal(t, ErrMultipleArchivesSameOS, doRun(ctx, ctx.Config.Brews[0], client))
assert.False(t, client.CreatedFile)
// clean the artifacts for the next run
ctx.Artifacts = artifact.New()
})
}
}
func TestRunPipeBrewNotSetup(t *testing.T) {
@ -329,6 +394,7 @@ func TestRunPipeNoUpload(t *testing.T) {
},
},
})
ctx.TokenType = context.TokenTypeGitHub
ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
var path = filepath.Join(folder, "whatever.tar.gz")
_, err = os.Create(path)
@ -380,13 +446,41 @@ func TestRunPipeNoUpload(t *testing.T) {
}
assertNoPublish(tt)
})
t.Run("skip publish because not a github release", func(tt *testing.T) {
ctx.Config.Release.Draft = false
ctx.Config.Brew.SkipUpload = "false"
ctx.SkipPublish = false
ctx.TokenType = context.TokenTypeGitLab
assertNoPublish(tt)
}
func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
folder, err := ioutil.TempDir("", "goreleasertest")
assert.NoError(t, err)
var ctx = context.New(config.Project{
Dist: folder,
ProjectName: "foo",
Release: config.Release{},
Brews: []config.Homebrew{
{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
},
})
ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
var path = filepath.Join(folder, "whatever.tar.gz")
_, err = os.Create(path)
assert.NoError(t, err)
ctx.Artifacts.Add(&artifact.Artifact{
Name: "bin",
Path: path,
Goos: "darwin",
Goarch: "amd64",
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
"ID": "foo",
"Format": "tar.gz",
},
})
client := &DummyClient{}
assert.Equal(t, ErrTokenTypeNotImplementedForBrew, doRun(ctx, ctx.Config.Brews[0], client))
}
func TestDefault(t *testing.T) {
@ -394,6 +488,7 @@ func TestDefault(t *testing.T) {
defer back()
var ctx = &context.Context{
TokenType: context.TokenTypeGitHub,
Config: config.Project{
ProjectName: "myproject",
Brews: []config.Homebrew{},
@ -427,8 +522,8 @@ func TestDefault(t *testing.T) {
}
func TestGHFolder(t *testing.T) {
assert.Equal(t, "bar.rb", ghFormulaPath("", "bar.rb"))
assert.Equal(t, "fooo/bar.rb", ghFormulaPath("fooo", "bar.rb"))
assert.Equal(t, "bar.rb", buildFormulaPath("", "bar.rb"))
assert.Equal(t, "fooo/bar.rb", buildFormulaPath("fooo", "bar.rb"))
}
type DummyClient struct {
@ -446,6 +541,6 @@ func (client *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.
return
}
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, name string, file *os.File) (err error) {
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error) {
return
}

View File

@ -0,0 +1,40 @@
# This file was generated by GoReleaser. DO NOT EDIT.
class DefaultGitlab < Formula
desc "A run pipe test formula and FOO=foo_is_bar"
homepage "https://gitlab.com/goreleaser"
version "1.0.1"
bottle :unneeded
if OS.mac?
url "https://gitlab.com/test/test/uploads/820ead5d9d2266c728dce6d4d55b6460/bin.tar.gz"
sha256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
elsif OS.linux?
end
depends_on "zsh"
depends_on "bash"
conflicts_with "gtk+"
conflicts_with "qt"
def install
bin.install "default_gitlab"
end
def caveats; <<~EOS
don't do this default_gitlab
EOS
end
plist_options :startup => false
def plist; <<~EOS
<xml>whatever</xml>
EOS
end
test do
system "true"
system "#{bin}/foo -h"
end
end

View File

@ -0,0 +1,40 @@
# This file was generated by GoReleaser. DO NOT EDIT.
class GitlabEnterpriseUrl < Formula
desc "A run pipe test formula and FOO=foo_is_bar"
homepage "https://gitlab.com/goreleaser"
version "1.0.1"
bottle :unneeded
if OS.mac?
url "https://gitlab.my-company.org/test/test/uploads/820ead5d9d2266c728dce6d4d55b6460/bin.tar.gz"
sha256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
elsif OS.linux?
end
depends_on "zsh"
depends_on "bash"
conflicts_with "gtk+"
conflicts_with "qt"
def install
bin.install "gitlab_enterprise_url"
end
def caveats; <<~EOS
don't do this gitlab_enterprise_url
EOS
end
plist_options :startup => false
def plist; <<~EOS
<xml>whatever</xml>
EOS
end
test do
system "true"
system "#{bin}/foo -h"
end
end

View File

@ -21,7 +21,8 @@ func TestFillBasicData(t *testing.T) {
testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git")
var ctx = &context.Context{
Config: config.Project{},
TokenType: context.TokenTypeGitHub,
Config: config.Project{},
}
assert.NoError(t, Pipe{}.Run(ctx))

View File

@ -142,5 +142,5 @@ func upload(ctx *context.Context, client client.Client, releaseID string, artifa
}
defer file.Close() // nolint: errcheck
log.WithField("file", file.Name()).WithField("name", artifact.Name).Info("uploading to release")
return client.Upload(ctx, releaseID, artifact.Name, file)
return client.Upload(ctx, releaseID, artifact, file)
}

View File

@ -374,7 +374,7 @@ func (client *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.
return
}
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, name string, file *os.File) error {
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) error {
client.Lock.Lock()
defer client.Lock.Unlock()
// ensure file is read to better mimic real behavior
@ -390,6 +390,6 @@ func (client *DummyClient) Upload(ctx *context.Context, releaseID string, name s
return errors.New("upload failed, should retry")
}
client.UploadedFile = true
client.UploadedFileNames = append(client.UploadedFileNames, name)
client.UploadedFileNames = append(client.UploadedFileNames, artifact.Name)
return nil
}

View File

@ -17,6 +17,9 @@ import (
// ErrNoWindows when there is no build for windows (goos doesn't contain windows)
var ErrNoWindows = errors.New("scoop requires a windows build")
// ErrTokenTypeNotImplementedForScoop indicates that a new token type was not implemented for this pipe
var ErrTokenTypeNotImplementedForScoop = errors.New("token type not implemented for scoop pipe")
// Pipe for build
type Pipe struct{}
@ -44,14 +47,7 @@ func (Pipe) Default(ctx *context.Context) error {
if ctx.Config.Scoop.CommitAuthor.Email == "" {
ctx.Config.Scoop.CommitAuthor.Email = "goreleaser@carlosbecker.com"
}
if ctx.Config.Scoop.URLTemplate == "" {
ctx.Config.Scoop.URLTemplate = fmt.Sprintf(
"%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}",
ctx.Config.GitHubURLs.Download,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
)
}
return nil
}
@ -59,12 +55,12 @@ func doRun(ctx *context.Context, client client.Client) error {
if ctx.Config.Scoop.Bucket.Name == "" {
return pipe.Skip("scoop section is not configured")
}
// If we'd use 'ctx.TokenType != context.TokenTypeGitHub' we'd have to adapt all the tests
// For simplicity we use this check because the functionality will be implemented later for
// all types of releases. See https://github.com/goreleaser/goreleaser/pull/1038#issuecomment-498891464
if ctx.TokenType == context.TokenTypeGitLab {
return pipe.Skip("scoop pipe is only configured for github releases")
}
// TODO mavogel: in another PR
// check if release pipe is not configured!
// if ctx.Config.Release.Disable {
// }
if ctx.Config.Archive.Format == "binary" {
return pipe.Skip("archive format is binary")
}
@ -131,6 +127,27 @@ func buildManifest(ctx *context.Context, artifacts []*artifact.Artifact) (bytes.
Persist: ctx.Config.Scoop.Persist,
}
if ctx.Config.Scoop.URLTemplate == "" {
switch ctx.TokenType {
case context.TokenTypeGitHub:
ctx.Config.Scoop.URLTemplate = fmt.Sprintf(
"%s/%s/%s/releases/download/{{ .Tag }}/{{ .ArtifactName }}",
ctx.Config.GitHubURLs.Download,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
)
case context.TokenTypeGitLab:
ctx.Config.Scoop.URLTemplate = fmt.Sprintf(
"%s/%s/%s/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}",
ctx.Config.GitLabURLs.Download,
ctx.Config.Release.GitLab.Owner,
ctx.Config.Release.GitLab.Name,
)
default:
return result, ErrTokenTypeNotImplementedForScoop
}
}
for _, artifact := range artifacts {
var arch = "64bit"
if artifact.Goarch == "386" {

View File

@ -28,6 +28,7 @@ func TestDefault(t *testing.T) {
defer back()
var ctx = &context.Context{
TokenType: context.TokenTypeGitHub,
Config: config.Project{
ProjectName: "barr",
Builds: []config.Build{
@ -85,9 +86,10 @@ func Test_doRun(t *testing.T) {
assertError errChecker
}{
{
"valid",
"valid public github",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -127,9 +129,10 @@ func Test_doRun(t *testing.T) {
shouldNotErr,
},
{
"valid",
"valid enterprise github",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -169,10 +172,172 @@ func Test_doRun(t *testing.T) {
},
shouldNotErr,
},
{
"valid public gitlab",
args{
&context.Context{
TokenType: context.TokenTypeGitLab,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
Version: "1.0.1",
Artifacts: artifact.New(),
Config: config.Project{
Builds: []config.Build{
{Binary: "test", Goarch: []string{"amd64"}, Goos: []string{"windows"}},
},
Dist: ".",
ProjectName: "run-pipe",
Archive: config.Archive{
Format: "tar.gz",
},
Release: config.Release{
GitLab: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.Repo{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://gitlab.com/goreleaser",
},
},
},
&DummyClient{},
},
[]*artifact.Artifact{
{
Name: "foo_1.0.1_windows_amd64.tar.gz",
Goos: "windows",
Goarch: "amd64",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
},
{
Name: "foo_1.0.1_windows_386.tar.gz",
Goos: "windows",
Goarch: "386",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
},
},
shouldNotErr,
},
{
"valid enterprise gitlab",
args{
&context.Context{
TokenType: context.TokenTypeGitLab,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
Version: "1.0.1",
Artifacts: artifact.New(),
Config: config.Project{
GitHubURLs: config.GitHubURLs{Download: "https://api.custom.gitlab.enterprise.com"},
Builds: []config.Build{
{Binary: "test", Goarch: []string{"amd64"}, Goos: []string{"windows"}},
},
Dist: ".",
ProjectName: "run-pipe",
Archive: config.Archive{
Format: "tar.gz",
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.Repo{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://gitlab.com/goreleaser",
},
},
},
&DummyClient{},
},
[]*artifact.Artifact{
{
Name: "foo_1.0.1_windows_amd64.tar.gz",
Goos: "windows",
Goarch: "amd64",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
},
{
Name: "foo_1.0.1_windows_386.tar.gz",
Goos: "windows",
Goarch: "386",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
},
},
},
shouldNotErr,
},
{
"token type not implemented for pipe",
args{
&context.Context{
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
Version: "1.0.1",
Artifacts: artifact.New(),
Config: config.Project{
Builds: []config.Build{
{Binary: "test", Goarch: []string{"amd64"}, Goos: []string{"windows"}},
},
Dist: ".",
ProjectName: "run-pipe",
Archive: config.Archive{
Format: "tar.gz",
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.Repo{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://github.com/goreleaser",
},
},
},
&DummyClient{},
},
[]*artifact.Artifact{
{Name: "foo_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Path: file},
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldErr(ErrTokenTypeNotImplementedForScoop.Error()),
},
{
"no windows build",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -215,6 +380,7 @@ func Test_doRun(t *testing.T) {
"no scoop",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -249,6 +415,7 @@ func Test_doRun(t *testing.T) {
"no publish",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -292,6 +459,7 @@ func Test_doRun(t *testing.T) {
"is draft",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -331,6 +499,7 @@ func Test_doRun(t *testing.T) {
"no archive",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -360,54 +529,11 @@ func Test_doRun(t *testing.T) {
},
&DummyClient{},
},
[]*artifact.Artifact{
{Name: "foo_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64"},
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386"},
},
shouldErr("archive format is binary"),
},
{
"valid but non github release",
args{
&context.Context{
TokenType: context.TokenTypeGitLab,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
Version: "1.0.1",
Artifacts: artifact.New(),
Config: config.Project{
Builds: []config.Build{
{Binary: "test", Goarch: []string{"amd64"}, Goos: []string{"windows"}},
},
Dist: ".",
ProjectName: "run-pipe",
Archive: config.Archive{
Format: "tar.gz",
},
Release: config.Release{
GitLab: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.Repo{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://github.com/goreleaser",
},
},
},
&DummyClient{},
},
[]*artifact.Artifact{
{Name: "foo_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Path: file},
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldErr("scoop pipe is only configured for github releases"),
shouldErr("archive format is binary"),
},
}
for _, tt := range tests {
@ -435,6 +561,7 @@ func Test_buildManifest(t *testing.T) {
{
"testdata/test_buildmanifest.json.golden",
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -470,6 +597,7 @@ func Test_buildManifest(t *testing.T) {
{
"testdata/test_buildmanifest_url_template.json.golden",
&context.Context{
TokenType: context.TokenTypeGitHub,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
@ -506,6 +634,46 @@ func Test_buildManifest(t *testing.T) {
},
},
},
{
"testdata/test_buildmanifest_gitlab_url_template.json.golden",
&context.Context{
TokenType: context.TokenTypeGitLab,
Git: context.GitInfo{
CurrentTag: "v1.0.1",
},
Version: "1.0.1",
Artifacts: artifact.New(),
Config: config.Project{
GitLabURLs: config.GitLabURLs{
Download: "https://gitlab.com",
},
Builds: []config.Build{
{Binary: "test"},
},
Dist: ".",
ProjectName: "run-pipe",
Archive: config.Archive{
Format: "tar.gz",
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.Repo{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://gitlab.com/goreleaser",
URLTemplate: "http://gitlab.mycompany.com/foo/bar/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}",
Persist: []string{"data.cfg", "etc"},
},
},
},
},
}
for _, tt := range tests {
@ -520,6 +688,7 @@ func Test_buildManifest(t *testing.T) {
Goarch: "amd64",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
"Builds": []*artifact.Artifact{
{
Extra: map[string]interface{}{
@ -540,6 +709,7 @@ func Test_buildManifest(t *testing.T) {
Goarch: "386",
Path: file,
Extra: map[string]interface{}{
"ArtifactUploadHash": "820ead5d9d2266c728dce6d4d55b6460",
"Builds": []*artifact.Artifact{
{
Extra: map[string]interface{}{
@ -583,6 +753,6 @@ func (client *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.
return
}
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, name string, file *os.File) (err error) {
func (client *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error) {
return
}

View File

@ -0,0 +1,27 @@
{
"version": "1.0.1",
"architecture": {
"32bit": {
"url": "http://gitlab.mycompany.com/foo/bar/uploads/820ead5d9d2266c728dce6d4d55b6460/foo_1.0.1_windows_386.tar.gz",
"bin": [
"foo.exe",
"bar.exe"
],
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
},
"64bit": {
"url": "http://gitlab.mycompany.com/foo/bar/uploads/820ead5d9d2266c728dce6d4d55b6460/foo_1.0.1_windows_amd64.tar.gz",
"bin": [
"foo.exe",
"bar.exe"
],
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
}
},
"homepage": "https://gitlab.com/goreleaser",
"description": "A run pipe test formula",
"persist": [
"data.cfg",
"etc"
]
}

View File

@ -40,6 +40,8 @@ const (
arm = "Arm"
binary = "Binary"
artifactName = "ArtifactName"
// gitlab only
artifactUploadHash = "ArtifactUploadHash"
)
// New Template
@ -92,6 +94,11 @@ func (t *Template) WithArtifact(a *artifact.Artifact, replacements map[string]st
t.fields[arm] = replace(replacements, a.Goarm)
t.fields[binary] = bin.(string)
t.fields[artifactName] = a.Name
if val, ok := a.Extra["ArtifactUploadHash"]; ok {
t.fields[artifactUploadHash] = val
} else {
t.fields[artifactUploadHash] = ""
}
return t
}

View File

@ -39,6 +39,7 @@ func TestWithArtifact(t *testing.T) {
"shortcommit": "{{.ShortCommit}}",
"binary": "{{.Binary}}",
"proj": "{{.ProjectName}}",
"": "{{.ArtifactUploadHash}}",
} {
tmpl := tmpl
expect := expect
@ -61,6 +62,24 @@ func TestWithArtifact(t *testing.T) {
})
}
t.Run("artifact with gitlab ArtifactUploadHash", func(tt *testing.T) {
tt.Parallel()
uploadHash := "820ead5d9d2266c728dce6d4d55b6460"
result, err := New(ctx).WithArtifact(
&artifact.Artifact{
Name: "another-binary",
Goarch: "amd64",
Goos: "linux",
Goarm: "6",
Extra: map[string]interface{}{
"ArtifactUploadHash": uploadHash,
},
}, map[string]string{},
).Apply("{{ .ArtifactUploadHash }}")
assert.NoError(tt, err)
assert.Equal(tt, uploadHash, result)
})
t.Run("artifact without binary name", func(tt *testing.T) {
tt.Parallel()
result, err := New(ctx).WithArtifact(

View File

@ -45,6 +45,7 @@ func (r Repo) String() string {
type Homebrew struct {
Name string `yaml:",omitempty"`
GitHub Repo `yaml:",omitempty"`
GitLab Repo `yaml:",omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
Folder string `yaml:",omitempty"`
Caveats string `yaml:",omitempty"`

View File

@ -38,14 +38,14 @@ func (e Env) Strings() []string {
return result
}
// tokenType is either github or gitlab
type tokenType string
// TokenType is either github or gitlab
type TokenType string
const (
// TokenTypeGitHub defines github as type of the token
TokenTypeGitHub tokenType = "github"
TokenTypeGitHub TokenType = "github"
// TokenTypeGitLab defines gitlab as type of the token
TokenTypeGitLab tokenType = "gitlab"
TokenTypeGitLab TokenType = "gitlab"
)
// Context carries along some data through the pipes
@ -54,7 +54,7 @@ type Context struct {
Config config.Project
Env Env
Token string
TokenType tokenType
TokenType TokenType
Git GitInfo
Artifacts artifact.Artifacts
ReleaseNotes string

View File

@ -5,7 +5,7 @@ hideFromIndex: true
weight: 90
---
After releasing to GitHub (GitLab is not supported yet), GoReleaser can generate and publish a _homebrew-tap_
After releasing to GitHub or GitLab, GoReleaser can generate and publish a _homebrew-tap_
recipe into a repository that you have access to.
The `brew` section specifies how the formula should be created.
@ -29,13 +29,23 @@ brews:
- foo
- bar
# Repository to push the tap to.
# NOTE: make sure the url_template, the token and given repo (github or gitlab) owner and name are from the
# same kind. We will probably unify this in the next major version like it is done with scoop.
# Github repository to push the tap to.
github:
owner: user
owner: github-user
name: homebrew-tap
# Template for the url.
# Default is "https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# OR Gitlab
# gitlab:
# owner: gitlab-user
# name: homebrew-tap
# Template for the url which is determined by the given Token (github or gitlab)
# Default for github is "https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Default for gitlab is "https://gitlab.com/<repo_owner>/<repo_name>/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}"
url_template: "http://github.mycompany.com/foo/bar/releases/{{ .Tag }}/{{ .ArtifactName }}"
# Allows you to set a custom download strategy.

View File

@ -5,7 +5,7 @@ hideFromIndex: true
weight: 100
---
After releasing to GitHub (GitLab is not supported yet), GoReleaser can generate and publish a
After releasing to GitHub or GitLab, GoReleaser can generate and publish a
_Scoop App Manifest_ into a repository that you have access to.
The `scoop` section specifies how the manifest should be created. See
@ -14,8 +14,9 @@ the commented example bellow:
```yml
# .goreleaser.yml
scoop:
# Template for the url.
# Default is "https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Template for the url which is determined by the given Token (github or gitlab)
# Default for github is "https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# Default for gitlab is "https://gitlab.com/<repo_owner>/<repo_name>/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}"
url_template: "http://github.mycompany.com/foo/bar/releases/{{ .Tag }}/{{ .ArtifactName }}"
# Repository to push the app manifest to.