You've already forked goreleaser
							
							
				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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							35cb87e66a
						
					
				
				
					commit
					61bead8989
				
			
							
								
								
									
										15
									
								
								cmd/build.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cmd/build.go
									
									
									
									
									
								
							| @@ -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 | ||||
| 			} | ||||
|   | ||||
| @@ -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 | ||||
| 			} | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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()) | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| package artifact | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -1,2 +0,0 @@ | ||||
| // Package middleware define middlewares for Actions. | ||||
| package middleware | ||||
| @@ -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 | ||||
							
								
								
									
										30
									
								
								internal/middleware/errhandler/error_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								internal/middleware/errhandler/error_test.go
									
									
									
									
									
										Normal 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)) | ||||
| 	}) | ||||
| } | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
| @@ -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) | ||||
							
								
								
									
										14
									
								
								internal/middleware/logging/logging_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								internal/middleware/logging/logging_test.go
									
									
									
									
									
										Normal 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)) | ||||
| } | ||||
| @@ -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)) | ||||
| } | ||||
| @@ -1,3 +1,4 @@ | ||||
| // Package middleware define middlewares for Actions. | ||||
| package middleware | ||||
|  | ||||
| import "github.com/goreleaser/goreleaser/pkg/context" | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										27
									
								
								internal/middleware/skip/skip.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								internal/middleware/skip/skip.go
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
							
								
								
									
										36
									
								
								internal/middleware/skip/skip_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								internal/middleware/skip/skip_test.go
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
| @@ -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) | ||||
| 		} | ||||
|   | ||||
| @@ -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{}))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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), | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
| } | ||||
|   | ||||
							
								
								
									
										38
									
								
								internal/pipe/custompublishers/custompublishers_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								internal/pipe/custompublishers/custompublishers_test.go
									
									
									
									
									
										Normal 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", | ||||
| 			}, | ||||
| 		}, | ||||
| 	}))) | ||||
| } | ||||
| @@ -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 | ||||
| 		} | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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)) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -1,2 +0,0 @@ | ||||
| // Package milestone implements Pipe and manages VCS milestones. | ||||
| package milestone | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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")) | ||||
|   | ||||
| @@ -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) | ||||
| 		} | ||||
|   | ||||
| @@ -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{}))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
							
								
								
									
										43
									
								
								internal/pipe/smtp/smtp_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								internal/pipe/smtp/smtp_test.go
									
									
									
									
									
										Normal 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) | ||||
| } | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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)) | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user