mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-10 03:47:03 +02:00
454abc9a0a
See #243. Upload binaries directly instead of creating archive. This option, however currently doesn't work together with brew and fpm since they both require archived artifacts.
101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
// Package build implements Pipe and can build Go projects for
|
|
// several platforms, with pre and post hook support.
|
|
package build
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/goreleaser/goreleaser/context"
|
|
"github.com/goreleaser/goreleaser/internal/ext"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
// Pipe for build
|
|
type Pipe struct{}
|
|
|
|
// Description of the pipe
|
|
func (Pipe) Description() string {
|
|
return "Building binaries"
|
|
}
|
|
|
|
// Run the pipe
|
|
func (Pipe) Run(ctx *context.Context) error {
|
|
if err := runHook(ctx.Config.Build.Env, ctx.Config.Build.Hooks.Pre); err != nil {
|
|
return err
|
|
}
|
|
sem := make(chan bool, 4)
|
|
var g errgroup.Group
|
|
for _, target := range buildTargets(ctx) {
|
|
name, err := nameFor(ctx, target)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ctx.Archives[target.String()] = name
|
|
|
|
sem <- true
|
|
target := target
|
|
g.Go(func() error {
|
|
defer func() {
|
|
<-sem
|
|
}()
|
|
return build(ctx, name, target)
|
|
})
|
|
}
|
|
if err := g.Wait(); err != nil {
|
|
return err
|
|
}
|
|
return runHook(ctx.Config.Build.Env, ctx.Config.Build.Hooks.Post)
|
|
}
|
|
|
|
func runHook(env []string, hook string) error {
|
|
if hook == "" {
|
|
return nil
|
|
}
|
|
log.Println("Running hook", hook)
|
|
cmd := strings.Fields(hook)
|
|
return run(runtimeTarget, cmd, env)
|
|
}
|
|
|
|
func build(ctx *context.Context, name string, target buildTarget) error {
|
|
output := filepath.Join(
|
|
ctx.Config.Dist,
|
|
name,
|
|
ctx.Config.Build.Binary+ext.For(target.goos),
|
|
)
|
|
if ctx.Config.Archive.Skip {
|
|
output = filepath.Join(ctx.Config.Dist, name+ext.For(target.goos))
|
|
}
|
|
log.Println("Building", output)
|
|
cmd := []string{"go", "build"}
|
|
if ctx.Config.Build.Flags != "" {
|
|
cmd = append(cmd, strings.Fields(ctx.Config.Build.Flags)...)
|
|
}
|
|
flags, err := ldflags(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmd = append(cmd, "-ldflags="+flags, "-o", output, ctx.Config.Build.Main)
|
|
return run(target, cmd, ctx.Config.Build.Env)
|
|
}
|
|
|
|
func run(target buildTarget, command, env []string) error {
|
|
cmd := exec.Command(command[0], command[1:]...)
|
|
cmd.Env = append(cmd.Env, os.Environ()...)
|
|
cmd.Env = append(cmd.Env, env...)
|
|
cmd.Env = append(
|
|
cmd.Env,
|
|
"GOOS="+target.goos,
|
|
"GOARCH="+target.goarch,
|
|
"GOARM="+target.goarm,
|
|
)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("build failed: %s\n%v", target.PrettyString(), string(out))
|
|
}
|
|
return nil
|
|
}
|