1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-07-03 00:57:43 +02:00

feat: improve skip-publish behavior (#1474)

* Revert "feat: split brew tap in 2 steps (#1425)"

This reverts commit 5e8882fbb6.

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: brew generation

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: improve bucket write

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: tests

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: tests

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: minio test

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: lint issues

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: lint issues

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: err handling

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
Carlos Alexandro Becker
2020-04-29 15:09:00 -03:00
committed by GitHub
parent 705ab90e4f
commit 15fd80eded
13 changed files with 271 additions and 221 deletions

View File

@ -29,8 +29,6 @@ const (
UploadableBinary UploadableBinary
// UploadableFile is any file that can be uploaded // UploadableFile is any file that can be uploaded
UploadableFile UploadableFile
// UploadableBrewTap is a .rb file that can be uploaded
UploadableBrewTap
// Binary is a binary (output of a gobuild) // Binary is a binary (output of a gobuild)
Binary Binary
// LinuxPackage is a linux package generated by nfpm // LinuxPackage is a linux package generated by nfpm
@ -60,8 +58,6 @@ func (t Type) String() string {
case UploadableBinary: case UploadableBinary:
case Binary: case Binary:
return "Binary" return "Binary"
case UploadableBrewTap:
return "Brew Tap"
case LinuxPackage: case LinuxPackage:
return "Linux Package" return "Linux Package"
case DockerImage: case DockerImage:

View File

@ -37,13 +37,16 @@ func (Pipe) Publish(ctx *context.Context) error {
if len(ctx.Config.Blobs) == 0 { if len(ctx.Config.Blobs) == 0 {
return pipe.Skip("Blob section is not configured") return pipe.Skip("Blob section is not configured")
} }
// Openning connection to the list of buckets var up uploader = productionUploader{}
o := newOpenBucket() if ctx.SkipPublish {
up = skipUploader{}
}
var g = semerrgroup.New(ctx.Parallelism) var g = semerrgroup.New(ctx.Parallelism)
for _, conf := range ctx.Config.Blobs { for _, conf := range ctx.Config.Blobs {
conf := conf conf := conf
g.Go(func() error { g.Go(func() error {
return o.Upload(ctx, conf) return doUpload(ctx, conf, up)
}) })
} }
return g.Wait() return g.Wait()

View File

@ -5,6 +5,7 @@ package blob
// the test setup and teardown // the test setup and teardown
import ( import (
"io"
"io/ioutil" "io/ioutil"
"net" "net"
"os" "os"
@ -19,6 +20,7 @@ import (
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gocloud.dev/blob"
) )
func TestMinioUpload(t *testing.T) { func TestMinioUpload(t *testing.T) {
@ -153,7 +155,7 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) {
}, },
}, },
}) })
ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} ctx.Git = context.GitInfo{CurrentTag: "v1.1.0"}
ctx.Artifacts.Add(&artifact.Artifact{ ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.UploadableArchive, Type: artifact.UploadableArchive,
Name: "bin.tar.gz", Name: "bin.tar.gz",
@ -172,6 +174,77 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) {
assert.Error(t, Pipe{}.Publish(ctx)) assert.Error(t, Pipe{}.Publish(ctx))
} }
func TestMinioUploadSkipPublish(t *testing.T) {
var listen = randomListen(t)
folder, err := ioutil.TempDir("", "goreleasertest")
assert.NoError(t, err)
srcpath := filepath.Join(folder, "source.tar.gz")
tgzpath := filepath.Join(folder, "bin.tar.gz")
debpath := filepath.Join(folder, "bin.deb")
checkpath := filepath.Join(folder, "check.txt")
assert.NoError(t, ioutil.WriteFile(checkpath, []byte("fake checksums"), 0744))
assert.NoError(t, ioutil.WriteFile(srcpath, []byte("fake\nsrc"), 0744))
assert.NoError(t, ioutil.WriteFile(tgzpath, []byte("fake\ntargz"), 0744))
assert.NoError(t, ioutil.WriteFile(debpath, []byte("fake\ndeb"), 0744))
var ctx = context.New(config.Project{
Dist: folder,
ProjectName: "testupload",
Blobs: []config.Blob{
{
Provider: "s3",
Bucket: "test",
Region: "us-east",
Endpoint: "http://" + listen,
IDs: []string{"foo", "bar"},
},
},
})
ctx.SkipPublish = true
ctx.Git = context.GitInfo{CurrentTag: "v1.2.0"}
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.Checksum,
Name: "checksum.txt",
Path: checkpath,
})
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.UploadableSourceArchive,
Name: "source.tar.gz",
Path: srcpath,
Extra: map[string]interface{}{
"Format": "tar.gz",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.UploadableArchive,
Name: "bin.tar.gz",
Path: tgzpath,
Extra: map[string]interface{}{
"ID": "foo",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.LinuxPackage,
Name: "bin.deb",
Path: debpath,
Extra: map[string]interface{}{
"ID": "bar",
},
})
var name = "test_upload"
defer stop(t, name)
start(t, name, listen)
prepareEnv(t, listen)
assert.NoError(t, Pipe{}.Default(ctx))
assert.NoError(t, Pipe{}.Publish(ctx))
require.NotContains(t, getFiles(t, ctx, ctx.Config.Blobs[0]), []string{
"testupload/v1.2.0/bin.deb",
"testupload/v1.2.0/bin.tar.gz",
"testupload/v1.2.0/checksum.txt",
"testupload/v1.2.0/source.tar.gz",
})
}
func randomListen(t *testing.T) string { func randomListen(t *testing.T) string {
listener, err := net.Listen("tcp", "127.0.0.1:0") listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err) require.NoError(t, err)
@ -229,19 +302,20 @@ func removeTestData(t *testing.T) {
_ = os.RemoveAll("./testdata/data/test/testupload") // dont care if it fails _ = os.RemoveAll("./testdata/data/test/testupload") // dont care if it fails
} }
func getFiles(t *testing.T, ctx *context.Context, blob config.Blob) []string { func getFiles(t *testing.T, ctx *context.Context, cfg config.Blob) []string {
var bucket = Bucket{} url, err := urlFor(ctx, cfg)
url, err := bucket.url(ctx, blob)
require.NoError(t, err) require.NoError(t, err)
conn, err := bucket.Connect(ctx, url) conn, err := blob.OpenBucket(ctx, url)
require.NoError(t, err) require.NoError(t, err)
defer conn.Close()
var iter = conn.List(nil) var iter = conn.List(nil)
var files []string var files []string
for { for {
file, err := iter.Next(ctx) file, err := iter.Next(ctx)
if err != nil { if err != nil && err == io.EOF {
break break
} }
require.NoError(t, err)
files = append(files, file.Key) files = append(files, file.Key)
} }
return files return files

View File

@ -240,10 +240,8 @@ func TestPipe_Publish(t *testing.T) {
} }
func TestURL(t *testing.T) { func TestURL(t *testing.T) {
var buck = Bucket{}
t.Run("s3 with opts", func(t *testing.T) { t.Run("s3 with opts", func(t *testing.T) {
url, err := buck.url(context.New(config.Project{}), config.Blob{ url, err := urlFor(context.New(config.Project{}), config.Blob{
Bucket: "foo", Bucket: "foo",
Provider: "s3", Provider: "s3",
Region: "us-west-1", Region: "us-west-1",
@ -256,7 +254,7 @@ func TestURL(t *testing.T) {
}) })
t.Run("s3 with some opts", func(t *testing.T) { t.Run("s3 with some opts", func(t *testing.T) {
url, err := buck.url(context.New(config.Project{}), config.Blob{ url, err := urlFor(context.New(config.Project{}), config.Blob{
Bucket: "foo", Bucket: "foo",
Provider: "s3", Provider: "s3",
Region: "us-west-1", Region: "us-west-1",
@ -267,7 +265,7 @@ func TestURL(t *testing.T) {
}) })
t.Run("gs with opts", func(t *testing.T) { t.Run("gs with opts", func(t *testing.T) {
url, err := buck.url(context.New(config.Project{}), config.Blob{ url, err := urlFor(context.New(config.Project{}), config.Blob{
Bucket: "foo", Bucket: "foo",
Provider: "gs", Provider: "gs",
Region: "us-west-1", Region: "us-west-1",
@ -280,7 +278,7 @@ func TestURL(t *testing.T) {
}) })
t.Run("s3 no opts", func(t *testing.T) { t.Run("s3 no opts", func(t *testing.T) {
url, err := buck.url(context.New(config.Project{}), config.Blob{ url, err := urlFor(context.New(config.Project{}), config.Blob{
Bucket: "foo", Bucket: "foo",
Provider: "s3", Provider: "s3",
}) })
@ -289,7 +287,7 @@ func TestURL(t *testing.T) {
}) })
t.Run("gs no opts", func(t *testing.T) { t.Run("gs no opts", func(t *testing.T) {
url, err := buck.url(context.New(config.Project{}), config.Blob{ url, err := urlFor(context.New(config.Project{}), config.Blob{
Bucket: "foo", Bucket: "foo",
Provider: "gs", Provider: "gs",
}) })

View File

@ -27,32 +27,7 @@ import (
_ "gocloud.dev/secrets/gcpkms" _ "gocloud.dev/secrets/gcpkms"
) )
// OpenBucket is the interface that wraps the BucketConnect and UploadBucket method func urlFor(ctx *context.Context, conf config.Blob) (string, error) {
type OpenBucket interface {
Connect(ctx *context.Context, bucketURL string) (*blob.Bucket, error)
Upload(ctx *context.Context, conf config.Blob) error
}
// Bucket is object which holds connection for Go Bucker Provider
type Bucket struct {
BucketConn *blob.Bucket
}
// returns openbucket connection for list of providers
func newOpenBucket() OpenBucket {
return Bucket{}
}
// Connect makes connection with provider
func (b Bucket) Connect(ctx *context.Context, bucketURL string) (*blob.Bucket, error) {
conn, err := blob.OpenBucket(ctx, bucketURL)
if err != nil {
return nil, err
}
return conn, nil
}
func (b Bucket) url(ctx *context.Context, conf config.Blob) (string, error) {
bucket, err := tmpl.New(ctx).Apply(conf.Bucket) bucket, err := tmpl.New(ctx).Apply(conf.Bucket)
if err != nil { if err != nil {
return "", err return "", err
@ -83,26 +58,20 @@ func (b Bucket) url(ctx *context.Context, conf config.Blob) (string, error) {
return bucketURL, nil return bucketURL, nil
} }
// Upload takes connection initilized from newOpenBucket to upload goreleaser artifacts // Takes goreleaser context(which includes artificats) and bucketURL for
// Takes goreleaser context(which includes artificats) and bucketURL for upload destination (gs://gorelease-bucket) // upload to destination (eg: gs://gorelease-bucket) using the given uploader
func (b Bucket) Upload(ctx *context.Context, conf config.Blob) error { // implementation
func doUpload(ctx *context.Context, conf config.Blob, up uploader) error {
folder, err := tmpl.New(ctx).Apply(conf.Folder) folder, err := tmpl.New(ctx).Apply(conf.Folder)
if err != nil { if err != nil {
return err return err
} }
bucketURL, err := b.url(ctx, conf) bucketURL, err := urlFor(ctx, conf)
if err != nil { if err != nil {
return err return err
} }
// Get the openbucket connection for specific provider
conn, err := b.Connect(ctx, bucketURL)
if err != nil {
return err
}
defer conn.Close()
var filter = artifact.Or( var filter = artifact.Or(
artifact.ByType(artifact.UploadableArchive), artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary), artifact.ByType(artifact.UploadableBinary),
@ -119,34 +88,18 @@ func (b Bucket) Upload(ctx *context.Context, conf config.Blob) error {
for _, artifact := range ctx.Artifacts.Filter(filter).List() { for _, artifact := range ctx.Artifacts.Filter(filter).List() {
artifact := artifact artifact := artifact
g.Go(func() error { g.Go(func() error {
log.WithFields(log.Fields{
"provider": bucketURL,
"folder": folder,
"artifact": artifact.Name,
}).Info("uploading")
// TODO: replace this with ?prefix=folder on the bucket url // TODO: replace this with ?prefix=folder on the bucket url
w, err := conn.NewWriter(ctx, filepath.Join(folder, artifact.Name), nil)
if err != nil {
return errors.Wrap(err, "failed to obtain writer")
}
data, err := getData(ctx, conf, artifact.Path) data, err := getData(ctx, conf, artifact.Path)
if err != nil { if err != nil {
return err return err
} }
_, err = w.Write(data)
if err != nil { if err := up.Upload(ctx, bucketURL, filepath.Join(folder, artifact.Name), data); err != nil {
switch { switch {
case errorContains(err, "NoSuchBucket", "ContainerNotFound", "notFound"): case errorContains(err, "NoSuchBucket", "ContainerNotFound", "notFound"):
return errors.Wrapf(err, "provided bucket does not exist: %s", bucketURL) return errors.Wrapf(err, "provided bucket does not exist: %s", bucketURL)
case errorContains(err, "NoCredentialProviders"): case errorContains(err, "NoCredentialProviders"):
return errors.Wrapf(err, "check credentials and access to bucket: %s", bucketURL) return errors.Wrapf(err, "check credentials and access to bucket: %s", bucketURL)
default:
return errors.Wrapf(err, "failed to write to bucket")
}
}
if err = w.Close(); err != nil {
switch {
case errorContains(err, "InvalidAccessKeyId"): case errorContains(err, "InvalidAccessKeyId"):
return errors.Wrap(err, "aws access key id you provided does not exist in our records") return errors.Wrap(err, "aws access key id you provided does not exist in our records")
case errorContains(err, "AuthenticationFailed"): case errorContains(err, "AuthenticationFailed"):
@ -155,14 +108,10 @@ func (b Bucket) Upload(ctx *context.Context, conf config.Blob) error {
return errors.Wrap(err, "google app credentials you provided is not valid") return errors.Wrap(err, "google app credentials you provided is not valid")
case errorContains(err, "no such host"): case errorContains(err, "no such host"):
return errors.Wrap(err, "azure storage account you provided is not valid") return errors.Wrap(err, "azure storage account you provided is not valid")
case errorContains(err, "NoSuchBucket", "ContainerNotFound", "notFound"):
return errors.Wrapf(err, "provided bucket does not exist: %s", bucketURL)
case errorContains(err, "NoCredentialProviders"):
return errors.Wrapf(err, "check credentials and access to bucket %s", bucketURL)
case errorContains(err, "ServiceCode=ResourceNotFound"): case errorContains(err, "ServiceCode=ResourceNotFound"):
return errors.Wrapf(err, "missing azure storage key for provided bucket %s", bucketURL) return errors.Wrapf(err, "missing azure storage key for provided bucket %s", bucketURL)
default: default:
return errors.Wrap(err, "failed to close Bucket writer") return errors.Wrap(err, "failed to write to bucket")
} }
} }
return err return err
@ -190,3 +139,52 @@ func getData(ctx *context.Context, conf config.Blob, path string) ([]byte, error
} }
return data, err return data, err
} }
// uploader implements upload
type uploader interface {
Upload(ctx *context.Context, url, path string, data []byte) error
}
// skipUploader is used when --skip-upload is set and will just log
// things without really doing anything
type skipUploader struct{}
func (u skipUploader) Upload(_ *context.Context, url, path string, _ []byte) error {
log.WithFields(log.Fields{
"bucket": url,
"path": path,
}).Warn("doUpload skipped because skip-publish is set")
return nil
}
// productionUploader actually do upload to
type productionUploader struct{}
func (u productionUploader) Upload(ctx *context.Context, url, path string, data []byte) (err error) {
log.WithFields(log.Fields{
"bucket": url,
"path": path,
}).Info("uploading")
// TODO: its not so great that we open one connection for each file
conn, err := blob.OpenBucket(ctx, url)
if err != nil {
return err
}
defer func() {
if cerr := conn.Close(); err == nil {
err = cerr
}
}()
w, err := conn.NewWriter(ctx, path, nil)
if err != nil {
return err
}
defer func() {
if cerr := w.Close(); err == nil {
err = cerr
}
}()
_, err = w.Write(data)
return
}

View File

@ -36,64 +36,14 @@ func (Pipe) String() string {
return "homebrew tap formula" return "homebrew tap formula"
} }
func (Pipe) Run(ctx *context.Context) error {
for _, brew := range ctx.Config.Brews {
if err := doRun(ctx, brew); err != nil {
return err
}
}
return nil
}
// Publish brew formula // Publish brew formula
func (Pipe) Publish(ctx *context.Context) error { func (Pipe) Publish(ctx *context.Context) error {
client, err := client.New(ctx) client, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }
for _, brew := range ctx.Config.Brews {
return doPublish(ctx, client) if err := doRun(ctx, brew, client); err != nil {
}
func doPublish(ctx *context.Context, client client.Client) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
var taps = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBrewTap)).List()
if len(taps) == 0 {
return pipe.Skip("no brew taps found")
}
for _, tap := range taps {
brew := tap.Extra["config"].(config.Homebrew)
if strings.TrimSpace(brew.SkipUpload) == "true" {
return pipe.Skip("brew.skip_upload is set")
}
if strings.TrimSpace(brew.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
return pipe.Skip("prerelease detected with 'auto' upload, skipping homebrew publish")
}
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, tap.Name)
log.WithField("formula", gpath).
WithField("repo", repo.String()).
Info("pushing")
content, err := ioutil.ReadFile(tap.Path)
if err != nil {
return errors.Wrap(err, "failed to read tap")
}
var msg = fmt.Sprintf("Brew formula update for %s version %s", ctx.Config.ProjectName, ctx.Git.CurrentTag)
if err := client.CreateFile(ctx, brew.CommitAuthor, repo, content, gpath, msg); err != nil {
return err return err
} }
} }
@ -155,7 +105,7 @@ func contains(ss []string, s string) bool {
return false return false
} }
func doRun(ctx *context.Context, brew config.Homebrew) error { func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) error {
if brew.GitHub.Name == "" && brew.GitLab.Name == "" { if brew.GitHub.Name == "" && brew.GitLab.Name == "" {
return pipe.Skip("brew section is not configured") return pipe.Skip("brew section is not configured")
} }
@ -198,16 +148,33 @@ func doRun(ctx *context.Context, brew config.Homebrew) error {
return errors.Wrap(err, "failed to write brew tap") return errors.Wrap(err, "failed to write brew tap")
} }
ctx.Artifacts.Add(&artifact.Artifact{ if strings.TrimSpace(brew.SkipUpload) == "true" {
Name: filename, return pipe.Skip("brew.skip_upload is set")
Path: path, }
Type: artifact.UploadableBrewTap, if ctx.SkipPublish {
Extra: map[string]interface{}{ return pipe.ErrSkipPublishEnabled
"config": brew, }
}, if strings.TrimSpace(brew.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
}) return pipe.Skip("prerelease detected with 'auto' upload, skipping homebrew publish")
}
return nil 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", 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, repo, []byte(content), gpath, msg)
} }
func buildFormulaPath(folder, filename string) string { func buildFormulaPath(folder, filename string) string {
@ -259,6 +226,13 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenT
if cfg.URLTemplate == "" { if cfg.URLTemplate == "" {
switch tokenType { 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: case context.TokenTypeGitLab:
cfg.URLTemplate = fmt.Sprintf( cfg.URLTemplate = fmt.Sprintf(
"%s/%s/%s/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}", "%s/%s/%s/uploads/{{ .ArtifactUploadHash }}/{{ .ArtifactName }}",
@ -267,13 +241,7 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenT
ctx.Config.Release.GitLab.Name, ctx.Config.Release.GitLab.Name,
) )
default: default:
log.Warn("no url_template set and not github/gitlab/gitea token found, defaulting to github url template") return result, ErrTokenTypeNotImplementedForBrew
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,
)
} }
} }
url, err := tmpl.New(ctx).WithArtifact(artifact, map[string]string{}).Apply(cfg.URLTemplate) url, err := tmpl.New(ctx).WithArtifact(artifact, map[string]string{}).Apply(cfg.URLTemplate)

View File

@ -13,7 +13,6 @@ import (
"github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
var update = flag.Bool("update", false, "update .golden files") var update = flag.Bool("update", false, "update .golden files")
@ -249,8 +248,7 @@ func TestRunPipe(t *testing.T) {
client := &DummyClient{} client := &DummyClient{}
var distFile = filepath.Join(folder, name+".rb") var distFile = filepath.Join(folder, name+".rb")
require.NoError(t, Pipe{}.Run(ctx)) assert.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
assert.NoError(t, doPublish(ctx, client))
assert.True(t, client.CreatedFile) assert.True(t, client.CreatedFile)
var golden = fmt.Sprintf("testdata/%s.rb.golden", name) var golden = fmt.Sprintf("testdata/%s.rb.golden", name)
if *update { if *update {
@ -377,8 +375,7 @@ func TestRunPipeForMultipleArmVersions(t *testing.T) {
client := &DummyClient{} client := &DummyClient{}
var distFile = filepath.Join(folder, name+".rb") var distFile = filepath.Join(folder, name+".rb")
require.NoError(t, Pipe{}.Run(ctx)) assert.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
assert.NoError(t, doPublish(ctx, client))
assert.True(t, client.CreatedFile) assert.True(t, client.CreatedFile)
var golden = fmt.Sprintf("testdata/%s.rb.golden", name) var golden = fmt.Sprintf("testdata/%s.rb.golden", name)
if *update { if *update {
@ -409,9 +406,8 @@ func TestRunPipeNoDarwin64Build(t *testing.T) {
}, },
} }
client := &DummyClient{} client := &DummyClient{}
require.Equal(t, ErrNoArchivesFound, Pipe{}.Run(ctx)) assert.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
testlib.AssertSkipped(t, doPublish(ctx, client)) assert.False(t, client.CreatedFile)
require.False(t, client.CreatedFile)
} }
func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) { func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
@ -554,9 +550,8 @@ func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
}) })
} }
client := &DummyClient{} client := &DummyClient{}
require.Equal(t, test.expectedError, Pipe{}.Run(ctx)) assert.Equal(t, test.expectedError, doRun(ctx, ctx.Config.Brews[0], client))
testlib.AssertSkipped(t, doPublish(ctx, client)) assert.False(t, client.CreatedFile)
require.False(t, client.CreatedFile)
// clean the artifacts for the next run // clean the artifacts for the next run
ctx.Artifacts = artifact.New() ctx.Artifacts = artifact.New()
} }
@ -567,8 +562,7 @@ func TestRunPipeBrewNotSetup(t *testing.T) {
Config: config.Project{}, Config: config.Project{},
} }
client := &DummyClient{} client := &DummyClient{}
require.NoError(t, Pipe{}.Run(ctx)) testlib.AssertSkipped(t, doRun(ctx, config.Homebrew{}, client))
testlib.AssertSkipped(t, doPublish(ctx, client))
assert.False(t, client.CreatedFile) assert.False(t, client.CreatedFile)
} }
@ -593,73 +587,97 @@ func TestRunPipeBinaryRelease(t *testing.T) {
Type: artifact.Binary, Type: artifact.Binary,
}) })
client := &DummyClient{} client := &DummyClient{}
require.Equal(t, ErrNoArchivesFound, Pipe{}.Run(ctx)) assert.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
testlib.AssertSkipped(t, doPublish(ctx, client)) assert.False(t, client.CreatedFile)
require.False(t, client.CreatedFile)
} }
func TestRunPipeNoUpload(t *testing.T) { func TestRunPipeNoUpload(t *testing.T) {
folder, err := ioutil.TempDir("", "goreleasertest") folder, err := ioutil.TempDir("", "goreleasertest")
assert.NoError(t, err) assert.NoError(t, err)
var ctx = context.New(config.Project{
var newCtx = func() *context.Context { Dist: folder,
var ctx = context.New(config.Project{ ProjectName: "foo",
Dist: folder, Release: config.Release{},
ProjectName: "foo", Brews: []config.Homebrew{
Release: config.Release{}, {
Brews: []config.Homebrew{ GitHub: config.Repo{
{ Owner: "test",
GitHub: config.Repo{ Name: "test",
Owner: "test",
Name: "test",
},
}, },
}, },
}) },
ctx.TokenType = context.TokenTypeGitHub })
ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"} ctx.TokenType = context.TokenTypeGitHub
var path = filepath.Join(folder, "whatever.tar.gz") ctx.Git = context.GitInfo{CurrentTag: "v1.0.1"}
_, err = os.Create(path) var path = filepath.Join(folder, "whatever.tar.gz")
assert.NoError(t, err) _, err = os.Create(path)
ctx.Artifacts.Add(&artifact.Artifact{ assert.NoError(t, err)
Name: "bin", ctx.Artifacts.Add(&artifact.Artifact{
Path: path, Name: "bin",
Goos: "darwin", Path: path,
Goarch: "amd64", Goos: "darwin",
Type: artifact.UploadableArchive, Goarch: "amd64",
Extra: map[string]interface{}{ Type: artifact.UploadableArchive,
"ID": "foo", Extra: map[string]interface{}{
"Format": "tar.gz", "ID": "foo",
}, "Format": "tar.gz",
}) },
return ctx })
} client := &DummyClient{}
var client = &DummyClient{}
var assertNoPublish = func(t *testing.T, ctx *context.Context) { var assertNoPublish = func(t *testing.T) {
require.NoError(t, Pipe{}.Run(ctx)) testlib.AssertSkipped(t, doRun(ctx, ctx.Config.Brews[0], client))
testlib.AssertSkipped(t, doPublish(ctx, client))
assert.False(t, client.CreatedFile) assert.False(t, client.CreatedFile)
} }
t.Run("skip upload", func(tt *testing.T) { t.Run("skip upload", func(tt *testing.T) {
var ctx = newCtx()
ctx.Config.Release.Draft = false ctx.Config.Release.Draft = false
ctx.Config.Brews[0].SkipUpload = "true" ctx.Config.Brews[0].SkipUpload = "true"
ctx.SkipPublish = false ctx.SkipPublish = false
require.NoError(t, Pipe{}.Run(ctx)) assertNoPublish(tt)
assertNoPublish(tt, ctx)
}) })
t.Run("skip publish", func(tt *testing.T) { t.Run("skip publish", func(tt *testing.T) {
var ctx = newCtx()
ctx.Config.Release.Draft = false ctx.Config.Release.Draft = false
ctx.Config.Brews[0].SkipUpload = "false" ctx.Config.Brews[0].SkipUpload = "false"
ctx.SkipPublish = true ctx.SkipPublish = true
require.NoError(t, Pipe{}.Run(ctx)) assertNoPublish(tt)
assertNoPublish(tt, ctx)
}) })
} }
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) { func TestDefault(t *testing.T) {
_, back := testlib.Mktmp(t) _, back := testlib.Mktmp(t)
defer back() defer back()

View File

@ -75,6 +75,9 @@ func (Pipe) Run(ctx *context.Context) error {
// Publish the docker images // Publish the docker images
func (Pipe) Publish(ctx *context.Context) error { func (Pipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
var images = ctx.Artifacts.Filter(artifact.ByType(artifact.PublishableDockerImage)).List() var images = ctx.Artifacts.Filter(artifact.ByType(artifact.PublishableDockerImage)).List()
for _, image := range images { for _, image := range images {
if err := dockerPush(ctx, image); err != nil { if err := dockerPush(ctx, image); err != nil {

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"github.com/goreleaser/goreleaser/internal/middleware" "github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/pipe/artifactory" "github.com/goreleaser/goreleaser/internal/pipe/artifactory"
"github.com/goreleaser/goreleaser/internal/pipe/blob" "github.com/goreleaser/goreleaser/internal/pipe/blob"
"github.com/goreleaser/goreleaser/internal/pipe/brew" "github.com/goreleaser/goreleaser/internal/pipe/brew"
@ -49,9 +48,6 @@ var publishers = []Publisher{
// Run the pipe // Run the pipe
func (Pipe) Run(ctx *context.Context) error { func (Pipe) Run(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
for _, publisher := range publishers { for _, publisher := range publishers {
if err := middleware.Logging( if err := middleware.Logging(
publisher.String(), publisher.String(),

View File

@ -3,7 +3,6 @@ package publish
import ( import (
"testing" "testing"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -13,12 +12,6 @@ func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String()) require.NotEmpty(t, Pipe{}.String())
} }
func TestPublishDisable(t *testing.T) {
var ctx = context.New(config.Project{})
ctx.SkipPublish = true
require.EqualError(t, Pipe{}.Run(ctx), pipe.ErrSkipPublishEnabled.Error())
}
func TestPublish(t *testing.T) { func TestPublish(t *testing.T) {
var ctx = context.New(config.Project{}) var ctx = context.New(config.Project{})
ctx.Config.Release.Disable = true ctx.Config.Release.Disable = true

View File

@ -99,6 +99,9 @@ func (Pipe) Default(ctx *context.Context) error {
// Publish github release // Publish github release
func (Pipe) Publish(ctx *context.Context) error { func (Pipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
c, err := client.New(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err

View File

@ -32,7 +32,9 @@ func (Pipe) String() string {
// Publish scoop manifest // Publish scoop manifest
func (Pipe) Publish(ctx *context.Context) error { func (Pipe) Publish(ctx *context.Context) error {
// TODO(caarlos0): split the creation of the json file and the publishing in two steps, like the brew pipe. if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
client, err := client.New(ctx) client, err := client.New(ctx)
if err != nil { if err != nil {
return err return err

View File

@ -4,7 +4,6 @@ package pipeline
import ( import (
"fmt" "fmt"
"github.com/goreleaser/goreleaser/internal/pipe/brew"
"github.com/goreleaser/goreleaser/internal/pipe/semver" "github.com/goreleaser/goreleaser/internal/pipe/semver"
"github.com/goreleaser/goreleaser/internal/pipe/sourcearchive" "github.com/goreleaser/goreleaser/internal/pipe/sourcearchive"
@ -55,6 +54,5 @@ var Pipeline = []Piper{
checksums.Pipe{}, // checksums of the files checksums.Pipe{}, // checksums of the files
sign.Pipe{}, // sign artifacts sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images docker.Pipe{}, // create and push docker images
brew.Pipe{}, // create the formula file on dist
publish.Pipe{}, // publishes artifacts publish.Pipe{}, // publishes artifacts
} }