1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-10-30 23:58:09 +02:00

feat: improve output and pipe skipping (#2480)

* refactor: improve middleware

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

* fix: upload tests

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

* fix: twitter tests

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

* fix: source tests

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

* fix: snapshot tests

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

* test: improved some tests

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

* fix: snapcraft skip

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

* fix: skip slack

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

* fix: skip sign

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

* fix: skip scoop

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

* fix: skip reddit

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

* fix: skip discord

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

* fix: skip publish

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

* fix: skip nfpm

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

* fix: skip milestone

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

* fix: skip custompublishers

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

* fix: skip checksums

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

* fix: skip changelog

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

* fix: skip brew

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

* fix: skip blob

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

* fix: skip before

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

* fix: skip artifactory

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

* fix: skip announce

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

* fix: skip defaults

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

* fix: cmds

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

* fix: skip docker

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

* chore: todo

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

* fix: go.mod

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

* fix: skip release

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

* fix: remove old skip pipe errors

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

* fix: skip teams

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

* fix: skip brew

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

* fix/test: skip smtp

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

* fix: lint issues

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

* fix: skip docker

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

* fix: skip brew and scoop

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

* fix: skip docker

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

* fix: skip http/artifactory

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

* test: increase coverage

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

* test: fix

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
Carlos Alexandro Becker
2021-09-18 10:21:29 -03:00
committed by GitHub
parent 35cb87e66a
commit 61bead8989
89 changed files with 1083 additions and 936 deletions

View File

@@ -9,7 +9,9 @@ import (
"github.com/apex/log"
"github.com/caarlos0/ctrlc"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
"github.com/goreleaser/goreleaser/internal/middleware/logging"
"github.com/goreleaser/goreleaser/internal/middleware/skip"
"github.com/goreleaser/goreleaser/internal/pipeline"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
@@ -97,10 +99,13 @@ func buildProject(options buildOpts) (*context.Context, error) {
}
return ctx, ctrlc.Default.Run(ctx, func() error {
for _, pipe := range pipeline.BuildPipeline {
if err := middleware.Logging(
pipe.String(),
middleware.ErrHandler(pipe.Run),
middleware.DefaultInitialPadding,
if err := skip.Maybe(
pipe,
logging.Log(
pipe.String(),
errhandler.Handle(pipe.Run),
logging.DefaultInitialPadding,
),
)(ctx); err != nil {
return err
}

View File

@@ -7,7 +7,9 @@ import (
"github.com/apex/log"
"github.com/caarlos0/ctrlc"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
"github.com/goreleaser/goreleaser/internal/middleware/logging"
"github.com/goreleaser/goreleaser/internal/middleware/skip"
"github.com/goreleaser/goreleaser/internal/pipe/git"
"github.com/goreleaser/goreleaser/internal/pipeline"
"github.com/goreleaser/goreleaser/pkg/context"
@@ -101,10 +103,13 @@ func releaseProject(options releaseOpts) (*context.Context, error) {
setupReleaseContext(ctx, options)
return ctx, ctrlc.Default.Run(ctx, func() error {
for _, pipe := range pipeline.Pipeline {
if err := middleware.Logging(
pipe.String(),
middleware.ErrHandler(pipe.Run),
middleware.DefaultInitialPadding,
if err := skip.Maybe(
pipe,
logging.Log(
pipe.String(),
errhandler.Handle(pipe.Run),
logging.DefaultInitialPadding,
),
)(ctx); err != nil {
return err
}

View File

@@ -48,6 +48,10 @@ const (
Signature
// UploadableSourceArchive is the archive with the current commit source code.
UploadableSourceArchive
// BrewTap is an uploadable homebrew tap recipe file.
BrewTap
// ScoopManifest is an uploadable scoop manifest file.
ScoopManifest
)
func (t Type) String() string {
@@ -72,6 +76,10 @@ func (t Type) String() string {
return "Signature"
case UploadableSourceArchive:
return "Source"
case BrewTap:
return "Brew Tap"
case ScoopManifest:
return "Scoop Manifest"
default:
return "unknown"
}
@@ -126,8 +134,8 @@ func (a Artifact) Checksum(algorithm string) (string, error) {
default:
return "", fmt.Errorf("invalid algorithm: %s", algorithm)
}
_, err = io.Copy(h, file)
if err != nil {
if _, err := io.Copy(h, file); err != nil {
return "", fmt.Errorf("failed to checksum: %w", err)
}
return hex.EncodeToString(h.Sum(nil)), nil

View File

@@ -306,6 +306,8 @@ func TestTypeToString(t *testing.T) {
Checksum,
Signature,
UploadableSourceArchive,
BrewTap,
ScoopManifest,
} {
t.Run(a.String(), func(t *testing.T) {
require.NotEqual(t, "unknown", a.String())

View File

@@ -1 +0,0 @@
package artifact

View File

@@ -8,6 +8,7 @@ import (
"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"
)
@@ -55,7 +56,7 @@ func New(ctx *context.Context) (Client, error) {
return nil, nil
}
func NewWithToken(ctx *context.Context, token string) (Client, error) {
func newWithToken(ctx *context.Context, token string) (Client, error) {
if ctx.TokenType == context.TokenTypeGitHub {
return NewGitHub(ctx, token)
}
@@ -68,6 +69,18 @@ func NewWithToken(ctx *context.Context, token string) (Client, error) {
return nil, nil
}
func NewIfToken(ctx *context.Context, cli Client, token string) (Client, error) {
if token == "" {
return cli, nil
}
token, err := tmpl.New(ctx).ApplySingleEnvOnly(token)
if err != nil {
return nil, err
}
log.Debug("using custom token")
return newWithToken(ctx, token)
}
// ErrNoMilestoneFound is an error when no milestone is found.
type ErrNoMilestoneFound struct {
Title string

View File

@@ -58,3 +58,102 @@ func TestClientNewGitLab(t *testing.T) {
_, ok := client.(*gitlabClient)
require.True(t, ok)
}
func TestNewIfToken(t *testing.T) {
t.Run("valid", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenTypeGitLab,
Token: "gitlabtoken",
}
client, err := New(ctx)
require.NoError(t, err)
_, ok := client.(*gitlabClient)
require.True(t, ok)
ctx = &context.Context{
Config: config.Project{
GiteaURLs: config.GiteaURLs{
API: "https://gitea.com/api/v1",
},
},
TokenType: context.TokenTypeGitea,
Token: "giteatoken",
Env: map[string]string{"VAR": "token"},
}
client, err = NewIfToken(ctx, client, "{{ .Env.VAR }}")
require.NoError(t, err)
_, ok = client.(*giteaClient)
require.True(t, ok)
})
t.Run("empty", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenTypeGitLab,
Token: "gitlabtoken",
}
client, err := New(ctx)
require.NoError(t, err)
client, err = NewIfToken(ctx, client, "")
require.NoError(t, err)
_, ok := client.(*gitlabClient)
require.True(t, ok)
})
t.Run("invalid tmpl", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenTypeGitLab,
Token: "gitlabtoken",
}
_, err := NewIfToken(ctx, nil, "nope")
require.EqualError(t, err, `expected {{ .Env.VAR_NAME }} only (no plain-text or other interpolation)`)
})
}
func TestNewWithToken(t *testing.T) {
t.Run("gitlab", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenTypeGitLab,
Env: map[string]string{"TK": "token"},
}
cli, err := newWithToken(ctx, "{{ .Env.TK }}")
require.NoError(t, err)
_, ok := cli.(*gitlabClient)
require.True(t, ok)
})
t.Run("gitea", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenTypeGitea,
Env: map[string]string{"TK": "token"},
Config: config.Project{
GiteaURLs: config.GiteaURLs{
API: "https://gitea.com/api/v1",
},
},
}
cli, err := newWithToken(ctx, "{{ .Env.TK }}")
require.NoError(t, err)
_, ok := cli.(*giteaClient)
require.True(t, ok)
})
t.Run("invalid", func(t *testing.T) {
ctx := &context.Context{
TokenType: context.TokenType("nope"),
Env: map[string]string{"TK": "token"},
}
cli, err := newWithToken(ctx, "{{ .Env.TK }}")
require.NoError(t, err)
require.Nil(t, cli)
})
}

View File

@@ -29,6 +29,7 @@ func NewGitHub(ctx *context.Context, token string) (Client, error) {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
httpClient := oauth2.NewClient(ctx, ts)
base := httpClient.Transport.(*oauth2.Transport).Base
if base == nil || reflect.ValueOf(base).IsNil() {

View File

@@ -141,10 +141,6 @@ type ResponseChecker func(*h.Response) error
// Upload does the actual uploading work.
func Upload(ctx *context.Context, uploads []config.Upload, kind string, check ResponseChecker) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
// Handle every configured upload
for _, upload := range uploads {
upload := upload

View File

@@ -485,15 +485,6 @@ func TestUpload(t *testing.T) {
},
checks(),
},
{
"skip-publishing", true, true, true, true,
func(s *httptest.Server) (*context.Context, config.Upload) {
c := *ctx
c.SkipPublish = true
return &c, config.Upload{}
},
checks(),
},
{
"checksumheader", true, true, false, false,
func(s *httptest.Server) (*context.Context, config.Upload) {

View File

@@ -1,2 +0,0 @@
// Package middleware define middlewares for Actions.
package middleware

View File

@@ -1,23 +1,20 @@
package middleware
package errhandler
import (
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/pkg/context"
)
// ErrHandler handles an action error, ignoring and logging pipe skipped
// Handle handles an action error, ignoring and logging pipe skipped
// errors.
func ErrHandler(action Action) Action {
func Handle(action middleware.Action) middleware.Action {
return func(ctx *context.Context) error {
err := action(ctx)
if err == nil {
return nil
}
if pipe.IsExpectedSkip(err) {
log.WithError(err).Debug("pipe skipped")
return nil
}
if pipe.IsSkip(err) {
log.WithError(err).Warn("pipe skipped")
return nil

View File

@@ -0,0 +1,30 @@
package errhandler
import (
"fmt"
"testing"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)
func TestError(t *testing.T) {
t.Run("no errors", func(t *testing.T) {
require.NoError(t, Handle(func(ctx *context.Context) error {
return nil
})(nil))
})
t.Run("pipe skipped", func(t *testing.T) {
require.NoError(t, Handle(func(ctx *context.Context) error {
return pipe.ErrSkipValidateEnabled
})(nil))
})
t.Run("some err", func(t *testing.T) {
require.Error(t, Handle(func(ctx *context.Context) error {
return fmt.Errorf("pipe errored")
})(nil))
})
}

View File

@@ -1,27 +0,0 @@
package middleware
import (
"fmt"
"testing"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/stretchr/testify/require"
)
func TestError(t *testing.T) {
t.Run("no errors", func(t *testing.T) {
require.NoError(t, ErrHandler(mockAction(nil))(ctx))
})
t.Run("pipe skipped", func(t *testing.T) {
require.NoError(t, ErrHandler(mockAction(pipe.ErrSkipValidateEnabled))(ctx))
})
t.Run("pipe expected skipped", func(t *testing.T) {
require.NoError(t, ErrHandler(mockAction(pipe.ErrSkipDisabledPipe))(ctx))
})
t.Run("some err", func(t *testing.T) {
require.Error(t, ErrHandler(mockAction(fmt.Errorf("pipe errored")))(ctx))
})
}

View File

@@ -1,9 +1,10 @@
package middleware
package logging
import (
"github.com/apex/log"
"github.com/apex/log/handlers/cli"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -16,13 +17,13 @@ const DefaultInitialPadding Padding = 3
// ExtraPadding is the double of the DefaultInitialPadding.
const ExtraPadding = DefaultInitialPadding * 2
// Logging pretty prints the given action and its title.
// Log pretty prints the given action and its title.
// You can have different padding levels by providing different initial
// paddings. The middleware will print the title in the given padding and the
// action logs in padding+default padding.
// The default padding in the log library is 3.
// The middleware always resets to the default padding.
func Logging(title string, next Action, padding Padding) Action {
func Log(title string, next middleware.Action, padding Padding) middleware.Action {
return func(ctx *context.Context) error {
defer func() {
cli.Default.Padding = int(DefaultInitialPadding)

View File

@@ -0,0 +1,14 @@
package logging
import (
"testing"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)
func TestLogging(t *testing.T) {
require.NoError(t, Log("foo", func(ctx *context.Context) error {
return nil
}, DefaultInitialPadding)(nil))
}

View File

@@ -1,11 +0,0 @@
package middleware
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestLogging(t *testing.T) {
require.NoError(t, Logging("foo", mockAction(nil), DefaultInitialPadding)(ctx))
}

View File

@@ -1,3 +1,4 @@
// Package middleware define middlewares for Actions.
package middleware
import "github.com/goreleaser/goreleaser/pkg/context"

View File

@@ -1,11 +0,0 @@
package middleware
import "github.com/goreleaser/goreleaser/pkg/context"
var ctx = &context.Context{}
func mockAction(err error) Action {
return func(ctx *context.Context) error {
return err
}
}

View File

@@ -0,0 +1,27 @@
// Package skip can skip an entire Action.
package skip
import (
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/pkg/context"
)
// Skipper defines a method to skip an entire Piper.
type Skipper interface {
// Skip returns true if the Piper should be skipped.
Skip(ctx *context.Context) bool
}
// Maybe returns an action that skips immediately if the given p is a Skipper
// and its Skip method returns true.
func Maybe(skipper interface{}, next middleware.Action) middleware.Action {
if skipper, ok := skipper.(Skipper); ok {
return func(ctx *context.Context) error {
if skipper.Skip(ctx) {
return nil
}
return next(ctx)
}
}
return next
}

View File

@@ -0,0 +1,36 @@
package skip
import (
"fmt"
"testing"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)
func TestSkip(t *testing.T) {
fakeErr := fmt.Errorf("fake error")
action := func(_ *context.Context) error {
return fakeErr
}
t.Run("not a skipper", func(t *testing.T) {
require.EqualError(t, Maybe(action, action)(nil), fakeErr.Error())
})
t.Run("skip", func(t *testing.T) {
require.NoError(t, Maybe(skipper{true}, action)(nil))
})
t.Run("do not skip", func(t *testing.T) {
require.EqualError(t, Maybe(skipper{false}, action)(nil), fakeErr.Error())
})
}
type skipper struct {
skip bool
}
func (s skipper) Skip(_ *context.Context) bool {
return s.skip
}

View File

@@ -4,7 +4,9 @@ package announce
import (
"fmt"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
"github.com/goreleaser/goreleaser/internal/middleware/logging"
"github.com/goreleaser/goreleaser/internal/middleware/skip"
"github.com/goreleaser/goreleaser/internal/pipe/discord"
"github.com/goreleaser/goreleaser/internal/pipe/reddit"
"github.com/goreleaser/goreleaser/internal/pipe/slack"
@@ -14,13 +16,6 @@ import (
"github.com/goreleaser/goreleaser/pkg/context"
)
// Pipe that announces releases.
type Pipe struct{}
func (Pipe) String() string {
return "announcing"
}
// Announcer should be implemented by pipes that want to announce releases.
type Announcer interface {
fmt.Stringer
@@ -39,13 +34,22 @@ var announcers = []Announcer{
twitter.Pipe{},
}
// Pipe that announces releases.
type Pipe struct{}
func (Pipe) String() string { return "announcing" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.SkipAnnounce }
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
for _, announcer := range announcers {
if err := middleware.Logging(
announcer.String(),
middleware.ErrHandler(announcer.Announce),
middleware.ExtraPadding,
if err := skip.Maybe(
announcer,
logging.Log(
announcer.String(),
errhandler.Handle(announcer.Announce),
logging.ExtraPadding,
),
)(ctx); err != nil {
return fmt.Errorf("%s: failed to announce release: %w", announcer.String(), err)
}

View File

@@ -13,6 +13,29 @@ func TestDescription(t *testing.T) {
}
func TestAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Twitter: config.Twitter{
Enabled: true,
},
},
})
require.Error(t, Pipe{}.Run(ctx))
}
func TestAnnounceAllDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Run(ctx))
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipAnnounce = true
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
require.False(t, Pipe{}.Skip(context.New(config.Project{})))
})
}

View File

@@ -15,10 +15,8 @@ import (
// Pipe for Artifactory.
type Pipe struct{}
// String returns the description of the pipe.
func (Pipe) String() string {
return "artifactory"
}
func (Pipe) String() string { return "artifactory" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Artifactories) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -35,10 +33,6 @@ func (Pipe) Default(ctx *context.Context) error {
//
// Docs: https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API#ArtifactoryRESTAPI-Example-DeployinganArtifact
func (Pipe) Publish(ctx *context.Context) error {
if len(ctx.Config.Artifactories) == 0 {
return pipe.ErrSkipDisabledPipe
}
// Check requirements for every instance we have configured.
// If not fulfilled, we can skip this pipeline
for _, instance := range ctx.Config.Artifactories {

View File

@@ -10,7 +10,7 @@ import (
"testing"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -568,31 +568,6 @@ func TestRunPipe_UnparsableTarget(t *testing.T) {
require.EqualError(t, Pipe{}.Publish(ctx), `artifactory: upload failed: parse "://artifacts.company.com/example-repo-local/mybin/darwin/amd64/mybin": missing protocol scheme`)
}
func TestRunPipe_SkipWhenPublishFalse(t *testing.T) {
ctx := context.New(config.Project{
Artifactories: []config.Upload{
{
Name: "production",
Mode: "binary",
Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}",
Username: "deployuser",
},
},
Archives: []config.Archive{
{},
},
})
ctx.Env = map[string]string{
"ARTIFACTORY_PRODUCTION_SECRET": "deployuser-secret",
}
ctx.SkipPublish = true
require.NoError(t, Pipe{}.Default(ctx))
err := Pipe{}.Publish(ctx)
require.True(t, pipe.IsSkip(err))
require.EqualError(t, err, pipe.ErrSkipPublishEnabled.Error())
}
func TestRunPipe_DirUpload(t *testing.T) {
folder := t.TempDir()
dist := filepath.Join(folder, "dist")
@@ -634,12 +609,6 @@ func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestNoArtifactories(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
}
func TestArtifactoriesWithoutTarget(t *testing.T) {
ctx := &context.Context{
Env: map[string]string{
@@ -656,7 +625,7 @@ func TestArtifactoriesWithoutTarget(t *testing.T) {
}
require.NoError(t, Pipe{}.Default(ctx))
require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
testlib.AssertSkipped(t, Pipe{}.Publish(ctx))
}
func TestArtifactoriesWithoutUsername(t *testing.T) {
@@ -675,7 +644,7 @@ func TestArtifactoriesWithoutUsername(t *testing.T) {
}
require.NoError(t, Pipe{}.Default(ctx))
require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
testlib.AssertSkipped(t, Pipe{}.Publish(ctx))
}
func TestArtifactoriesWithoutName(t *testing.T) {
@@ -688,7 +657,7 @@ func TestArtifactoriesWithoutName(t *testing.T) {
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
testlib.AssertSkipped(t, Pipe{}.Publish(ctx))
}
func TestArtifactoriesWithoutSecret(t *testing.T) {
@@ -702,7 +671,7 @@ func TestArtifactoriesWithoutSecret(t *testing.T) {
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.True(t, pipe.IsSkip(Pipe{}.Publish(ctx)))
testlib.AssertSkipped(t, Pipe{}.Publish(ctx))
}
func TestArtifactoriesWithInvalidMode(t *testing.T) {
@@ -772,3 +741,16 @@ func TestDefaultSet(t *testing.T) {
require.Equal(t, "custom", artifactory.Mode)
require.Equal(t, "foo", artifactory.ChecksumHeader)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Artifactories: []config.Upload{{}},
})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -18,10 +18,8 @@ import (
// Pipe is a global hook pipe.
type Pipe struct{}
// String is the name of this pipe.
func (Pipe) String() string {
return "running before hooks"
}
func (Pipe) String() string { return "running before hooks" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Before.Hooks) == 0 }
// Run executes the hooks.
func (Pipe) Run(ctx *context.Context) error {

View File

@@ -91,3 +91,18 @@ func TestInvalidTemplate(t *testing.T) {
},
)), `template: tmpl:1: unexpected "}" in operand`)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Before: config.Before{
Hooks: []string{""},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"strings"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/semerrgroup"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -14,9 +13,8 @@ import (
type Pipe struct{}
// String returns the description of the pipe.
func (Pipe) String() string {
return "blobs"
}
func (Pipe) String() string { return "blobs" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Blobs) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -35,10 +33,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Publish to specified blob bucket url.
func (Pipe) Publish(ctx *context.Context) error {
if len(ctx.Config.Blobs) == 0 {
return pipe.ErrSkipDisabledPipe
}
g := semerrgroup.New(ctx.Parallelism)
for _, conf := range ctx.Config.Blobs {
conf := conf

View File

@@ -200,75 +200,6 @@ func TestMinioUploadInvalidCustomBucketID(t *testing.T) {
require.Error(t, Pipe{}.Publish(ctx))
}
func TestMinioUploadSkipPublish(t *testing.T) {
listen := randomListen(t)
folder := t.TempDir()
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")
require.NoError(t, os.WriteFile(checkpath, []byte("fake checksums"), 0o744))
require.NoError(t, os.WriteFile(srcpath, []byte("fake\nsrc"), 0o744))
require.NoError(t, os.WriteFile(tgzpath, []byte("fake\ntargz"), 0o744))
require.NoError(t, os.WriteFile(debpath, []byte("fake\ndeb"), 0o744))
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",
},
})
name := "test_upload"
start(t, name, listen)
prepareEnv()
require.NoError(t, Pipe{}.Default(ctx))
require.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 {
t.Helper()
listener, err := net.Listen("tcp", "127.0.0.1:0")

View File

@@ -7,7 +7,6 @@ import (
"testing"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -17,16 +16,10 @@ func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestNoBlob(t *testing.T) {
testlib.AssertSkipped(t, Pipe{}.Publish(context.New(config.Project{})))
}
func TestDefaultsNoConfig(t *testing.T) {
errorString := "bucket or provider cannot be empty"
ctx := context.New(config.Project{
Blobs: []config.Blob{
{},
},
Blobs: []config.Blob{{}},
})
require.EqualError(t, Pipe{}.Default(ctx), errorString)
}
@@ -306,6 +299,19 @@ func TestURL(t *testing.T) {
})
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Blobs: []config.Blob{{}},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func setEnv(env map[string]string) {
for k, v := range env {
os.Setenv(k, v)

View File

@@ -23,7 +23,7 @@ import (
_ "gocloud.dev/blob/gcsblob"
_ "gocloud.dev/blob/s3blob"
// import the secrets packages we want to be able to open:.
// import the secrets packages we want to be able to be used.
_ "gocloud.dev/secrets/awskms"
_ "gocloud.dev/secrets/azurekeyvault"
_ "gocloud.dev/secrets/gcpkms"
@@ -87,7 +87,7 @@ func doUpload(ctx *context.Context, conf config.Blob) error {
filter = artifact.And(filter, artifact.ByIDs(conf.IDs...))
}
up := newUploader(ctx)
up := &productionUploader{}
if err := up.Open(ctx, bucketURL); err != nil {
return handleError(err, bucketURL)
}
@@ -160,13 +160,6 @@ func handleError(err error, url string) error {
}
}
func newUploader(ctx *context.Context) uploader {
if ctx.SkipPublish {
return &skipUploader{}
}
return &productionUploader{}
}
func getData(ctx *context.Context, conf config.Blob, path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
@@ -194,18 +187,6 @@ type uploader interface {
Upload(ctx *context.Context, 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) Close() error { return nil }
func (u *skipUploader) Open(_ *context.Context, _ string) error { return nil }
func (u *skipUploader) Upload(_ *context.Context, path string, _ []byte) error {
log.WithField("path", path).Warn("upload skipped because skip-publish is set")
return nil
}
// productionUploader actually do upload to.
type productionUploader struct {
bucket *blob.Bucket

View File

@@ -20,6 +20,8 @@ import (
"github.com/goreleaser/goreleaser/pkg/context"
)
const brewConfigExtra = "BrewConfig"
// ErrNoArchivesFound happens when 0 archives are found.
var ErrNoArchivesFound = errors.New("no linux/macos archives found")
@@ -33,51 +35,15 @@ type ErrTokenTypeNotImplementedForBrew struct {
}
func (e ErrTokenTypeNotImplementedForBrew) Error() string {
if e.TokenType != "" {
return fmt.Sprintf("token type %q not implemented for brew pipe", e.TokenType)
}
return "token type not implemented for brew pipe"
return fmt.Sprintf("token type %q not implemented for brew pipe", e.TokenType)
}
// Pipe for brew deployment.
type Pipe struct{}
func (Pipe) String() string {
return "homebrew tap formula"
}
func (Pipe) String() string { return "homebrew tap formula" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Brews) == 0 }
// Publish brew formula.
func (Pipe) Publish(ctx *context.Context) error {
// we keep GitHub as default for now, in line with releases
if string(ctx.TokenType) == "" {
ctx.TokenType = context.TokenTypeGitHub
}
cli, err := client.New(ctx)
if err != nil {
return err
}
return publishAll(ctx, cli)
}
func publishAll(ctx *context.Context, cli client.Client) error {
// even if one of them skips, we run them all, and then show return the skips all at once.
// this is needed so we actually create the `dist/foo.rb` file, which is useful for debugging.
skips := pipe.SkipMemento{}
for _, brew := range ctx.Config.Brews {
err := doRun(ctx, brew, cli)
if err != nil && pipe.IsSkip(err) {
skips.Remember(err)
continue
}
if err != nil {
return err
}
}
return skips.Evaluate()
}
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
for i := range ctx.Config.Brews {
brew := &ctx.Config.Brews[i]
@@ -106,22 +72,95 @@ func (Pipe) Default(ctx *context.Context) error {
return nil
}
func doRun(ctx *context.Context, brew config.Homebrew, cl client.Client) error {
if brew.Tap.Name == "" {
return pipe.ErrSkipDisabledPipe
func (Pipe) Run(ctx *context.Context) error {
cli, err := client.New(ctx)
if err != nil {
return err
}
if brew.Tap.Token != "" {
token, err := tmpl.New(ctx).ApplySingleEnvOnly(brew.Tap.Token)
return runAll(ctx, cli)
}
// Publish brew formula.
func (Pipe) Publish(ctx *context.Context) error {
// we keep GitHub as default for now, in line with releases
if string(ctx.TokenType) == "" {
ctx.TokenType = context.TokenTypeGitHub
}
cli, err := client.New(ctx)
if err != nil {
return err
}
return publishAll(ctx, cli)
}
func runAll(ctx *context.Context, cli client.Client) error {
for _, brew := range ctx.Config.Brews {
err := doRun(ctx, brew, cli)
if err != nil {
return err
}
log.Debug("using custom token to publish homebrew formula")
c, err := client.NewWithToken(ctx, token)
}
return nil
}
func publishAll(ctx *context.Context, cli client.Client) error {
// even if one of them skips, we run them all, and then show return the skips all at once.
// this is needed so we actually create the `dist/foo.rb` file, which is useful for debugging.
skips := pipe.SkipMemento{}
for _, formula := range ctx.Artifacts.Filter(artifact.ByType(artifact.BrewTap)).List() {
err := doPublish(ctx, formula, cli)
if err != nil && pipe.IsSkip(err) {
skips.Remember(err)
continue
}
if err != nil {
return err
}
cl = c
}
return skips.Evaluate()
}
func doPublish(ctx *context.Context, formula *artifact.Artifact, cl client.Client) error {
brew := formula.Extra[brewConfigExtra].(config.Homebrew)
var err error
cl, err = client.NewIfToken(ctx, cl, brew.Tap.Token)
if err != nil {
return err
}
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")
}
repo := client.RepoFromRef(brew.Tap)
gpath := buildFormulaPath(brew.Folder, formula.Name)
log.WithField("formula", gpath).
WithField("repo", repo.String()).
Info("pushing")
msg, err := tmpl.New(ctx).Apply(brew.CommitMessageTemplate)
if err != nil {
return err
}
content, err := os.ReadFile(formula.Path)
if err != nil {
return err
}
return cl.CreateFile(ctx, brew.CommitAuthor, repo, content, gpath, msg)
}
func doRun(ctx *context.Context, brew config.Homebrew, cl client.Client) error {
if brew.Tap.Name == "" {
return pipe.Skip("brew tap name is not set")
}
// TODO: properly cover this with tests
@@ -168,28 +207,16 @@ func doRun(ctx *context.Context, brew config.Homebrew, cl client.Client) error {
return fmt.Errorf("failed to write brew formula: %w", err)
}
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.BrewTap,
Extra: map[string]interface{}{
brewConfigExtra: brew,
},
})
repo := client.RepoFromRef(brew.Tap)
gpath := buildFormulaPath(brew.Folder, filename)
log.WithField("formula", gpath).
WithField("repo", repo.String()).
Info("pushing")
msg, err := tmpl.New(ctx).Apply(brew.CommitMessageTemplate)
if err != nil {
return err
}
return cl.CreateFile(ctx, brew.CommitAuthor, repo, []byte(content), gpath, msg)
return nil
}
func buildFormulaPath(folder, filename string) string {

View File

@@ -126,10 +126,10 @@ func TestSplit(t *testing.T) {
require.Equal(t, []string{}, parts)
}
func TestRunPipe(t *testing.T) {
func TestFullPipe(t *testing.T) {
type testcase struct {
prepare func(ctx *context.Context)
expectedError string
prepare func(ctx *context.Context)
expectedPublishError string
}
for name, tt := range map[string]testcase{
"default": {
@@ -185,7 +185,7 @@ func TestRunPipe(t *testing.T) {
ctx.Config.Brews[0].Tap.Name = "test"
ctx.Config.Brews[0].CommitMessageTemplate = "{{ .Asdsa }"
},
expectedError: `template: tmpl:1: unexpected "}" in operand`,
expectedPublishError: `template: tmpl:1: unexpected "}" in operand`,
},
} {
t.Run(name, func(t *testing.T) {
@@ -250,12 +250,13 @@ func TestRunPipe(t *testing.T) {
client := &DummyClient{}
distFile := filepath.Join(folder, name+".rb")
if tt.expectedError != "" {
require.EqualError(t, doRun(ctx, ctx.Config.Brews[0], client), tt.expectedError)
require.NoError(t, runAll(ctx, client))
if tt.expectedPublishError != "" {
require.EqualError(t, publishAll(ctx, client), tt.expectedPublishError)
return
}
require.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, publishAll(ctx, client))
require.True(t, client.CreatedFile)
golden.RequireEqualRb(t, []byte(client.Content))
@@ -313,7 +314,8 @@ func TestRunPipeNameTemplate(t *testing.T) {
client := &DummyClient{}
distFile := filepath.Join(folder, "foo_is_bar.rb")
require.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, runAll(ctx, client))
require.NoError(t, publishAll(ctx, client))
require.True(t, client.CreatedFile)
golden.RequireEqualRb(t, []byte(client.Content))
distBts, err := os.ReadFile(distFile)
@@ -389,6 +391,7 @@ func TestRunPipeMultipleBrewsWithSkip(t *testing.T) {
require.NoError(t, f.Close())
cli := &DummyClient{}
require.NoError(t, runAll(ctx, cli))
require.EqualError(t, publishAll(ctx, cli), `brew.skip_upload is set`)
require.True(t, cli.CreatedFile)
@@ -511,7 +514,8 @@ func TestRunPipeForMultipleArmVersions(t *testing.T) {
client := &DummyClient{}
distFile := filepath.Join(folder, name+".rb")
require.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, runAll(ctx, client))
require.NoError(t, publishAll(ctx, client))
require.True(t, client.CreatedFile)
golden.RequireEqualRb(t, []byte(client.Content))
@@ -537,7 +541,7 @@ func TestRunPipeNoBuilds(t *testing.T) {
},
}
client := &DummyClient{}
require.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
require.Equal(t, ErrNoArchivesFound, runAll(ctx, client))
require.False(t, client.CreatedFile)
}
@@ -681,22 +685,13 @@ func TestRunPipeMultipleArchivesSameOsBuild(t *testing.T) {
})
}
client := &DummyClient{}
require.Equal(t, test.expectedError, doRun(ctx, ctx.Config.Brews[0], client))
require.Equal(t, test.expectedError, runAll(ctx, client))
require.False(t, client.CreatedFile)
// clean the artifacts for the next run
ctx.Artifacts = artifact.New()
}
}
func TestRunPipeBrewNotSetup(t *testing.T) {
ctx := &context.Context{
Config: config.Project{},
}
client := &DummyClient{}
testlib.AssertSkipped(t, doRun(ctx, config.Homebrew{}, client))
require.False(t, client.CreatedFile)
}
func TestRunPipeBinaryRelease(t *testing.T) {
ctx := context.New(
config.Project{
@@ -718,7 +713,7 @@ func TestRunPipeBinaryRelease(t *testing.T) {
Type: artifact.Binary,
})
client := &DummyClient{}
require.Equal(t, ErrNoArchivesFound, doRun(ctx, ctx.Config.Brews[0], client))
require.Equal(t, ErrNoArchivesFound, runAll(ctx, client))
require.False(t, client.CreatedFile)
}
@@ -758,21 +753,21 @@ func TestRunPipeNoUpload(t *testing.T) {
assertNoPublish := func(t *testing.T) {
t.Helper()
testlib.AssertSkipped(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, runAll(ctx, client))
testlib.AssertSkipped(t, publishAll(ctx, client))
require.False(t, client.CreatedFile)
}
t.Run("skip upload", func(t *testing.T) {
ctx.Config.Release.Draft = false
t.Run("skip upload true", func(t *testing.T) {
ctx.Config.Brews[0].SkipUpload = "true"
ctx.SkipPublish = false
ctx.Semver.Prerelease = ""
assertNoPublish(t)
})
t.Run("skip publish", func(t *testing.T) {
ctx.Config.Release.Draft = false
ctx.Config.Brews[0].SkipUpload = "false"
ctx.SkipPublish = true
t.Run("skip upload auto", func(t *testing.T) {
ctx.Config.Brews[0].SkipUpload = "auto"
ctx.Semver.Prerelease = "beta1"
assertNoPublish(t)
})
// TODO: skip when ctx.Config.Release.Draft=true ?
}
func TestRunEmptyTokenType(t *testing.T) {
@@ -807,7 +802,7 @@ func TestRunEmptyTokenType(t *testing.T) {
},
})
client := &DummyClient{}
require.NoError(t, doRun(ctx, ctx.Config.Brews[0], client))
require.NoError(t, runAll(ctx, client))
}
func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
@@ -843,7 +838,7 @@ func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
},
})
client := &DummyClient{NotImplemented: true}
require.Equal(t, ErrTokenTypeNotImplementedForBrew{TokenType: "gitea"}, doRun(ctx, ctx.Config.Brews[0], client))
require.EqualError(t, runAll(ctx, client), `token type "gitea" not implemented for brew pipe`)
}
func TestDefault(t *testing.T) {
@@ -922,3 +917,27 @@ func (dc *DummyClient) CreateFile(ctx *context.Context, commitAuthor config.Comm
func (dc *DummyClient) Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error) {
return
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Brews: []config.Homebrew{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func TestRunSkipNoName(t *testing.T) {
ctx := context.New(config.Project{
Brews: []config.Homebrew{{}},
})
client := &DummyClient{}
testlib.AssertSkipped(t, runAll(ctx, client))
}

View File

@@ -202,20 +202,14 @@ func buildOptionsForTarget(ctx *context.Context, build config.Build, target stri
if build.NoUniqueDistDir {
dir = ""
}
path, err := filepath.Abs(
filepath.Join(
ctx.Config.Dist,
dir,
name,
),
)
path, err := filepath.Abs(filepath.Join(ctx.Config.Dist, dir, name))
if err != nil {
return nil, err
}
buildOpts.Path = path
buildOpts.Name = name
log.WithField("binary", buildOpts.Path).Info("building")
buildOpts.Name = name
return &buildOpts, nil
}

View File

@@ -12,7 +12,6 @@ import (
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -23,9 +22,8 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction")
// Pipe for checksums.
type Pipe struct{}
func (Pipe) String() string {
return "generating changelog"
}
func (Pipe) String() string { return "generating changelog" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Changelog.Skip || ctx.Snapshot }
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
@@ -35,12 +33,6 @@ func (Pipe) Run(ctx *context.Context) error {
}
ctx.ReleaseNotes = notes
if ctx.Config.Changelog.Skip {
return pipe.ErrSkipDisabledPipe
}
if ctx.Snapshot {
return pipe.Skip("not available for snapshots")
}
if ctx.ReleaseNotes != "" {
return nil
}

View File

@@ -32,29 +32,12 @@ func TestTemplatedChangelogProvidedViaFlag(t *testing.T) {
require.Equal(t, "c0ff33 coffeee v0.0.1\n", ctx.ReleaseNotes)
}
func TestChangelogProvidedViaFlagAndSkipEnabled(t *testing.T) {
ctx := context.New(config.Project{
Changelog: config.Changelog{
Skip: true,
},
})
ctx.ReleaseNotesFile = "testdata/changes.md"
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
require.Equal(t, "c0ff33 coffeee\n", ctx.ReleaseNotes)
}
func TestChangelogProvidedViaFlagDoesntExist(t *testing.T) {
ctx := context.New(config.Project{})
ctx.ReleaseNotesFile = "testdata/changes.nope"
require.EqualError(t, Pipe{}.Run(ctx), "open testdata/changes.nope: no such file or directory")
}
func TestChangelogSkip(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Config.Changelog.Skip = true
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
}
func TestReleaseHeaderProvidedViaFlagDoesntExist(t *testing.T) {
ctx := context.New(config.Project{})
ctx.ReleaseHeaderFile = "testdata/header.nope"
@@ -67,12 +50,6 @@ func TestReleaseFooterProvidedViaFlagDoesntExist(t *testing.T) {
require.EqualError(t, Pipe{}.Run(ctx), "open testdata/footer.nope: no such file or directory")
}
func TestSnapshot(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Snapshot = true
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
}
func TestChangelog(t *testing.T) {
folder := testlib.Mktmp(t)
testlib.GitInit(t)
@@ -448,3 +425,25 @@ func TestChangeLogWithoutReleaseFooter(t *testing.T) {
require.Contains(t, ctx.ReleaseNotes, "## Changelog")
require.Equal(t, rune(ctx.ReleaseNotes[len(ctx.ReleaseNotes)-1]), '\n')
}
func TestSkip(t *testing.T) {
t.Run("skip on snapshot", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Snapshot = true
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("skip", func(t *testing.T) {
ctx := context.New(config.Project{
Changelog: config.Changelog{
Skip: true,
},
})
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -12,7 +12,6 @@ import (
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/extrafiles"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/semerrgroup"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
@@ -21,9 +20,8 @@ import (
// Pipe for checksums.
type Pipe struct{}
func (Pipe) String() string {
return "calculating checksums"
}
func (Pipe) String() string { return "calculating checksums" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Checksum.Disable }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -38,9 +36,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Run the pipe.
func (Pipe) Run(ctx *context.Context) (err error) {
if ctx.Config.Checksum.Disable {
return pipe.ErrSkipDisabledPipe
}
filter := artifact.Or(
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary),

View File

@@ -7,8 +7,6 @@ import (
"testing"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -103,21 +101,6 @@ func TestPipe(t *testing.T) {
}
}
func TestPipeSkipTrue(t *testing.T) {
folder := t.TempDir()
ctx := context.New(
config.Project{
Dist: folder,
Checksum: config.Checksum{
Disable: true,
},
},
)
err := Pipe{}.Run(ctx)
testlib.AssertSkipped(t, err)
require.EqualError(t, err, pipe.ErrSkipDisabledPipe.Error())
}
func TestPipeFileNotExist(t *testing.T) {
folder := t.TempDir()
ctx := context.New(
@@ -342,4 +325,19 @@ func TestExtraFilesNoMatch(t *testing.T) {
require.EqualError(t, Pipe{}.Run(ctx), `globbing failed for pattern ./nope/nope.txt: matching "./nope/nope.txt": file does not exist`)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
ctx := context.New(config.Project{
Checksum: config.Checksum{
Disable: true,
},
})
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
require.False(t, Pipe{}.Skip(context.New(config.Project{})))
})
}
// TODO: add tests for LinuxPackage and UploadableSourceArchive

View File

@@ -3,7 +3,6 @@ package custompublishers
import (
"github.com/goreleaser/goreleaser/internal/exec"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -11,15 +10,10 @@ import (
type Pipe struct{}
// String returns the description of the pipe.
func (Pipe) String() string {
return "custom publisher"
}
func (Pipe) String() string { return "custom publisher" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Publishers) == 0 }
// Publish artifacts.
func (Pipe) Publish(ctx *context.Context) error {
if len(ctx.Config.Publishers) == 0 {
return pipe.ErrSkipDisabledPipe
}
return exec.Execute(ctx, ctx.Config.Publishers)
}

View File

@@ -0,0 +1,38 @@
package custompublishers
import (
"testing"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)
func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Publishers: []config.Publisher{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func TestPublish(t *testing.T) {
require.NoError(t, Pipe{}.Publish(context.New(config.Project{
Publishers: []config.Publisher{
{
Cmd: "echo",
},
},
})))
}

View File

@@ -7,7 +7,9 @@ import (
"strings"
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
"github.com/goreleaser/goreleaser/internal/middleware/logging"
"github.com/goreleaser/goreleaser/internal/middleware/skip"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/goreleaser/goreleaser/pkg/defaults"
@@ -16,9 +18,7 @@ import (
// Pipe that sets the defaults.
type Pipe struct{}
func (Pipe) String() string {
return "setting defaults"
}
func (Pipe) String() string { return "setting defaults" }
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
@@ -40,10 +40,13 @@ func (Pipe) Run(ctx *context.Context) error {
ctx.Config.GiteaURLs.Download = strings.ReplaceAll(apiURL, "/api/v1", "")
}
for _, defaulter := range defaults.Defaulters {
if err := middleware.Logging(
defaulter.String(),
middleware.ErrHandler(defaulter.Default),
middleware.ExtraPadding,
if err := skip.Maybe(
defaulter,
logging.Log(
defaulter.String(),
errhandler.Handle(defaulter.Default),
logging.ExtraPadding,
),
)(ctx); err != nil {
return err
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/DisgoOrg/disgohook/api"
"github.com/apex/log"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -22,7 +21,8 @@ const (
type Pipe struct{}
func (Pipe) String() string { return "discord" }
func (Pipe) String() string { return "discord" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Discord.Enabled }
type Config struct {
WebhookID string `env:"DISCORD_WEBHOOK_ID,notEmpty"`
@@ -46,13 +46,6 @@ func (p Pipe) Default(ctx *context.Context) error {
}
func (p Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Discord.Enabled {
return pipe.ErrSkipDisabledPipe
}
msg, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Discord.MessageTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to discord: %w", err)

View File

@@ -3,7 +3,6 @@ package discord
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -19,17 +18,10 @@ func TestDefault(t *testing.T) {
require.Equal(t, ctx.Config.Announce.Discord.MessageTemplate, defaultMessageTemplate)
}
func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
func TestAnnounceInvalidTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Discord: config.Discord{
Enabled: true,
MessageTemplate: "{{ .Foo }",
},
},
@@ -40,23 +32,26 @@ func TestAnnounceInvalidTemplate(t *testing.T) {
func TestAnnounceMissingEnv(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Discord: config.Discord{
Enabled: true,
},
Discord: config.Discord{},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to discord: env: environment variable "DISCORD_WEBHOOK_ID" should not be empty`)
}
func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Discord: config.Discord{
Enabled: true,
},
},
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Discord: config.Discord{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

View File

@@ -1,7 +1,6 @@
package docker
import (
"errors"
"fmt"
"io/ioutil"
"os"
@@ -32,9 +31,8 @@ const (
// Pipe for docker.
type Pipe struct{}
func (Pipe) String() string {
return "docker images"
}
func (Pipe) String() string { return "docker images" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Dockers) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -89,19 +87,8 @@ func validateImager(use string) error {
return fmt.Errorf("docker: invalid use: %s, valid options are %v", use, valid)
}
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
if len(ctx.Config.Dockers) == 0 || len(ctx.Config.Dockers[0].ImageTemplates) == 0 {
return pipe.ErrSkipDisabledPipe
}
return doRun(ctx)
}
// Publish the docker images.
func (Pipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
images := ctx.Artifacts.Filter(artifact.ByType(artifact.PublishableDockerImage)).List()
for _, image := range images {
if err := dockerPush(ctx, image); err != nil {
@@ -111,7 +98,8 @@ func (Pipe) Publish(ctx *context.Context) error {
return nil
}
func doRun(ctx *context.Context) error {
// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
g := semerrgroup.NewSkipAware(semerrgroup.New(ctx.Parallelism))
for _, docker := range ctx.Config.Dockers {
docker := docker
@@ -148,6 +136,10 @@ func process(ctx *context.Context, docker config.Docker, artifacts []*artifact.A
return err
}
if len(images) == 0 {
return pipe.Skip("no image templates found")
}
log := log.WithField("image", images[0])
log.Debug("tempdir: " + tmp)
@@ -220,10 +212,6 @@ func processImageTemplates(ctx *context.Context, docker config.Docker) ([]string
images = append(images, image)
}
if len(images) == 0 {
return images, errors.New("no image templates found")
}
return images, nil
}

View File

@@ -1176,18 +1176,14 @@ func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestNoDockers(t *testing.T) {
require.True(t, pipe.IsSkip(Pipe{}.Run(context.New(config.Project{}))))
}
func TestNoDockerWithoutImageName(t *testing.T) {
require.True(t, pipe.IsSkip(Pipe{}.Run(context.New(config.Project{
testlib.AssertSkipped(t, Pipe{}.Run(context.New(config.Project{
Dockers: []config.Docker{
{
Goos: "linux",
},
},
}))))
})))
}
func TestDefault(t *testing.T) {
@@ -1381,7 +1377,7 @@ func Test_processImageTemplates(t *testing.T) {
},
},
}
ctx.SkipPublish = true
ctx.Env = map[string]string{
"FOO": "123",
}
@@ -1410,3 +1406,31 @@ func Test_processImageTemplates(t *testing.T) {
"gcr.io/image:v1.0",
}, images)
}
func TestSkip(t *testing.T) {
t.Run("image", func(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Dockers: []config.Docker{{}},
})
require.False(t, Pipe{}.Skip(ctx))
})
})
t.Run("manifest", func(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, ManifestPipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
DockerManifests: []config.DockerManifest{{}},
})
require.False(t, ManifestPipe{}.Skip(ctx))
})
})
}

View File

@@ -19,9 +19,8 @@ import (
// allowing to publish multi-arch docker images.
type ManifestPipe struct{}
func (ManifestPipe) String() string {
return "docker manifests"
}
func (ManifestPipe) String() string { return "docker manifests" }
func (ManifestPipe) Skip(ctx *context.Context) bool { return len(ctx.Config.DockerManifests) == 0 }
// Default sets the pipe defaults.
func (ManifestPipe) Default(ctx *context.Context) error {
@@ -43,9 +42,6 @@ func (ManifestPipe) Default(ctx *context.Context) error {
// Publish the docker manifests.
func (ManifestPipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
g := semerrgroup.NewSkipAware(semerrgroup.New(1))
for _, manifest := range ctx.Config.DockerManifests {
manifest := manifest

View File

@@ -27,9 +27,7 @@ const (
// Pipe for env.
type Pipe struct{}
func (Pipe) String() string {
return "loading go mod information"
}
func (Pipe) String() string { return "loading go mod information" }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -53,7 +51,8 @@ func (Pipe) Run(ctx *context.Context) error {
ctx.ModulePath = result
if !ctx.Config.GoMod.Proxy {
return pipe.ErrSkipDisabledPipe
// TODO: check this on Skip?
return pipe.Skip("proxying not enabled")
}
if ctx.Snapshot {

View File

@@ -1,2 +0,0 @@
// Package milestone implements Pipe and manages VCS milestones.
package milestone

View File

@@ -1,3 +1,4 @@
// Package milestone implements Pipe and manages VCS milestones.
package milestone
import (
@@ -6,7 +7,6 @@ import (
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -15,16 +15,11 @@ const defaultNameTemplate = "{{ .Tag }}"
// Pipe for milestone.
type Pipe struct{}
func (Pipe) String() string {
return "milestones"
}
func (Pipe) String() string { return "milestones" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Milestones) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
if len(ctx.Config.Milestones) == 0 {
ctx.Config.Milestones = append(ctx.Config.Milestones, config.Milestone{})
}
for i := range ctx.Config.Milestones {
milestone := &ctx.Config.Milestones[i]
@@ -48,9 +43,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Publish the release.
func (Pipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
c, err := client.New(ctx)
if err != nil {
return err
@@ -63,7 +55,7 @@ func doPublish(ctx *context.Context, vcsClient client.Client) error {
milestone := &ctx.Config.Milestones[i]
if !milestone.Close {
return pipe.ErrSkipDisabledPipe
return pipe.Skip("closing not enabled")
}
name, err := tmpl.New(ctx).Apply(milestone.NameTemplate)

View File

@@ -41,7 +41,9 @@ func TestDefaultWithRepoRemote(t *testing.T) {
testlib.GitInit(t)
testlib.GitRemoteAdd(t, "git@github.com:githubowner/githubrepo.git")
ctx := context.New(config.Project{})
ctx := context.New(config.Project{
Milestones: []config.Milestone{{}},
})
ctx.TokenType = context.TokenTypeGitHub
require.NoError(t, Pipe{}.Default(ctx))
require.Equal(t, "githubrepo", ctx.Config.Milestones[0].Repo.Name)
@@ -65,7 +67,9 @@ func TestDefaultWithNameTemplate(t *testing.T) {
func TestDefaultWithoutGitRepo(t *testing.T) {
testlib.Mktmp(t)
ctx := &context.Context{
Config: config.Project{},
Config: config.Project{
Milestones: []config.Milestone{{}},
},
}
ctx.TokenType = context.TokenTypeGitHub
require.EqualError(t, Pipe{}.Default(ctx), "current folder is not a git repository")
@@ -75,7 +79,9 @@ func TestDefaultWithoutGitRepo(t *testing.T) {
func TestDefaultWithoutGitRepoOrigin(t *testing.T) {
testlib.Mktmp(t)
ctx := &context.Context{
Config: config.Project{},
Config: config.Project{
Milestones: []config.Milestone{{}},
},
}
ctx.TokenType = context.TokenTypeGitHub
testlib.GitInit(t)
@@ -86,7 +92,9 @@ func TestDefaultWithoutGitRepoOrigin(t *testing.T) {
func TestDefaultWithoutGitRepoSnapshot(t *testing.T) {
testlib.Mktmp(t)
ctx := &context.Context{
Config: config.Project{},
Config: config.Project{
Milestones: []config.Milestone{{}},
},
}
ctx.TokenType = context.TokenTypeGitHub
ctx.Snapshot = true
@@ -97,7 +105,7 @@ func TestDefaultWithoutGitRepoSnapshot(t *testing.T) {
func TestDefaultWithoutNameTemplate(t *testing.T) {
ctx := &context.Context{
Config: config.Project{
Milestones: []config.Milestone{},
Milestones: []config.Milestone{{}},
},
}
require.NoError(t, Pipe{}.Default(ctx))
@@ -185,6 +193,21 @@ func TestPublishCloseFailOnError(t *testing.T) {
require.Equal(t, "", client.ClosedMilestone)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Milestones: []config.Milestone{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
type DummyClient struct {
ClosedMilestone string
FailToCloseMilestone bool

View File

@@ -30,9 +30,8 @@ const defaultNameTemplate = "{{ .PackageName }}_{{ .Version }}_{{ .Os }}_{{ .Arc
// Pipe for nfpm packaging.
type Pipe struct{}
func (Pipe) String() string {
return "linux packages"
}
func (Pipe) String() string { return "linux packages" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.NFPMs) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {

View File

@@ -1123,6 +1123,21 @@ func TestBinDirTemplating(t *testing.T) {
}
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
NFPMs: []config.NFPM{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func sources(contents files.Contents) []string {
result := make([]string, 0, len(contents))
for _, f := range contents {

View File

@@ -25,31 +25,14 @@ var ErrSkipSignEnabled = Skip("artifact signing is disabled")
// It means that the part of a Piper that validates some things was not run.
var ErrSkipValidateEnabled = Skip("validation is disabled")
// ErrSkipDisabledPipe happens when a pipe is skipped because it is not configured.
var ErrSkipDisabledPipe = ErrSkip{
reason: "pipe not configured/disabled",
expected: true,
}
// IsSkip returns true if the error is an ErrSkip.
func IsSkip(err error) bool {
return errors.As(err, &ErrSkip{})
}
// IsExpectedSkip returns true if the given error is ErrSkip and if it is an
// expected skip.
func IsExpectedSkip(err error) bool {
skipErr := ErrSkip{}
if !errors.As(err, &skipErr) {
return false
}
return skipErr.expected
}
// ErrSkip occurs when a pipe is skipped for some reason.
type ErrSkip struct {
reason string
expected bool
reason string
}
// Error implements the error interface. returns the reason the pipe was skipped.

View File

@@ -16,15 +16,9 @@ func TestSkipPipe(t *testing.T) {
func TestIsSkip(t *testing.T) {
require.True(t, IsSkip(Skip("whatever")))
require.True(t, IsSkip(ErrSkipDisabledPipe))
require.False(t, IsSkip(errors.New("nope")))
}
func TestIsExpectedSkip(t *testing.T) {
require.True(t, IsSkip(ErrSkipDisabledPipe))
require.True(t, IsSkip(Skip("nope")))
}
func TestSkipMemento(t *testing.T) {
m := SkipMemento{}
m.Remember(Skip("foo"))

View File

@@ -4,7 +4,9 @@ package publish
import (
"fmt"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
"github.com/goreleaser/goreleaser/internal/middleware/logging"
"github.com/goreleaser/goreleaser/internal/middleware/skip"
"github.com/goreleaser/goreleaser/internal/pipe/artifactory"
"github.com/goreleaser/goreleaser/internal/pipe/blob"
"github.com/goreleaser/goreleaser/internal/pipe/brew"
@@ -19,13 +21,6 @@ import (
"github.com/goreleaser/goreleaser/pkg/context"
)
// Pipe that publishes artifacts.
type Pipe struct{}
func (Pipe) String() string {
return "publishing"
}
// Publisher should be implemented by pipes that want to publish artifacts.
type Publisher interface {
fmt.Stringer
@@ -52,13 +47,21 @@ var publishers = []Publisher{
milestone.Pipe{},
}
// Run the pipe.
// Pipe that publishes artifacts.
type Pipe struct{}
func (Pipe) String() string { return "publishing" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.SkipPublish }
func (Pipe) Run(ctx *context.Context) error {
for _, publisher := range publishers {
if err := middleware.Logging(
publisher.String(),
middleware.ErrHandler(publisher.Publish),
middleware.ExtraPadding,
if err := skip.Maybe(
publisher,
logging.Log(
publisher.String(),
errhandler.Handle(publisher.Publish),
logging.ExtraPadding,
),
)(ctx); err != nil {
return fmt.Errorf("%s: failed to publish artifacts: %w", publisher.String(), err)
}

View File

@@ -21,3 +21,15 @@ func TestPublish(t *testing.T) {
}
require.NoError(t, Pipe{}.Run(ctx))
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipPublish = true
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
require.False(t, Pipe{}.Skip(context.New(config.Project{})))
})
}

View File

@@ -5,7 +5,6 @@ import (
"github.com/apex/log"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/vartanbeno/go-reddit/v2/reddit"
@@ -18,7 +17,8 @@ const (
type Pipe struct{}
func (Pipe) String() string { return "reddit" }
func (Pipe) String() string { return "reddit" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Reddit.Enabled }
type Config struct {
Secret string `env:"REDDIT_SECRET,notEmpty"`
@@ -38,13 +38,6 @@ func (Pipe) Default(ctx *context.Context) error {
}
func (Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Reddit.Enabled {
return pipe.ErrSkipDisabledPipe
}
title, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Reddit.TitleTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)

View File

@@ -3,7 +3,6 @@ package reddit
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -19,17 +18,10 @@ func TestDefault(t *testing.T) {
require.Equal(t, ctx.Config.Announce.Reddit.TitleTemplate, defaultTitleTemplate)
}
func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
func TestAnnounceInvalidURLTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
URLTemplate: "{{ .Foo }",
},
},
@@ -41,7 +33,6 @@ func TestAnnounceInvalidTitleTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
TitleTemplate: "{{ .Foo }",
},
},
@@ -52,23 +43,26 @@ func TestAnnounceInvalidTitleTemplate(t *testing.T) {
func TestAnnounceMissingEnv(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
},
Reddit: config.Reddit{},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to reddit: env: environment variable "REDDIT_SECRET" should not be empty`)
}
func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
},
},
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/extrafiles"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/semerrgroup"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -23,9 +22,8 @@ var ErrMultipleReleases = errors.New("multiple releases are defined. Only one is
// Pipe for github release.
type Pipe struct{}
func (Pipe) String() string {
return "github/gitlab/gitea releases"
}
func (Pipe) String() string { return "github/gitlab/gitea releases" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Release.Disable }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -101,9 +99,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Publish the release.
func (Pipe) Publish(ctx *context.Context) error {
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
c, err := client.New(ctx)
if err != nil {
return err
@@ -112,9 +107,6 @@ func (Pipe) Publish(ctx *context.Context) error {
}
func doPublish(ctx *context.Context, client client.Client) error {
if ctx.Config.Release.Disable {
return pipe.ErrSkipDisabledPipe
}
log.WithField("tag", ctx.Git.CurrentTag).
WithField("repo", ctx.Config.Release.GitHub.String()).
Info("creating or updating release")

View File

@@ -314,18 +314,6 @@ func TestRunPipeUploadRetry(t *testing.T) {
require.True(t, client.UploadedFile)
}
func TestPipeDisabled(t *testing.T) {
ctx := context.New(config.Project{
Release: config.Release{
Disable: true,
},
})
client := &DummyClient{}
testlib.AssertSkipped(t, doPublish(ctx, client))
require.False(t, client.CreatedRelease)
require.False(t, client.UploadedFile)
}
func TestDefault(t *testing.T) {
testlib.Mktmp(t)
testlib.GitInit(t)
@@ -521,6 +509,21 @@ func TestDefaultMultipleReleasesDefined(t *testing.T) {
require.EqualError(t, Pipe{}.Default(ctx), ErrMultipleReleases.Error())
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
ctx := context.New(config.Project{
Release: config.Release{
Disable: true,
},
})
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
require.False(t, Pipe{}.Skip(context.New(config.Project{})))
})
}
type DummyClient struct {
FailToCreateRelease bool
FailToUpload bool

View File

@@ -16,6 +16,7 @@ import (
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -25,11 +26,21 @@ 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.
const scoopConfigExtra = "ScoopConfig"
// Pipe that builds and publishes scoop manifests.
type Pipe struct{}
func (Pipe) String() string {
return "scoop manifests"
func (Pipe) String() string { return "scoop manifests" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Scoop.Bucket.Name == "" }
// Run creates the scoop manifest locally.
func (Pipe) Run(ctx *context.Context) error {
client, err := client.New(ctx)
if err != nil {
return err
}
return doRun(ctx, client)
}
// Publish scoop manifest.
@@ -38,7 +49,7 @@ func (Pipe) Publish(ctx *context.Context) error {
if err != nil {
return err
}
return doRun(ctx, client)
return doPublish(ctx, client)
}
// Default sets the pipe defaults.
@@ -60,22 +71,6 @@ func (Pipe) Default(ctx *context.Context) error {
func doRun(ctx *context.Context, cl client.Client) error {
scoop := ctx.Config.Scoop
if scoop.Bucket.Name == "" {
return pipe.ErrSkipDisabledPipe
}
if scoop.Bucket.Token != "" {
token, err := tmpl.New(ctx).ApplySingleEnvOnly(scoop.Bucket.Token)
if err != nil {
return err
}
log.Debug("using custom token to publish scoop manifest")
c, err := client.NewWithToken(ctx, token)
if err != nil {
return err
}
cl = c
}
// TODO: multiple archives
if ctx.Config.Archives[0].Format == "binary" {
@@ -103,18 +98,41 @@ func doRun(ctx *context.Context, cl client.Client) error {
return err
}
distPath := filepath.Join(ctx.Config.Dist, filename)
log.WithField("manifest", distPath).Info("writing")
if err := os.WriteFile(distPath, content.Bytes(), 0o644); err != nil {
path := filepath.Join(ctx.Config.Dist, filename)
log.WithField("manifest", path).Info("writing")
if err := os.WriteFile(path, content.Bytes(), 0o644); err != nil {
return fmt.Errorf("failed to write scoop manifest: %w", err)
}
ctx.Artifacts.Add(&artifact.Artifact{
Name: filename,
Path: path,
Type: artifact.ScoopManifest,
Extra: map[string]interface{}{
scoopConfigExtra: scoop,
},
})
return nil
}
func doPublish(ctx *context.Context, cl client.Client) error {
manifests := ctx.Artifacts.Filter(artifact.ByType(artifact.ScoopManifest)).List()
if len(manifests) == 0 { // should never happen
return nil
}
manifest := manifests[0]
scoop := manifest.Extra[scoopConfigExtra].(config.Scoop)
var err error
cl, err = client.NewIfToken(ctx, cl, scoop.Bucket.Token)
if err != nil {
return err
}
if strings.TrimSpace(scoop.SkipUpload) == "true" {
return pipe.Skip("scoop.skip_upload is true")
}
if ctx.SkipPublish {
return pipe.ErrSkipPublishEnabled
}
if strings.TrimSpace(scoop.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
return pipe.Skip("release is prerelease")
}
@@ -130,13 +148,18 @@ func doRun(ctx *context.Context, cl client.Client) error {
return err
}
content, err := os.ReadFile(manifest.Path)
if err != nil {
return err
}
repo := client.RepoFromRef(scoop.Bucket)
return cl.CreateFile(
ctx,
scoop.CommitAuthor,
repo,
content.Bytes(),
path.Join(scoop.Folder, filename),
content,
path.Join(scoop.Folder, manifest.Name),
commitMessage,
)
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/client"
"github.com/goreleaser/goreleaser/internal/golden"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
@@ -84,11 +83,12 @@ func Test_doRun(t *testing.T) {
}
tests := []struct {
name string
args args
artifacts []*artifact.Artifact
assertError errChecker
assert asserter
name string
args args
artifacts []*artifact.Artifact
assertRunError errChecker
assertPublishError errChecker
assert asserter
}{
{
"valid public github",
@@ -133,6 +133,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldNotErr,
shouldNotErr,
func(t *testing.T, a args) {
t.Helper()
require.Equal(t, "scoops/run-pipe.json", a.client.Path)
@@ -196,6 +197,7 @@ func Test_doRun(t *testing.T) {
},
},
shouldNotErr,
shouldNotErr,
noAssertions,
},
{
@@ -241,6 +243,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldNotErr,
shouldNotErr,
func(t *testing.T, a args) {
t.Helper()
require.Equal(t, "run-pipe.json", a.client.Path)
@@ -298,6 +301,7 @@ func Test_doRun(t *testing.T) {
},
},
shouldNotErr,
shouldNotErr,
noAssertions,
},
{
@@ -353,6 +357,7 @@ func Test_doRun(t *testing.T) {
},
},
shouldNotErr,
shouldNotErr,
noAssertions,
},
{
@@ -396,6 +401,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldErr(ErrTokenTypeNotImplementedForScoop.Error()),
shouldNotErr,
noAssertions,
},
{
@@ -440,87 +446,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1_linux_386.tar.gz", Goos: "linux", Goarch: "386"},
},
shouldErr("scoop requires a windows build"),
noAssertions,
},
{
"no scoop",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
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",
Archives: []config.Archive{
{Format: "tar.gz"},
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
},
},
&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(pipe.ErrSkipDisabledPipe.Error()),
noAssertions,
},
{
"no publish",
args{
&context.Context{
TokenType: context.TokenTypeGitHub,
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",
Archives: []config.Archive{
{Format: "tar.gz"},
},
Release: config.Release{
GitHub: config.Repo{
Owner: "test",
Name: "test",
},
},
Scoop: config.Scoop{
Bucket: config.RepoRef{
Owner: "test",
Name: "test",
},
Description: "A run pipe test formula",
Homepage: "https://github.com/goreleaser",
},
},
SkipPublish: true,
},
&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(pipe.ErrSkipPublishEnabled.Error()),
shouldNotErr,
noAssertions,
},
{
@@ -561,6 +487,7 @@ func Test_doRun(t *testing.T) {
{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},
},
shouldNotErr,
shouldErr("release is marked as draft"),
noAssertions,
},
@@ -612,6 +539,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1-pre.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Path: file},
{Name: "foo_1.0.1-pre.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldNotErr,
shouldErr("release is prerelease"),
noAssertions,
},
@@ -657,6 +585,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1-pre.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Path: file},
{Name: "foo_1.0.1-pre.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldNotErr,
shouldErr("scoop.skip_upload is true"),
noAssertions,
},
@@ -698,6 +627,7 @@ func Test_doRun(t *testing.T) {
{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},
},
shouldNotErr,
shouldErr("release is disabled"),
noAssertions,
},
@@ -740,6 +670,7 @@ func Test_doRun(t *testing.T) {
{Name: "foo_1.0.1_windows_386.tar.gz", Goos: "windows", Goarch: "386", Path: file},
},
shouldErr("archive format is binary"),
shouldNotErr,
noAssertions,
},
}
@@ -751,7 +682,8 @@ func Test_doRun(t *testing.T) {
}
require.NoError(t, Pipe{}.Default(ctx))
tt.assertError(t, doRun(ctx, tt.args.client))
tt.assertRunError(t, doRun(ctx, tt.args.client))
tt.assertPublishError(t, doPublish(ctx, tt.args.client))
tt.assert(t, tt.args)
})
}
@@ -1052,29 +984,14 @@ func TestRunPipeScoopWithSkipUpload(t *testing.T) {
require.NoError(t, f.Close())
cli := &DummyClient{}
require.EqualError(t, doRun(ctx, cli), `scoop.skip_upload is true`)
require.NoError(t, doRun(ctx, cli))
require.EqualError(t, doPublish(ctx, cli), `scoop.skip_upload is true`)
distFile := filepath.Join(folder, ctx.Config.Scoop.Name+".json")
_, err = os.Stat(distFile)
require.NoError(t, err, "file should exist: "+distFile)
}
func TestRunPipeScoopWithSkipPublish(t *testing.T) {
folder := t.TempDir()
ctx, path := getScoopPipeSkipCtx(folder)
ctx.SkipPublish = true
f, err := os.Create(path)
require.NoError(t, err)
require.NoError(t, f.Close())
cli := &DummyClient{}
require.EqualError(t, doRun(ctx, cli), pipe.ErrSkipPublishEnabled.Error())
distFile := filepath.Join(folder, ctx.Config.Scoop.Name+".json")
require.FileExists(t, distFile)
}
func TestWrapInDirectory(t *testing.T) {
folder := t.TempDir()
file := filepath.Join(folder, "archive")
@@ -1146,6 +1063,23 @@ func TestWrapInDirectory(t *testing.T) {
golden.RequireEqualJSON(t, out.Bytes())
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Scoop: config.Scoop{
Bucket: config.RepoRef{
Name: "a",
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
type DummyClient struct {
CreatedFile bool
Content string

View File

@@ -24,9 +24,8 @@ import (
// Pipe that signs common artifacts.
type Pipe struct{}
func (Pipe) String() string {
return "signing artifacts"
}
func (Pipe) String() string { return "signing artifacts" }
func (Pipe) Skip(ctx *context.Context) bool { return ctx.SkipSign || len(ctx.Config.Signs) == 0 }
// Default sets the Pipes defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -55,10 +54,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Run executes the Pipe.
func (Pipe) Run(ctx *context.Context) error {
if ctx.SkipSign {
return pipe.ErrSkipSignEnabled
}
g := semerrgroup.New(ctx.Parallelism)
for i := range ctx.Config.Signs {
cfg := ctx.Config.Signs[i]
@@ -89,7 +84,7 @@ func (Pipe) Run(ctx *context.Context) error {
filters = append(filters, artifact.ByType(artifact.UploadableBinary))
case "package":
filters = append(filters, artifact.ByType(artifact.LinuxPackage))
case "none":
case "none": // TODO(caarlos0): this is not very useful, lets remove it.
return pipe.ErrSkipSignEnabled
default:
return fmt.Errorf("invalid list of artifacts to sign: %s", cfg.Artifacts)

View File

@@ -13,8 +13,10 @@ import (
// Pipe that signs docker images and manifests.
type DockerPipe struct{}
func (DockerPipe) String() string {
return "signing docker images"
func (DockerPipe) String() string { return "signing docker images" }
func (DockerPipe) Skip(ctx *context.Context) bool {
return ctx.SkipSign || len(ctx.Config.DockerSigns) == 0
}
// Default sets the Pipes defaults.
@@ -41,14 +43,6 @@ func (DockerPipe) Default(ctx *context.Context) error {
// Publish signs and pushes the docker images signatures.
func (DockerPipe) Publish(ctx *context.Context) error {
if ctx.SkipSign {
return pipe.ErrSkipSignEnabled
}
if ctx.SkipPublish {
return pipe.ErrSkipSignEnabled
}
g := semerrgroup.New(ctx.Parallelism)
for i := range ctx.Config.DockerSigns {
cfg := ctx.Config.DockerSigns[i]
@@ -64,7 +58,7 @@ func (DockerPipe) Publish(ctx *context.Context) error {
artifact.ByType(artifact.DockerImage),
artifact.ByType(artifact.DockerManifest),
))
case "none":
case "none": // TODO(caarlos0): remove this
return pipe.ErrSkipSignEnabled
default:
return fmt.Errorf("invalid list of artifacts to sign: %s", cfg.Artifacts)

View File

@@ -37,20 +37,6 @@ func TestDockerSignDisabled(t *testing.T) {
require.EqualError(t, err, "artifact signing is disabled")
}
func TestDockerSignSkipped(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipSign = true
err := DockerPipe{}.Publish(ctx)
require.EqualError(t, err, "artifact signing is disabled")
}
func TestDockerSignSkipPublish(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipPublish = true
err := DockerPipe{}.Publish(ctx)
require.EqualError(t, err, "artifact signing is disabled")
}
func TestDockerSignInvalidArtifacts(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Config.DockerSigns = []config.Sign{
@@ -187,3 +173,24 @@ func TestDockerSignArtifacts(t *testing.T) {
})
}
}
func TestDockerSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, DockerPipe{}.Skip(context.New(config.Project{})))
})
t.Run("skip sign", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipSign = true
require.True(t, DockerPipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
DockerSigns: []config.Sign{
{},
},
})
require.False(t, DockerPipe{}.Skip(ctx))
})
}

View File

@@ -70,13 +70,6 @@ func TestSignDisabled(t *testing.T) {
require.EqualError(t, err, "artifact signing is disabled")
}
func TestSignSkipped(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipSign = true
err := Pipe{}.Run(ctx)
require.EqualError(t, err, "artifact signing is disabled")
}
func TestSignInvalidArtifacts(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Config.Signs = []config.Sign{
@@ -630,3 +623,24 @@ func TestSeveralSignsWithTheSameID(t *testing.T) {
}
require.EqualError(t, Pipe{}.Default(ctx), "found 2 signs with the ID 'a', please fix your config")
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("skip sign", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.SkipSign = true
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Signs: []config.Sign{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -5,7 +5,6 @@ import (
"github.com/apex/log"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/slack-go/slack"
@@ -18,7 +17,8 @@ const (
type Pipe struct{}
func (Pipe) String() string { return "slack" }
func (Pipe) String() string { return "slack" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Slack.Enabled }
type Config struct {
Webhook string `env:"SLACK_WEBHOOK,notEmpty"`
@@ -35,13 +35,6 @@ func (Pipe) Default(ctx *context.Context) error {
}
func (Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Slack.Enabled {
return pipe.ErrSkipDisabledPipe
}
msg, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Slack.MessageTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to slack: %w", err)

View File

@@ -3,7 +3,6 @@ package slack
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -19,17 +18,10 @@ func TestDefault(t *testing.T) {
require.Equal(t, ctx.Config.Announce.Slack.MessageTemplate, defaultMessageTemplate)
}
func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
func TestAnnounceInvalidTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Slack: config.Slack{
Enabled: true,
MessageTemplate: "{{ .Foo }",
},
},
@@ -40,23 +32,26 @@ func TestAnnounceInvalidTemplate(t *testing.T) {
func TestAnnounceMissingEnv(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Slack: config.Slack{
Enabled: true,
},
Slack: config.Slack{},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to slack: env: environment variable "SLACK_WEBHOOK" should not be empty`)
}
func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Slack: config.Slack{
Enabled: true,
},
},
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Slack: config.Slack{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

View File

@@ -6,7 +6,6 @@ import (
"github.com/apex/log"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
gomail "gopkg.in/mail.v2"
@@ -19,7 +18,8 @@ const (
type Pipe struct{}
func (Pipe) String() string { return "reddit" }
func (Pipe) String() string { return "smtp" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.SMTP.Enabled }
type Config struct {
Host string `env:"SMTP_HOST,notEmpty"`
@@ -41,13 +41,6 @@ func (Pipe) Default(ctx *context.Context) error {
}
func (Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.SMTP.Enabled {
return pipe.ErrSkipDisabledPipe
}
subject, err := tmpl.New(ctx).Apply(ctx.Config.Announce.SMTP.SubjectTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to SMTP: %w", err)

View File

@@ -0,0 +1,43 @@
package smtp
import (
"testing"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)
func TestStringer(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
SMTP: config.SMTP{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func TestDefault(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
SMTP: config.SMTP{
Enabled: true,
},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.Equal(t, defaultBodyTemplate, ctx.Config.Announce.SMTP.BodyTemplate)
require.Equal(t, defaultSubjectTemplate, ctx.Config.Announce.SMTP.SubjectTemplate)
}

View File

@@ -71,9 +71,8 @@ const defaultNameTemplate = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arc
// Pipe for snapcraft packaging.
type Pipe struct{}
func (Pipe) String() string {
return "snapcraft packages"
}
func (Pipe) String() string { return "snapcraft packages" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Snapcrafts) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {

View File

@@ -538,6 +538,21 @@ func Test_isValidArch(t *testing.T) {
}
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Snapcrafts: []config.Snapcraft{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func requireEqualFiles(tb testing.TB, a, b string) {
tb.Helper()
eq, err := gio.EqualFiles(a, b)

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -13,9 +12,8 @@ import (
// Pipe for checksums.
type Pipe struct{}
func (Pipe) String() string {
return "snapshotting"
}
func (Pipe) String() string { return "snapshotting" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Snapshot }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -26,9 +24,6 @@ func (Pipe) Default(ctx *context.Context) error {
}
func (Pipe) Run(ctx *context.Context) error {
if !ctx.Snapshot {
return pipe.ErrSkipDisabledPipe
}
name, err := tmpl.New(ctx).Apply(ctx.Config.Snapshot.NameTemplate)
if err != nil {
return fmt.Errorf("failed to generate snapshot name: %w", err)

View File

@@ -3,7 +3,6 @@ package snapshot
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -41,7 +40,6 @@ func TestSnapshotInvalidNametemplate(t *testing.T) {
NameTemplate: "{{.ShortCommit}{{{sss}}}",
},
})
ctx.Snapshot = true
require.EqualError(t, Pipe{}.Run(ctx), `failed to generate snapshot name: template: tmpl:1: unexpected "}" in operand`)
}
@@ -51,12 +49,29 @@ func TestSnapshotEmptyFinalName(t *testing.T) {
NameTemplate: "{{ .Commit }}",
},
})
ctx.Snapshot = true
ctx.Git.CurrentTag = "v1.2.3"
require.EqualError(t, Pipe{}.Run(ctx), "empty snapshot name")
}
func TestNotASnapshot(t *testing.T) {
ctx := context.New(config.Project{})
testlib.AssertSkipped(t, Pipe{}.Run(ctx))
func TestSnapshot(t *testing.T) {
ctx := context.New(config.Project{
Snapshot: config.Snapshot{
NameTemplate: "{{ incpatch .Tag }}",
},
})
ctx.Git.CurrentTag = "v1.2.3"
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(t, "v1.2.4", ctx.Version)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{})
ctx.Snapshot = true
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/git"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -19,12 +18,12 @@ func (Pipe) String() string {
return "creating source archive"
}
func (Pipe) Skip(ctx *context.Context) bool {
return !ctx.Config.Source.Enabled
}
// Run the pipe.
func (Pipe) Run(ctx *context.Context) (err error) {
if !ctx.Config.Source.Enabled {
return pipe.ErrSkipDisabledPipe
}
name, err := tmpl.New(ctx).Apply(ctx.Config.Source.NameTemplate)
if err != nil {
return err

View File

@@ -75,9 +75,20 @@ func TestInvalidNameTemplate(t *testing.T) {
}
func TestDisabled(t *testing.T) {
testlib.AssertSkipped(t, Pipe{}.Run(context.New(config.Project{})))
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
}
func TestString(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Source: config.Source{
Enabled: true,
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -6,7 +6,6 @@ import (
"github.com/apex/log"
goteamsnotify "github.com/atc0005/go-teams-notify/v2"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -20,7 +19,8 @@ const (
type Pipe struct{}
func (Pipe) String() string { return "teams" }
func (Pipe) String() string { return "teams" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Teams.Enabled }
type Config struct {
Webhook string `env:"TEAMS_WEBHOOK,notEmpty"`
@@ -43,13 +43,6 @@ func (p Pipe) Default(ctx *context.Context) error {
}
func (p Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Teams.Enabled {
return pipe.ErrSkipDisabledPipe
}
title, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Teams.TitleTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to teams: %w", err)

View File

@@ -3,7 +3,6 @@ package teams
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -19,12 +18,6 @@ func TestDefault(t *testing.T) {
require.Equal(t, ctx.Config.Announce.Teams.MessageTemplate, defaultMessageTemplate)
}
func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
func TestAnnounceInvalidTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
@@ -49,14 +42,19 @@ func TestAnnounceMissingEnv(t *testing.T) {
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to teams: env: environment variable "TEAMS_WEBHOOK" should not be empty`)
}
func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Teams: config.Teams{
Enabled: true,
},
},
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Teams: config.Teams{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/caarlos0/env/v6"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
)
@@ -16,7 +15,8 @@ const defaultMessageTemplate = `{{ .ProjectName }} {{ .Tag }} is out! Check it o
type Pipe struct{}
func (Pipe) String() string { return "twitter" }
func (Pipe) String() string { return "twitter" }
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.Announce.Twitter.Enabled }
type Config struct {
ConsumerKey string `env:"TWITTER_CONSUMER_KEY,notEmpty"`
@@ -33,13 +33,6 @@ func (Pipe) Default(ctx *context.Context) error {
}
func (Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Twitter.Enabled {
return pipe.ErrSkipDisabledPipe
}
msg, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Twitter.MessageTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to twitter: %w", err)

View File

@@ -3,7 +3,6 @@ package twitter
import (
"testing"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
@@ -19,17 +18,10 @@ func TestDefault(t *testing.T) {
require.Equal(t, ctx.Config.Announce.Twitter.MessageTemplate, defaultMessageTemplate)
}
func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
func TestAnnounceInvalidTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Twitter: config.Twitter{
Enabled: true,
MessageTemplate: "{{ .Foo }",
},
},
@@ -40,23 +32,26 @@ func TestAnnounceInvalidTemplate(t *testing.T) {
func TestAnnounceMissingEnv(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Twitter: config.Twitter{
Enabled: true,
},
Twitter: config.Twitter{},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to twitter: env: environment variable "TWITTER_CONSUMER_KEY" should not be empty`)
}
func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Twitter: config.Twitter{
Enabled: true,
},
},
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Twitter: config.Twitter{
Enabled: true,
},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

View File

@@ -14,9 +14,8 @@ import (
type Pipe struct{}
// String returns the description of the pipe.
func (Pipe) String() string {
return "http upload"
}
func (Pipe) String() string { return "http upload" }
func (Pipe) Skip(ctx *context.Context) bool { return len(ctx.Config.Uploads) == 0 }
// Default sets the pipe defaults.
func (Pipe) Default(ctx *context.Context) error {
@@ -25,10 +24,6 @@ func (Pipe) Default(ctx *context.Context) error {
// Publish artifacts.
func (Pipe) Publish(ctx *context.Context) error {
if len(ctx.Config.Uploads) == 0 {
return pipe.ErrSkipDisabledPipe
}
// Check requirements for every instance we have configured.
// If not fulfilled, we can skip this pipeline
for _, instance := range ctx.Config.Uploads {

View File

@@ -543,30 +543,6 @@ func TestRunPipe_UnparsableTarget(t *testing.T) {
require.EqualError(t, Pipe{}.Publish(ctx), `upload: upload failed: parse "://artifacts.company.com/example-repo-local/mybin/darwin/amd64/mybin": missing protocol scheme`)
}
func TestRunPipe_SkipWhenPublishFalse(t *testing.T) {
ctx := context.New(config.Project{
Uploads: []config.Upload{
{
Name: "production",
Mode: "binary",
Target: "http://artifacts.company.com/example-repo-local/{{ .ProjectName }}/{{ .Os }}/{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}",
Username: "deployuser",
},
},
Archives: []config.Archive{
{},
},
})
ctx.Env = map[string]string{
"UPLOAD_PRODUCTION_SECRET": "deployuser-secret",
}
ctx.SkipPublish = true
err := Pipe{}.Publish(ctx)
require.True(t, pipe.IsSkip(err))
require.EqualError(t, err, pipe.ErrSkipPublishEnabled.Error())
}
func TestRunPipe_DirUpload(t *testing.T) {
folder := t.TempDir()
dist := filepath.Join(folder, "dist")
@@ -608,10 +584,6 @@ func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestNoPuts(t *testing.T) {
require.True(t, pipe.IsSkip(Pipe{}.Publish(context.New(config.Project{}))))
}
func TestPutsWithoutTarget(t *testing.T) {
ctx := &context.Context{
Env: map[string]string{
@@ -741,3 +713,18 @@ func TestDefaultSet(t *testing.T) {
require.Equal(t, "custom", upload.Mode)
require.Equal(t, h.MethodPost, upload.Method)
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(context.New(config.Project{})))
})
t.Run("dont skip", func(t *testing.T) {
ctx := context.New(config.Project{
Uploads: []config.Upload{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/goreleaser/goreleaser/internal/pipe/announce"
"github.com/goreleaser/goreleaser/internal/pipe/archive"
"github.com/goreleaser/goreleaser/internal/pipe/before"
"github.com/goreleaser/goreleaser/internal/pipe/brew"
"github.com/goreleaser/goreleaser/internal/pipe/build"
"github.com/goreleaser/goreleaser/internal/pipe/changelog"
"github.com/goreleaser/goreleaser/internal/pipe/checksums"
@@ -19,6 +20,7 @@ import (
"github.com/goreleaser/goreleaser/internal/pipe/gomod"
"github.com/goreleaser/goreleaser/internal/pipe/nfpm"
"github.com/goreleaser/goreleaser/internal/pipe/publish"
"github.com/goreleaser/goreleaser/internal/pipe/scoop"
"github.com/goreleaser/goreleaser/internal/pipe/semver"
"github.com/goreleaser/goreleaser/internal/pipe/sign"
"github.com/goreleaser/goreleaser/internal/pipe/snapcraft"
@@ -59,6 +61,8 @@ var Pipeline = append(
sourcearchive.Pipe{}, // archive the source code using git-archive
nfpm.Pipe{}, // archive via fpm (deb, rpm) using "native" go impl
snapcraft.Pipe{}, // archive via snapcraft (snap)
brew.Pipe{}, // create brew tap
scoop.Pipe{}, // create scoop buckets
checksums.Pipe{}, // checksums of the files
sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images

View File

@@ -578,7 +578,7 @@ type Filters struct {
type Changelog struct {
Filters Filters `yaml:",omitempty"`
Sort string `yaml:",omitempty"`
Skip bool `yaml:",omitempty"`
Skip bool `yaml:",omitempty"` // TODO(caarlos0): rename to Disable to match other pipes
}
// EnvFiles holds paths to files that contains environment variables