Skip to content

Commit

Permalink
feat: split brew tap in 2 steps (#1425)
Browse files Browse the repository at this point in the history
* feat: split brew tap in 2 steps

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

* refactor: improve env

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

* fix: loop

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
  • Loading branch information
caarlos0 committed Apr 9, 2020
1 parent 88213a5 commit 5e8882f
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 98 deletions.
4 changes: 4 additions & 0 deletions internal/artifact/artifact.go
Expand Up @@ -29,6 +29,8 @@ const (
UploadableBinary
// UploadableFile is any file that can be uploaded
UploadableFile
// UploadableBrewTap is a .rb file that can be uploaded
UploadableBrewTap
// Binary is a binary (output of a gobuild)
Binary
// LinuxPackage is a linux package generated by nfpm
Expand All @@ -54,6 +56,8 @@ func (t Type) String() string {
case UploadableBinary:
case Binary:
return "Binary"
case UploadableBrewTap:
return "Brew Tap"
case LinuxPackage:
return "Linux Package"
case DockerImage:
Expand Down
96 changes: 65 additions & 31 deletions internal/pipe/brew/brew.go
Expand Up @@ -2,7 +2,6 @@ package brew

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"path"
Expand All @@ -17,6 +16,7 @@ import (
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/pkg/errors"
)

// ErrNoArchivesFound happens when 0 archives are found
Expand All @@ -36,14 +36,64 @@ func (Pipe) String() string {
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
func (Pipe) Publish(ctx *context.Context) error {
client, err := client.New(ctx)
if err != nil {
return err
}
for _, brew := range ctx.Config.Brews {
if err := doRun(ctx, brew, client); err != nil {

return doPublish(ctx, client)
}

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
}
}
Expand Down Expand Up @@ -105,7 +155,7 @@ func contains(ss []string, s string) bool {
return false
}

func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) error {
func doRun(ctx *context.Context, brew config.Homebrew) error {
if brew.GitHub.Name == "" && brew.GitLab.Name == "" {
return pipe.Skip("brew section is not configured")
}
Expand Down Expand Up @@ -145,36 +195,19 @@ func doRun(ctx *context.Context, brew config.Homebrew, client client.Client) err
var path = filepath.Join(ctx.Config.Dist, filename)
log.WithField("formula", path).Info("writing")
if err := ioutil.WriteFile(path, []byte(content), 0644); err != nil {
return err
return errors.Wrap(err, "failed to write brew tap")
}

if strings.TrimSpace(brew.SkipUpload) == "true" {
return pipe.Skip("brew.skip_upload is set")
}
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
if strings.TrimSpace(brew.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
return pipe.Skip("prerelease detected with 'auto' upload, skipping homebrew publish")
}
ctx.Artifacts.Add(&artifact.Artifact{
Name: filename,
Path: path,
Type: artifact.UploadableBrewTap,
Extra: map[string]interface{}{
"config": brew,
},
})

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)
return nil
}

func buildFormulaPath(folder, filename string) string {
Expand Down Expand Up @@ -241,6 +274,7 @@ func dataFor(ctx *context.Context, cfg config.Homebrew, tokenType context.TokenT
ctx.Config.Release.GitLab.Name,
)
default:
log.WithField("type", tokenType).Info("here")
return result, ErrTokenTypeNotImplementedForBrew
}
}
Expand Down
102 changes: 60 additions & 42 deletions internal/pipe/brew/brew_test.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var update = flag.Bool("update", false, "update .golden files")
Expand Down Expand Up @@ -248,7 +249,8 @@ func TestRunPipe(t *testing.T) {
client := &DummyClient{}
var distFile = filepath.Join(folder, name+".rb")

assert.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, Pipe{}.Run(ctx))
assert.NoError(t, doPublish(ctx, client))
assert.True(t, client.CreatedFile)
var golden = fmt.Sprintf("testdata/%s.rb.golden", name)
if *update {
Expand Down Expand Up @@ -375,7 +377,8 @@ func TestRunPipeForMultipleArmVersions(t *testing.T) {
client := &DummyClient{}
var distFile = filepath.Join(folder, name+".rb")

assert.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, Pipe{}.Run(ctx))
assert.NoError(t, doPublish(ctx, client))
assert.True(t, client.CreatedFile)
var golden = fmt.Sprintf("testdata/%s.rb.golden", name)
if *update {
Expand Down Expand Up @@ -406,8 +409,9 @@ func TestRunPipeNoDarwin64Build(t *testing.T) {
},
}
client := &DummyClient{}
assert.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
assert.False(t, client.CreatedFile)
require.Equal(t, ErrNoArchivesFound, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
require.False(t, client.CreatedFile)
}

func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
Expand Down Expand Up @@ -550,8 +554,9 @@ func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
})
}
client := &DummyClient{}
assert.Equal(t, test.expectedError, doRun(ctx, ctx.Config.Brews[0], client))
assert.False(t, client.CreatedFile)
require.Equal(t, test.expectedError, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
require.False(t, client.CreatedFile)
// clean the artifacts for the next run
ctx.Artifacts = artifact.New()
}
Expand All @@ -562,7 +567,8 @@ func TestRunPipeBrewNotSetup(t *testing.T) {
Config: config.Project{},
}
client := &DummyClient{}
testlib.AssertSkipped(t, doRun(ctx, config.Homebrew{}, client))
require.NoError(t, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
assert.False(t, client.CreatedFile)
}

