You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +02:00 
			
		
		
		
	fix: break the release if archive has different binary counts for each platform (#1841)
Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							2d8823b8cf
						
					
				
				
					commit
					4471154461
				
			| @@ -4,6 +4,7 @@ | |||||||
| package archive | package archive | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| @@ -28,6 +29,11 @@ const ( | |||||||
| 	defaultBinaryNameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" | 	defaultBinaryNameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // ErrArchiveDifferentBinaryCount happens when an archive uses several builds which have different goos/goarch/etc sets, | ||||||
|  | // causing the archives for some platforms to have more binaries than others. | ||||||
|  | // GoReleaser breaks in these cases as it will only cause confusion to other users. | ||||||
|  | var ErrArchiveDifferentBinaryCount = errors.New("archive has different count of built binaries for each platform, which may cause your users confusion. Please make sure all builds used have the same set of goos/goarch/etc or split it into multiple archives") | ||||||
|  |  | ||||||
| // nolint: gochecknoglobals | // nolint: gochecknoglobals | ||||||
| var lock sync.Mutex | var lock sync.Mutex | ||||||
|  |  | ||||||
| @@ -83,15 +89,18 @@ func (Pipe) Default(ctx *context.Context) error { | |||||||
| // Run the pipe. | // Run the pipe. | ||||||
| func (Pipe) Run(ctx *context.Context) error { | func (Pipe) Run(ctx *context.Context) error { | ||||||
| 	var g = semerrgroup.New(ctx.Parallelism) | 	var g = semerrgroup.New(ctx.Parallelism) | ||||||
| 	for _, archive := range ctx.Config.Archives { | 	for i, archive := range ctx.Config.Archives { | ||||||
| 		archive := archive | 		archive := archive | ||||||
| 		var filtered = ctx.Artifacts.Filter( | 		var artifacts = ctx.Artifacts.Filter( | ||||||
| 			artifact.And( | 			artifact.And( | ||||||
| 				artifact.ByType(artifact.Binary), | 				artifact.ByType(artifact.Binary), | ||||||
| 				artifact.ByIDs(archive.Builds...), | 				artifact.ByIDs(archive.Builds...), | ||||||
| 			), | 			), | ||||||
| 		) | 		).GroupByPlatform() | ||||||
| 		for group, artifacts := range filtered.GroupByPlatform() { | 		if err := checkArtifacts(artifacts); err != nil { | ||||||
|  | 			return fmt.Errorf("invalid archive: %d: %w", i, ErrArchiveDifferentBinaryCount) | ||||||
|  | 		} | ||||||
|  | 		for group, artifacts := range artifacts { | ||||||
| 			log.Debugf("group %s has %d binaries", group, len(artifacts)) | 			log.Debugf("group %s has %d binaries", group, len(artifacts)) | ||||||
| 			artifacts := artifacts | 			artifacts := artifacts | ||||||
| 			g.Go(func() error { | 			g.Go(func() error { | ||||||
| @@ -105,6 +114,17 @@ func (Pipe) Run(ctx *context.Context) error { | |||||||
| 	return g.Wait() | 	return g.Wait() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func checkArtifacts(artifacts map[string][]*artifact.Artifact) error { | ||||||
|  | 	var lens = map[int]bool{} | ||||||
|  | 	for _, v := range artifacts { | ||||||
|  | 		lens[len(v)] = true | ||||||
|  | 	} | ||||||
|  | 	if len(lens) == 1 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return ErrArchiveDifferentBinaryCount | ||||||
|  | } | ||||||
|  |  | ||||||
| func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Artifact) error { | func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Artifact) error { | ||||||
| 	var format = packageFormat(arch, binaries[0].Goos) | 	var format = packageFormat(arch, binaries[0].Goos) | ||||||
| 	folder, err := tmpl.New(ctx). | 	folder, err := tmpl.New(ctx). | ||||||
|   | |||||||
| @@ -181,6 +181,69 @@ func TestRunPipe(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestRunPipeDifferentBinaryCount(t *testing.T) { | ||||||
|  | 	folder, back := testlib.Mktmp(t) | ||||||
|  | 	defer back() | ||||||
|  | 	var dist = filepath.Join(folder, "dist") | ||||||
|  | 	require.NoError(t, os.Mkdir(dist, 0755)) | ||||||
|  | 	for _, arch := range []string{"darwinamd64", "linuxamd64"} { | ||||||
|  | 		createFakeBinary(t, dist, arch, "bin/mybin") | ||||||
|  | 	} | ||||||
|  | 	createFakeBinary(t, dist, "darwinamd64", "bin/foobar") | ||||||
|  | 	var ctx = context.New(config.Project{ | ||||||
|  | 		Dist:        dist, | ||||||
|  | 		ProjectName: "foobar", | ||||||
|  | 		Archives: []config.Archive{ | ||||||
|  | 			{ | ||||||
|  | 				ID:           "myid", | ||||||
|  | 				Format:       "tar.gz", | ||||||
|  | 				Builds:       []string{"default", "foobar"}, | ||||||
|  | 				NameTemplate: defaultNameTemplate, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
|  | 	var darwinBuild = &artifact.Artifact{ | ||||||
|  | 		Goos:   "darwin", | ||||||
|  | 		Goarch: "amd64", | ||||||
|  | 		Name:   "bin/mybin", | ||||||
|  | 		Path:   filepath.Join(dist, "darwinamd64", "bin", "mybin"), | ||||||
|  | 		Type:   artifact.Binary, | ||||||
|  | 		Extra: map[string]interface{}{ | ||||||
|  | 			"Binary": "bin/mybin", | ||||||
|  | 			"ID":     "default", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	var darwinBuild2 = &artifact.Artifact{ | ||||||
|  | 		Goos:   "darwin", | ||||||
|  | 		Goarch: "amd64", | ||||||
|  | 		Name:   "bin/foobar", | ||||||
|  | 		Path:   filepath.Join(dist, "darwinamd64", "bin", "foobar"), | ||||||
|  | 		Type:   artifact.Binary, | ||||||
|  | 		Extra: map[string]interface{}{ | ||||||
|  | 			"Binary": "bin/foobar", | ||||||
|  | 			"ID":     "foobar", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	var linuxArmBuild = &artifact.Artifact{ | ||||||
|  | 		Goos:   "linux", | ||||||
|  | 		Goarch: "amd64", | ||||||
|  | 		Name:   "bin/mybin", | ||||||
|  | 		Path:   filepath.Join(dist, "linuxamd64", "bin", "mybin"), | ||||||
|  | 		Type:   artifact.Binary, | ||||||
|  | 		Extra: map[string]interface{}{ | ||||||
|  | 			"Binary": "bin/mybin", | ||||||
|  | 			"ID":     "default", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.Artifacts.Add(darwinBuild) | ||||||
|  | 	ctx.Artifacts.Add(darwinBuild2) | ||||||
|  | 	ctx.Artifacts.Add(linuxArmBuild) | ||||||
|  | 	ctx.Version = "0.0.1" | ||||||
|  | 	ctx.Git.CurrentTag = "v0.0.1" | ||||||
|  | 	require.EqualError(t, Pipe{}.Run(ctx), "invalid archive: 0: "+ErrArchiveDifferentBinaryCount.Error()) | ||||||
|  | } | ||||||
|  |  | ||||||
| func zipFiles(t *testing.T, path string) []string { | func zipFiles(t *testing.T, path string) []string { | ||||||
| 	f, err := os.Open(path) | 	f, err := os.Open(path) | ||||||
| 	require.NoError(t, err) | 	require.NoError(t, err) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user