You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +02:00 
			
		
		
		
	multiple binaries on naked release: fpm working
This commit is contained in:
		| @@ -21,13 +21,18 @@ type GitInfo struct { | ||||
| 	Commit     string | ||||
| } | ||||
|  | ||||
| // Binary with pretty name and path | ||||
| type Binary struct { | ||||
| 	Name, Path string | ||||
| } | ||||
|  | ||||
| // Context carries along some data through the pipes | ||||
| type Context struct { | ||||
| 	ctx.Context | ||||
| 	Config       config.Project | ||||
| 	Token        string | ||||
| 	Git          GitInfo | ||||
| 	Folders      map[string]string | ||||
| 	Binaries     map[string]map[string][]Binary | ||||
| 	Artifacts    []string | ||||
| 	ReleaseNotes string | ||||
| 	Version      string | ||||
| @@ -38,7 +43,7 @@ type Context struct { | ||||
| } | ||||
|  | ||||
| var artifactsLock sync.Mutex | ||||
| var foldersLock sync.Mutex | ||||
| var binariesLock sync.Mutex | ||||
|  | ||||
| // AddArtifact adds a file to upload list | ||||
| func (ctx *Context) AddArtifact(file string) { | ||||
| @@ -49,19 +54,32 @@ func (ctx *Context) AddArtifact(file string) { | ||||
| 	log.WithField("artifact", file).Info("new artifact") | ||||
| } | ||||
|  | ||||
| // AddFolder adds a built binary to the current context | ||||
| func (ctx *Context) AddFolder(key, folder string) { | ||||
| 	foldersLock.Lock() | ||||
| 	defer foldersLock.Unlock() | ||||
| 	ctx.Folders[key] = folder | ||||
| 	log.WithField("key", key).WithField("folder", folder).Info("new folder") | ||||
| // AddBinary adds a built binary to the current context | ||||
| func (ctx *Context) AddBinary(key, group, name, path string) { | ||||
| 	binariesLock.Lock() | ||||
| 	defer binariesLock.Unlock() | ||||
| 	if ctx.Binaries[key] == nil { | ||||
| 		ctx.Binaries[key] = map[string][]Binary{} | ||||
| 	} | ||||
| 	ctx.Binaries[key][group] = append( | ||||
| 		ctx.Binaries[key][group], | ||||
| 		Binary{ | ||||
| 			Name: name, | ||||
| 			Path: path, | ||||
| 		}, | ||||
| 	) | ||||
| 	log.WithField("key", key). | ||||
| 		WithField("group", group). | ||||
| 		WithField("name", name). | ||||
| 		WithField("path", path). | ||||
| 		Info("new binary") | ||||
| } | ||||
|  | ||||
| // New context | ||||
| func New(config config.Project) *Context { | ||||
| 	return &Context{ | ||||
| 		Context: ctx.Background(), | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Context:  ctx.Background(), | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string]map[string][]Binary{}, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -32,13 +32,13 @@ func TestMultipleArtifactAdds(t *testing.T) { | ||||
| 	assert.Contains(ctx.Artifacts, "a", "b", "c", "d") | ||||
| } | ||||
|  | ||||
| func TestMultipleFolderAdds(t *testing.T) { | ||||
| func TestMultipleBinaryAdds(t *testing.T) { | ||||
| 	var assert = assert.New(t) | ||||
| 	var list = map[string]string{ | ||||
| 		"key-a": "folder/a", | ||||
| 		"key-b": "folder/b", | ||||
| 		"key-c": "folder/c", | ||||
| 		"key-d": "folder/d", | ||||
| 		"a": "folder/a", | ||||
| 		"b": "folder/b", | ||||
| 		"c": "folder/c", | ||||
| 		"d": "folder/d", | ||||
| 	} | ||||
| 	var ctx = New(config.Project{ | ||||
| 		Dist: "dist", | ||||
| @@ -48,10 +48,11 @@ func TestMultipleFolderAdds(t *testing.T) { | ||||
| 		f := f | ||||
| 		k := k | ||||
| 		g.Go(func() error { | ||||
| 			ctx.AddFolder(k, f) | ||||
| 			ctx.AddBinary("linuxamd64", k, f) | ||||
| 			return nil | ||||
| 		}) | ||||
| 	} | ||||
| 	assert.NoError(g.Wait()) | ||||
| 	assert.Len(ctx.Folders, len(list)) | ||||
| 	assert.Len(ctx.Binaries["linuxamd64"], len(list)) | ||||
| 	assert.Len(ctx.Binaries, 1) | ||||
| } | ||||
|   | ||||
| @@ -4,9 +4,7 @@ | ||||
| package archive | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/apex/log" | ||||
| 	"github.com/goreleaser/archive" | ||||
| @@ -27,65 +25,56 @@ func (Pipe) Description() string { | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) error { | ||||
| 	var g errgroup.Group | ||||
| 	for platform, folder := range ctx.Folders { | ||||
| 		folder := folder | ||||
| 	for platform, binaries := range ctx.Binaries { | ||||
| 		platform := platform | ||||
| 		binaries := binaries | ||||
| 		g.Go(func() error { | ||||
| 			if ctx.Config.Archive.Format == "binary" { | ||||
| 				return skip(ctx, platform, folder) | ||||
| 				return skip(ctx, platform, binaries) | ||||
| 			} | ||||
| 			return create(ctx, platform, folder) | ||||
| 			return create(ctx, platform, binaries) | ||||
| 		}) | ||||
| 	} | ||||
| 	return g.Wait() | ||||
| } | ||||
|  | ||||
| func create(ctx *context.Context, platform, name string) error { | ||||
| 	var folder = filepath.Join(ctx.Config.Dist, name) | ||||
| 	var format = archiveformat.For(ctx, platform) | ||||
| 	file, err := os.Create(folder + "." + format) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	log.WithField("archive", file.Name()).Info("creating") | ||||
| 	defer func() { _ = file.Close() }() | ||||
| 	var archive = archive.New(file) | ||||
| 	defer func() { _ = archive.Close() }() | ||||
| func create(ctx *context.Context, platform string, groups map[string][]context.Binary) error { | ||||
| 	for folder, binaries := range groups { | ||||
| 		var format = archiveformat.For(ctx, platform) | ||||
| 		file, err := os.Create(folder + "." + format) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer func() { _ = file.Close() }() | ||||
| 		log.WithField("archive", file.Name()).Info("creating") | ||||
| 		var archive = archive.New(file) | ||||
| 		defer func() { _ = archive.Close() }() | ||||
|  | ||||
| 	files, err := findFiles(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, f := range files { | ||||
| 		if err = archive.Add(f, f); err != nil { | ||||
| 		files, err := findFiles(ctx) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	var basepath = filepath.Join(ctx.Config.Dist, name) | ||||
| 	binaries, err := ioutil.ReadDir(basepath) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, binary := range binaries { | ||||
| 		var path = filepath.Join(basepath, binary.Name()) | ||||
| 		if err := archive.Add(binary.Name(), path); err != nil { | ||||
| 			return err | ||||
| 		for _, f := range files { | ||||
| 			if err = archive.Add(f, f); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		for _, binary := range binaries { | ||||
| 			if err := archive.Add(binary.Name, binary.Path); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 		ctx.AddArtifact(file.Name()) | ||||
| 	} | ||||
| 	ctx.AddArtifact(file.Name()) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func skip(ctx *context.Context, platform, name string) error { | ||||
| 	var path = filepath.Join(ctx.Config.Dist, name) | ||||
| 	binaries, err := ioutil.ReadDir(path) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	log.WithField("platform", platform).Debugf("found %v binaries", len(binaries)) | ||||
| 	for _, binary := range binaries { | ||||
| 		log.WithField("binary", binary.Name()).Info("skip archiving") | ||||
| 		ctx.AddArtifact(filepath.Join(path+"/", binary.Name())) | ||||
| func skip(ctx *context.Context, platform string, groups map[string][]context.Binary) error { | ||||
| 	for _, binaries := range groups { | ||||
| 		for _, binary := range binaries { | ||||
| 			log.WithField("binary", binary.Name).Info("skip archiving") | ||||
| 			ctx.AddArtifact(binary.Path) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -10,10 +10,8 @@ import ( | ||||
| 	"text/template" | ||||
|  | ||||
| 	"github.com/apex/log" | ||||
| 	"github.com/goreleaser/goreleaser/checksum" | ||||
| 	"github.com/goreleaser/goreleaser/config" | ||||
| 	"github.com/goreleaser/goreleaser/context" | ||||
| 	"github.com/goreleaser/goreleaser/internal/archiveformat" | ||||
| 	"github.com/goreleaser/goreleaser/internal/client" | ||||
| ) | ||||
|  | ||||
| @@ -141,30 +139,31 @@ func doBuildFormula(data templateData) (bytes.Buffer, error) { | ||||
| } | ||||
|  | ||||
| func dataFor(ctx *context.Context, client client.Client) (result templateData, err error) { | ||||
| 	var folder = ctx.Folders[platform] | ||||
| 	if folder == "" { | ||||
| 		return result, ErrNoDarwin64Build | ||||
| 	} | ||||
| 	var file = folder + "." + archiveformat.For(ctx, platform) | ||||
| 	sum, err := checksum.SHA256(filepath.Join(ctx.Config.Dist, file)) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return templateData{ | ||||
| 		Name:         formulaNameFor(ctx.Config.ProjectName), | ||||
| 		Desc:         ctx.Config.Brew.Description, | ||||
| 		Homepage:     ctx.Config.Brew.Homepage, | ||||
| 		Repo:         ctx.Config.Release.GitHub, | ||||
| 		Tag:          ctx.Git.CurrentTag, | ||||
| 		Version:      ctx.Version, | ||||
| 		Caveats:      ctx.Config.Brew.Caveats, | ||||
| 		File:         file, | ||||
| 		SHA256:       sum, | ||||
| 		Dependencies: ctx.Config.Brew.Dependencies, | ||||
| 		Conflicts:    ctx.Config.Brew.Conflicts, | ||||
| 		Plist:        ctx.Config.Brew.Plist, | ||||
| 		Install:      strings.Split(ctx.Config.Brew.Install, "\n"), | ||||
| 	}, err | ||||
| 	// var folder = ctx.Binaries[platform] | ||||
| 	// if len(folder) == 0 { | ||||
| 	// 	return result, ErrNoDarwin64Build | ||||
| 	// } | ||||
| 	// var file = folder + "." + archiveformat.For(ctx, platform) | ||||
| 	// sum, err := checksum.SHA256(filepath.Join(ctx.Config.Dist, file)) | ||||
| 	// if err != nil { | ||||
| 	// 	return | ||||
| 	// } | ||||
| 	// return templateData{ | ||||
| 	// 	Name:         formulaNameFor(ctx.Config.ProjectName), | ||||
| 	// 	Desc:         ctx.Config.Brew.Description, | ||||
| 	// 	Homepage:     ctx.Config.Brew.Homepage, | ||||
| 	// 	Repo:         ctx.Config.Release.GitHub, | ||||
| 	// 	Tag:          ctx.Git.CurrentTag, | ||||
| 	// 	Version:      ctx.Version, | ||||
| 	// 	Caveats:      ctx.Config.Brew.Caveats, | ||||
| 	// 	File:         file, | ||||
| 	// 	SHA256:       sum, | ||||
| 	// 	Dependencies: ctx.Config.Brew.Dependencies, | ||||
| 	// 	Conflicts:    ctx.Config.Brew.Conflicts, | ||||
| 	// 	Plist:        ctx.Config.Brew.Plist, | ||||
| 	// 	Install:      strings.Split(ctx.Config.Brew.Install, "\n"), | ||||
| 	// }, err | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func formulaNameFor(name string) string { | ||||
|   | ||||
| @@ -74,8 +74,8 @@ func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	ctx.AddFolder(target.String(), folder) | ||||
| 	var binaryName = build.Binary + ext.For(target) | ||||
| 	var prettyName = binaryName | ||||
| 	if ctx.Config.Archive.Format == "binary" { | ||||
| 		binaryName, err = name.ForBuild(ctx, build, target) | ||||
| 		if err != nil { | ||||
| @@ -84,6 +84,7 @@ func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target | ||||
| 		binaryName = binaryName + ext.For(target) | ||||
| 	} | ||||
| 	var binary = filepath.Join(ctx.Config.Dist, folder, binaryName) | ||||
| 	ctx.AddBinary(target.String(), folder, prettyName, binary) | ||||
| 	log.WithField("binary", binary).Info("building") | ||||
| 	cmd := []string{"go", "build"} | ||||
| 	if build.Flags != "" { | ||||
|   | ||||
| @@ -39,8 +39,8 @@ func TestBuild(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.NoError(doBuild(ctx, ctx.Config.Builds[0], buildtarget.Runtime)) | ||||
| } | ||||
| @@ -73,8 +73,8 @@ func TestRunFullPipe(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
| 	assert.True(exists(binary), binary) | ||||
| @@ -107,8 +107,8 @@ func TestRunPipeFormatBinary(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
| 	assert.True(exists(binary)) | ||||
| @@ -140,8 +140,8 @@ func TestRunPipeArmBuilds(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
| 	assert.True(exists(binary), binary) | ||||
| @@ -163,8 +163,8 @@ func TestBuildFailed(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.Error(Pipe{}.Run(ctx)) | ||||
| } | ||||
| @@ -185,8 +185,8 @@ func TestRunPipeWithInvalidOS(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
| } | ||||
| @@ -222,7 +222,7 @@ func TestRunInvalidNametemplate(t *testing.T) { | ||||
| func TestRunInvalidLdflags(t *testing.T) { | ||||
| 	var assert = assert.New(t) | ||||
| 	var ctx = &context.Context{ | ||||
| 		Folders: map[string]string{}, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 		Config: config.Project{ | ||||
| 			Builds: []config.Build{ | ||||
| 				{ | ||||
| @@ -258,8 +258,8 @@ func TestRunPipeFailingHooks(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config:  config, | ||||
| 		Folders: map[string]string{}, | ||||
| 		Config:   config, | ||||
| 		Binaries: map[string][]context.Binary{}, | ||||
| 	} | ||||
| 	t.Run("pre-hook", func(t *testing.T) { | ||||
| 		ctx.Config.Builds[0].Hooks.Pre = "exit 1" | ||||
|   | ||||
| @@ -4,7 +4,6 @@ package fpm | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -31,10 +30,6 @@ func (Pipe) Run(ctx *context.Context) error { | ||||
| 		log.Info("no output formats configured, skipping") | ||||
| 		return nil | ||||
| 	} | ||||
| 	if ctx.Config.Archive.Format == "binary" { | ||||
| 		log.Info("skipped because archive format is binary") | ||||
| 		return nil | ||||
| 	} | ||||
| 	_, err := exec.LookPath("fpm") | ||||
| 	if err != nil { | ||||
| 		return ErrNoFPM | ||||
| @@ -42,17 +37,18 @@ func (Pipe) Run(ctx *context.Context) error { | ||||
|  | ||||
| 	var g errgroup.Group | ||||
| 	for _, format := range ctx.Config.FPM.Formats { | ||||
| 		for key, folder := range ctx.Folders { | ||||
| 			if !strings.Contains(key, "linux") { | ||||
| 				log.WithField("key", key).Debug("skipped non-linux builds for fpm") | ||||
| 		for platform, groups := range ctx.Binaries { | ||||
| 			if !strings.Contains(platform, "linux") { | ||||
| 				log.WithField("platform", platform).Debug("skipped non-linux builds for fpm") | ||||
| 				continue | ||||
| 			} | ||||
| 			folder := folder | ||||
| 			format := format | ||||
| 			arch := archFor(key) | ||||
| 			g.Go(func() error { | ||||
| 				return create(ctx, format, folder, arch) | ||||
| 			}) | ||||
| 			arch := archFor(platform) | ||||
| 			for folder, binaries := range groups { | ||||
| 				g.Go(func() error { | ||||
| 					return create(ctx, format, folder, arch, binaries) | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return g.Wait() | ||||
| @@ -65,7 +61,7 @@ func archFor(key string) string { | ||||
| 	return "x86_64" | ||||
| } | ||||
|  | ||||
| func create(ctx *context.Context, format, folder, arch string) error { | ||||
| func create(ctx *context.Context, format, folder, arch string, binaries []context.Binary) error { | ||||
| 	var path = filepath.Join(ctx.Config.Dist, folder) | ||||
| 	var file = path + "." + format | ||||
| 	log.WithField("file", file).Info("creating fpm archive") | ||||
| @@ -76,7 +72,7 @@ func create(ctx *context.Context, format, folder, arch string) error { | ||||
| 		"--name", ctx.Config.ProjectName, | ||||
| 		"--version", ctx.Version, | ||||
| 		"--architecture", arch, | ||||
| 		"--chdir", path, | ||||
| 		// "--chdir", path, | ||||
| 		"--package", file, | ||||
| 		"--force", | ||||
| 	} | ||||
| @@ -103,19 +99,16 @@ func create(ctx *context.Context, format, folder, arch string) error { | ||||
| 		options = append(options, "--conflicts", conflict) | ||||
| 	} | ||||
|  | ||||
| 	files, err := ioutil.ReadDir(path) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, file := range files { | ||||
| 		// XXX: skip non executable files here? | ||||
| 	for _, binary := range binaries { | ||||
| 		// This basically tells fpm to put the binary in the /usr/local/bin | ||||
| 		// binary=/usr/local/bin/binary | ||||
| 		log.WithField("file", file.Name()).Debug("passed binary to fpm") | ||||
| 		log.WithField("path", binary.Path). | ||||
| 			WithField("name", binary.Name). | ||||
| 			Info("passed binary to fpm") | ||||
| 		options = append(options, fmt.Sprintf( | ||||
| 			"%s=%s", | ||||
| 			file.Name(), | ||||
| 			filepath.Join("/usr/local/bin", file.Name()), | ||||
| 			binary.Path, | ||||
| 			filepath.Join("/usr/local/bin", binary.Name), | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user