Expand All @@ -587,59 +593,70 @@ func TestRunPipeBinaryRelease(t *testing.T) {
Type: artifact.Binary,
})
client := &DummyClient{}
assert.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
assert.False(t, client.CreatedFile)
require.Equal(t, ErrNoArchivesFound, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
require.False(t, client.CreatedFile)
}

func TestRunPipeNoUpload(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",

var newCtx = func() *context.Context {
var ctx = context.New(config.Project{
Dist: folder,
ProjectName: "foo",
Release: config.Release{},
Brews: []config.Homebrew{
{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
},
},
})
ctx.TokenType = context.TokenTypeGitHub
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{}
})
ctx.TokenType = context.TokenTypeGitHub
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",
},
})
return ctx
}
var client = &DummyClient{}

var assertNoPublish = func(t *testing.T) {
testlib.AssertSkipped(t, doRun(ctx, ctx.Config.Brews[0], client))
var assertNoPublish = func(t *testing.T, ctx *context.Context) {
require.NoError(t, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
assert.False(t, client.CreatedFile)
}

t.Run("skip upload", func(tt *testing.T) {
var ctx = newCtx()
ctx.Config.Release.Draft = false
ctx.Config.Brews[0].SkipUpload = "true"
ctx.SkipPublish = false
assertNoPublish(tt)
require.NoError(t, Pipe{}.Run(ctx))
assertNoPublish(tt, ctx)
})
t.Run("skip publish", func(tt *testing.T) {
var ctx = newCtx()
ctx.Config.Release.Draft = false
ctx.Config.Brews[0].SkipUpload = "false"
ctx.SkipPublish = true
assertNoPublish(tt)
require.NoError(t, Pipe{}.Run(ctx))
assertNoPublish(tt, ctx)
})
}

Expand Down Expand Up @@ -675,7 +692,8 @@ func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
},
})
client := &DummyClient{}
assert.Equal(t, ErrTokenTypeNotImplementedForBrew, doRun(ctx, ctx.Config.Brews[0], client))
require.Equal(t, ErrTokenTypeNotImplementedForBrew, Pipe{}.Run(ctx))
testlib.AssertSkipped(t, doPublish(ctx, client))
}

func TestDefault(t *testing.T) {
Expand Down

0 comments on commit 5e8882f

Please sign in to comment.