1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-11-06 09:09:29 +02:00

feat: support multiple binaries on docker (#919)

* feat: support multiple binaries on docker

* test: docker: fixed to use binaries

* refactor: several docker pipe improvements

* fix: tag templates

* test: fix defaults test

* fix: breaking: remove .Binary, .Os, .Arch support from docker image_templates

* fix: lint issues
This commit is contained in:
Carlos Alexandro Becker
2019-01-11 16:27:39 -02:00
committed by GitHub
parent a0255abec6
commit cdfaae9b28
8 changed files with 312 additions and 298 deletions

View File

@@ -78,14 +78,16 @@ func TestFillPartial(t *testing.T) {
}, },
}, },
Dockers: []config.Docker{ Dockers: []config.Docker{
{Image: "a/b"}, {
ImageTemplates: []string{"a/b"},
},
}, },
}, },
} }
assert.NoError(t, Pipe{}.Run(ctx)) assert.NoError(t, Pipe{}.Run(ctx))
assert.Len(t, ctx.Config.Archive.Files, 1) assert.Len(t, ctx.Config.Archive.Files, 1)
assert.Equal(t, `bin.install "testreleaser"`, ctx.Config.Brew.Install) assert.Equal(t, `bin.install "testreleaser"`, ctx.Config.Brew.Install)
assert.NotEmpty(t, ctx.Config.Dockers[0].Binary) assert.NotEmpty(t, ctx.Config.Dockers[0].Binaries)
assert.NotEmpty(t, ctx.Config.Dockers[0].Goos) assert.NotEmpty(t, ctx.Config.Dockers[0].Goos)
assert.NotEmpty(t, ctx.Config.Dockers[0].Goarch) assert.NotEmpty(t, ctx.Config.Dockers[0].Goarch)
assert.NotEmpty(t, ctx.Config.Dockers[0].Dockerfile) assert.NotEmpty(t, ctx.Config.Dockers[0].Dockerfile)

View File

@@ -37,12 +37,23 @@ func (Pipe) Default(ctx *context.Context) error {
if docker.Image != "" { if docker.Image != "" {
deprecate.Notice("docker.image") deprecate.Notice("docker.image")
deprecate.Notice("docker.tag_templates")
if len(docker.TagTemplates) != 0 { if len(docker.TagTemplates) == 0 {
deprecate.Notice("docker.tag_templates")
} else {
docker.TagTemplates = []string{"{{ .Version }}"} docker.TagTemplates = []string{"{{ .Version }}"}
} }
for _, tag := range docker.TagTemplates {
docker.ImageTemplates = append(
docker.ImageTemplates,
fmt.Sprintf("%s:%s", docker.Image, tag),
)
}
}
if docker.Binary != "" {
deprecate.Notice("docker.binary")
docker.Binaries = append(docker.Binaries, docker.Binary)
} }
if docker.Goos == "" { if docker.Goos == "" {
@@ -56,8 +67,10 @@ func (Pipe) Default(ctx *context.Context) error {
if len(ctx.Config.Dockers) != 1 { if len(ctx.Config.Dockers) != 1 {
return nil return nil
} }
if ctx.Config.Dockers[0].Binary == "" { if len(ctx.Config.Dockers[0].Binaries) == 0 {
ctx.Config.Dockers[0].Binary = ctx.Config.Builds[0].Binary ctx.Config.Dockers[0].Binaries = []string{
ctx.Config.Builds[0].Binary,
}
} }
if ctx.Config.Dockers[0].Dockerfile == "" { if ctx.Config.Dockers[0].Dockerfile == "" {
ctx.Config.Dockers[0].Dockerfile = "Dockerfile" ctx.Config.Dockers[0].Dockerfile = "Dockerfile"
@@ -105,31 +118,39 @@ func doRun(ctx *context.Context) error {
artifact.ByGoarm(docker.Goarm), artifact.ByGoarm(docker.Goarm),
artifact.ByType(artifact.Binary), artifact.ByType(artifact.Binary),
func(a artifact.Artifact) bool { func(a artifact.Artifact) bool {
return a.ExtraOr("Binary", "").(string) == docker.Binary for _, bin := range docker.Binaries {
if a.ExtraOr("Binary", "").(string) == bin {
return true
}
}
return false
}, },
), ),
).List() ).List()
if len(binaries) != 1 { // TODO: not so good of a check, if one binary match multiple
// binaries and the other match none, this will still pass...
if len(binaries) != len(docker.Binaries) {
return fmt.Errorf( return fmt.Errorf(
"%d binaries match docker definition: %s: %s_%s_%s", "%d binaries match docker definition: %v: %s_%s_%s, should be %d",
len(binaries), len(binaries),
docker.Binary, docker.Goos, docker.Goarch, docker.Goarm, docker.Binaries, docker.Goos, docker.Goarch, docker.Goarm,
len(docker.Binaries),
) )
} }
return process(ctx, docker, binaries[0]) return process(ctx, docker, binaries)
}) })
} }
return g.Wait() return g.Wait()
} }
func process(ctx *context.Context, docker config.Docker, bin artifact.Artifact) error { func process(ctx *context.Context, docker config.Docker, bins []artifact.Artifact) error {
tmp, err := ioutil.TempDir(ctx.Config.Dist, "goreleaserdocker") tmp, err := ioutil.TempDir(ctx.Config.Dist, "goreleaserdocker")
if err != nil { if err != nil {
return errors.Wrap(err, "failed to create temporary dir") return errors.Wrap(err, "failed to create temporary dir")
} }
log.Debug("tempdir: " + tmp) log.Debug("tempdir: " + tmp)
images, err := processImageTemplates(ctx, docker, bin) images, err := processImageTemplates(ctx, docker)
if err != nil { if err != nil {
return err return err
} }
@@ -145,11 +166,13 @@ func process(ctx *context.Context, docker config.Docker, bin artifact.Artifact)
return errors.Wrapf(err, "failed to link extra file '%s'", file) return errors.Wrapf(err, "failed to link extra file '%s'", file)
} }
} }
if err := os.Link(bin.Path, filepath.Join(tmp, filepath.Base(bin.Path))); err != nil { for _, bin := range bins {
return errors.Wrap(err, "failed to link binary") if err := os.Link(bin.Path, filepath.Join(tmp, filepath.Base(bin.Path))); err != nil {
return errors.Wrap(err, "failed to link binary")
}
} }
buildFlags, err := processBuildFlagTemplates(ctx, docker, bin) buildFlags, err := processBuildFlagTemplates(ctx, docker)
if err != nil { if err != nil {
return err return err
} }
@@ -175,18 +198,11 @@ func process(ctx *context.Context, docker config.Docker, bin artifact.Artifact)
return nil return nil
} }
func processImageTemplates(ctx *context.Context, docker config.Docker, artifact artifact.Artifact) ([]string, error) { func processImageTemplates(ctx *context.Context, docker config.Docker) ([]string, error) {
if len(docker.ImageTemplates) != 0 && docker.Image != "" {
return nil, errors.New("failed to process image, use either image_templates (preferred) or image, not both")
}
// nolint:prealloc // nolint:prealloc
var images []string var images []string
for _, imageTemplate := range docker.ImageTemplates { for _, imageTemplate := range docker.ImageTemplates {
// TODO: add overrides support to config image, err := tmpl.New(ctx).Apply(imageTemplate)
image, err := tmpl.New(ctx).
WithArtifact(artifact, map[string]string{}).
Apply(imageTemplate)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to execute image template '%s'", imageTemplate) return nil, errors.Wrapf(err, "failed to execute image template '%s'", imageTemplate)
} }
@@ -194,28 +210,14 @@ func processImageTemplates(ctx *context.Context, docker config.Docker, artifact
images = append(images, image) images = append(images, image)
} }
for _, tagTemplate := range docker.TagTemplates {
imageTemplate := fmt.Sprintf("%s:%s", docker.Image, tagTemplate)
// TODO: add overrides support to config
image, err := tmpl.New(ctx).
WithArtifact(artifact, map[string]string{}).
Apply(imageTemplate)
if err != nil {
return nil, errors.Wrapf(err, "failed to execute tag template '%s'", tagTemplate)
}
images = append(images, image)
}
return images, nil return images, nil
} }
func processBuildFlagTemplates(ctx *context.Context, docker config.Docker, artifact artifact.Artifact) ([]string, error) { func processBuildFlagTemplates(ctx *context.Context, docker config.Docker) ([]string, error) {
// nolint:prealloc // nolint:prealloc
var buildFlags []string var buildFlags []string
for _, buildFlagTemplate := range docker.BuildFlagTemplates { for _, buildFlagTemplate := range docker.BuildFlagTemplates {
buildFlag, err := tmpl.New(ctx). buildFlag, err := tmpl.New(ctx).Apply(buildFlagTemplate)
WithArtifact(artifact, map[string]string{}).
Apply(buildFlagTemplate)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to process build flag template '%s'", buildFlagTemplate) return nil, errors.Wrapf(err, "failed to process build flag template '%s'", buildFlagTemplate)
} }

View File

@@ -104,19 +104,17 @@ func TestRunPipe(t *testing.T) {
registry + "goreleaser/test_run_pipe:v{{.Major}}", registry + "goreleaser/test_run_pipe:v{{.Major}}",
registry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}", registry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}",
registry + "goreleaser/test_run_pipe:commit-{{.Commit}}", registry + "goreleaser/test_run_pipe:commit-{{.Commit}}",
registry + "goreleaser/test_run_pipe:le-{{.Os}}",
registry + "goreleaser/test_run_pipe:latest", registry + "goreleaser/test_run_pipe:latest",
altRegistry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}", altRegistry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}",
altRegistry + "goreleaser/test_run_pipe:v{{.Major}}", altRegistry + "goreleaser/test_run_pipe:v{{.Major}}",
altRegistry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}", altRegistry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}",
altRegistry + "goreleaser/test_run_pipe:commit-{{.Commit}}", altRegistry + "goreleaser/test_run_pipe:commit-{{.Commit}}",
altRegistry + "goreleaser/test_run_pipe:le-{{.Os}}",
altRegistry + "goreleaser/test_run_pipe:latest", altRegistry + "goreleaser/test_run_pipe:latest",
}, },
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
Binary: "mybin", Binaries: []string{"mybin"},
BuildFlagTemplates: []string{ BuildFlagTemplates: []string{
"--label=org.label-schema.schema-version=1.0", "--label=org.label-schema.schema-version=1.0",
"--label=org.label-schema.version={{.Version}}", "--label=org.label-schema.version={{.Version}}",
@@ -134,13 +132,11 @@ func TestRunPipe(t *testing.T) {
registry + "goreleaser/test_run_pipe:v1", registry + "goreleaser/test_run_pipe:v1",
registry + "goreleaser/test_run_pipe:v1.0", registry + "goreleaser/test_run_pipe:v1.0",
registry + "goreleaser/test_run_pipe:commit-a1b2c3d4", registry + "goreleaser/test_run_pipe:commit-a1b2c3d4",
registry + "goreleaser/test_run_pipe:le-linux",
registry + "goreleaser/test_run_pipe:latest", registry + "goreleaser/test_run_pipe:latest",
altRegistry + "goreleaser/test_run_pipe:v1.0.0-123", altRegistry + "goreleaser/test_run_pipe:v1.0.0-123",
altRegistry + "goreleaser/test_run_pipe:v1", altRegistry + "goreleaser/test_run_pipe:v1",
altRegistry + "goreleaser/test_run_pipe:v1.0", altRegistry + "goreleaser/test_run_pipe:v1.0",
altRegistry + "goreleaser/test_run_pipe:commit-a1b2c3d4", altRegistry + "goreleaser/test_run_pipe:commit-a1b2c3d4",
altRegistry + "goreleaser/test_run_pipe:le-linux",
altRegistry + "goreleaser/test_run_pipe:latest", altRegistry + "goreleaser/test_run_pipe:latest",
}, },
assertImageLabels: shouldFindImagesWithLabels( assertImageLabels: shouldFindImagesWithLabels(
@@ -152,51 +148,27 @@ func TestRunPipe(t *testing.T) {
assertError: shouldNotErr, assertError: shouldNotErr,
pubAssertError: shouldNotErr, pubAssertError: shouldNotErr,
}, },
"with deprecated image name & tag templates": {
publish: true,
dockers: []config.Docker{
{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile",
Binary: "mybin",
TagTemplates: []string{
"{{.Tag}}-{{.Env.FOO}}",
},
BuildFlagTemplates: []string{
"--label=org.label-schema.version={{.Version}}",
},
},
},
expect: []string{
registry + "goreleaser/test_run_pipe:v1.0.0-123",
},
assertImageLabels: shouldFindImagesWithLabels(
"goreleaser/test_run_pipe",
"label=org.label-schema.version=1.0.0",
),
assertError: shouldNotErr,
pubAssertError: shouldNotErr,
},
"multiple images with same extra file": { "multiple images with same extra file": {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/multiplefiles1", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/multiplefiles1:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Files: []string{"testdata/extra_file.txt"}, Binaries: []string{"mybin"},
Files: []string{"testdata/extra_file.txt"},
}, },
{ {
Image: registry + "goreleaser/multiplefiles2", ImageTemplates: []string{
registry + "goreleaser/multiplefiles2:latest",
},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
Binary: "mybin", Binaries: []string{"mybin"},
TagTemplates: []string{"latest"}, TagTemplates: []string{"latest"},
Files: []string{"testdata/extra_file.txt"}, Files: []string{"testdata/extra_file.txt"},
}, },
@@ -213,20 +185,22 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
}, },
{ {
Image: registry + "goreleaser/test_run_pipe2", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe2:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
@@ -241,13 +215,14 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
SkipPush: true, Dockerfile: "testdata/Dockerfile",
TagTemplates: []string{"latest"}, Binaries: []string{"mybin"},
SkipPush: true,
}, },
}, },
expect: []string{ expect: []string{
@@ -261,12 +236,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:{{.Version}}",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"{{.Version}}"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
}, },
}, },
expect: []string{ expect: []string{
@@ -280,12 +256,13 @@ func TestRunPipe(t *testing.T) {
publish: false, publish: false,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
}, },
}, },
expect: []string{ expect: []string{
@@ -299,12 +276,13 @@ func TestRunPipe(t *testing.T) {
publish: false, publish: false,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_build_args", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_build_args:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
BuildFlagTemplates: []string{ BuildFlagTemplates: []string{
"--label=foo=bar", "--label=foo=bar",
}, },
@@ -321,12 +299,13 @@ func TestRunPipe(t *testing.T) {
publish: false, publish: false,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_build_args", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_build_args:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
BuildFlagTemplates: []string{ BuildFlagTemplates: []string{
"--bad-flag", "--bad-flag",
}, },
@@ -339,12 +318,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/bad_dockerfile", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/bad_dockerfile:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile.bad", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile.bad",
Binaries: []string{"mybin"},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
@@ -354,14 +334,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
registry + "goreleaser/test_run_pipe:{{.Tag}",
},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
Binary: "mybin", Binaries: []string{"mybin"},
TagTemplates: []string{
"{{.Tag}",
},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
@@ -371,12 +350,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
BuildFlagTemplates: []string{ BuildFlagTemplates: []string{
"--label=tag={{.Tag}", "--label=tag={{.Tag}",
}, },
@@ -389,14 +369,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
registry + "goreleaser/test_run_pipe:{{.Env.NOPE}}",
},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
Binary: "mybin", Binaries: []string{"mybin"},
TagTemplates: []string{
"{{.Env.NOPE}}",
},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
@@ -406,12 +385,13 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/test_run_pipe", ImageTemplates: []string{
Goos: "linux", registry + "goreleaser/test_run_pipe:latest",
Goarch: "amd64", },
Dockerfile: "testdata/Dockerfile", Goos: "linux",
Binary: "mybin", Goarch: "amd64",
TagTemplates: []string{"latest"}, Dockerfile: "testdata/Dockerfile",
Binaries: []string{"mybin"},
BuildFlagTemplates: []string{ BuildFlagTemplates: []string{
"--label=nope={{.Env.NOPE}}", "--label=nope={{.Env.NOPE}}",
}, },
@@ -424,16 +404,15 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: registry + "goreleaser/{{.ProjectName}}", ImageTemplates: []string{
registry + "goreleaser/{{.ProjectName}}:{{.Tag}}-{{.Env.FOO}}",
registry + "goreleaser/{{.ProjectName}}:latest",
},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
Binary: "mybin", Binaries: []string{"mybin"},
SkipPush: true, SkipPush: true,
TagTemplates: []string{
"{{.Tag}}-{{.Env.FOO}}",
"latest",
},
}, },
}, },
expect: []string{ expect: []string{
@@ -448,12 +427,11 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: "docker.io/nope", ImageTemplates: []string{"docker.io/nope:latest"},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Binary: "mybin", Binaries: []string{"mybin"},
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
TagTemplates: []string{"latest"},
}, },
}, },
expect: []string{ expect: []string{
@@ -467,12 +445,11 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: "whatever", ImageTemplates: []string{"whatever:latest"},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Binary: "mybin", Binaries: []string{"mybin"},
Dockerfile: "testdata/Dockerfilezzz", Dockerfile: "testdata/Dockerfilezzz",
TagTemplates: []string{"latest"},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
@@ -482,12 +459,11 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: "whatever", ImageTemplates: []string{"whatever:latest"},
Goos: "linux", Goos: "linux",
Goarch: "amd64", Goarch: "amd64",
Binary: "mybin", Binaries: []string{"mybin"},
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
TagTemplates: []string{"latest"},
Files: []string{ Files: []string{
"testdata/nope.txt", "testdata/nope.txt",
}, },
@@ -500,34 +476,35 @@ func TestRunPipe(t *testing.T) {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
Image: "whatever", ImageTemplates: []string{"whatever:latest"},
Goos: "darwin", Goos: "darwin",
Goarch: "amd64", Goarch: "amd64",
Binary: "mybinnnn", Binaries: []string{"mybinnnn"},
Dockerfile: "testdata/Dockerfile", Dockerfile: "testdata/Dockerfile",
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
assertError: shouldErr(`0 binaries match docker definition: mybinnnn: darwin_amd64_`), assertError: shouldErr(`0 binaries match docker definition: [mybinnnn]: darwin_amd64_, should be 1`),
}, },
"mixed image and image template": { "multiple_binaries": {
publish: true, publish: true,
dockers: []config.Docker{ dockers: []config.Docker{
{ {
ImageTemplates: []string{ ImageTemplates: []string{registry + "goreleaser/multiple:latest"},
registry + "goreleaser/test_run_pipe:latest", Goos: "darwin",
}, Goarch: "amd64",
Image: registry + "goreleaser/test_run_pipe", Binaries: []string{"mybin", "anotherbin"},
Goos: "darwin", Dockerfile: "testdata/Dockerfile.multiple",
Goarch: "amd64",
Binary: "mybin",
Dockerfile: "testdata/Dockerfile",
TagTemplates: []string{"latest"},
}, },
}, },
assertImageLabels: noLabels, assertImageLabels: noLabels,
assertError: shouldErr("failed to process image, use either image_templates (preferred) or image, not both"), assertError: shouldNotErr,
pubAssertError: shouldNotErr,
expect: []string{
registry + "goreleaser/multiple:latest",
},
}, },
// TODO: add a test case for multiple matching binaries for the same name
} }
killAndRm(t) killAndRm(t)
@@ -541,8 +518,9 @@ func TestRunPipe(t *testing.T) {
var dist = filepath.Join(folder, "dist") var dist = filepath.Join(folder, "dist")
require.NoError(tt, os.Mkdir(dist, 0755)) require.NoError(tt, os.Mkdir(dist, 0755))
require.NoError(tt, os.Mkdir(filepath.Join(dist, "mybin"), 0755)) require.NoError(tt, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
var binPath = filepath.Join(dist, "mybin", "mybin") _, err = os.Create(filepath.Join(dist, "mybin", "mybin"))
_, err = os.Create(binPath) require.NoError(tt, err)
_, err = os.Create(filepath.Join(dist, "mybin", "anotherbin"))
require.NoError(tt, err) require.NoError(tt, err)
var ctx = context.New(config.Project{ var ctx = context.New(config.Project{
@@ -561,16 +539,18 @@ func TestRunPipe(t *testing.T) {
} }
for _, os := range []string{"linux", "darwin"} { for _, os := range []string{"linux", "darwin"} {
for _, arch := range []string{"amd64", "386"} { for _, arch := range []string{"amd64", "386"} {
ctx.Artifacts.Add(artifact.Artifact{ for _, bin := range []string{"mybin", "anotherbin"} {
Name: "mybin", ctx.Artifacts.Add(artifact.Artifact{
Path: binPath, Name: bin,
Goarch: arch, Path: filepath.Join(dist, "mybin", bin),
Goos: os, Goarch: arch,
Type: artifact.Binary, Goos: os,
Extra: map[string]interface{}{ Type: artifact.Binary,
"Binary": "mybin", Extra: map[string]interface{}{
}, "Binary": bin,
}) },
})
}
} }
} }
@@ -665,7 +645,7 @@ func TestDockerNotInPath(t *testing.T) {
Config: config.Project{ Config: config.Project{
Dockers: []config.Docker{ Dockers: []config.Docker{
{ {
Image: "a/b", ImageTemplates: []string{"a/b"},
}, },
}, },
}, },
@@ -691,8 +671,25 @@ func TestDefault(t *testing.T) {
var docker = ctx.Config.Dockers[0] var docker = ctx.Config.Dockers[0]
assert.Equal(t, "linux", docker.Goos) assert.Equal(t, "linux", docker.Goos)
assert.Equal(t, "amd64", docker.Goarch) assert.Equal(t, "amd64", docker.Goarch)
assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary) assert.Equal(t, []string{ctx.Config.Builds[0].Binary}, docker.Binaries)
assert.Equal(t, "Dockerfile", docker.Dockerfile) }
func TestDefaultBinaries(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Dockers: []config.Docker{
{
Binary: "foo",
},
},
},
}
assert.NoError(t, Pipe{}.Default(ctx))
assert.Len(t, ctx.Config.Dockers, 1)
var docker = ctx.Config.Dockers[0]
assert.Equal(t, "linux", docker.Goos)
assert.Equal(t, "amd64", docker.Goarch)
assert.Equal(t, []string{"foo"}, docker.Binaries)
} }
func TestDefaultNoDockers(t *testing.T) { func TestDefaultNoDockers(t *testing.T) {
@@ -712,7 +709,7 @@ func TestDefaultSet(t *testing.T) {
{ {
Goos: "windows", Goos: "windows",
Goarch: "i386", Goarch: "i386",
Binary: "bar", Binaries: []string{"bar"},
Dockerfile: "Dockerfile.foo", Dockerfile: "Dockerfile.foo",
}, },
}, },
@@ -723,7 +720,7 @@ func TestDefaultSet(t *testing.T) {
var docker = ctx.Config.Dockers[0] var docker = ctx.Config.Dockers[0]
assert.Equal(t, "windows", docker.Goos) assert.Equal(t, "windows", docker.Goos)
assert.Equal(t, "i386", docker.Goarch) assert.Equal(t, "i386", docker.Goarch)
assert.Equal(t, "bar", docker.Binary) assert.Equal(t, "bar", docker.Binaries[0])
assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
} }
@@ -734,7 +731,7 @@ func TestDefaultWithImage(t *testing.T) {
{ {
Goos: "windows", Goos: "windows",
Goarch: "i386", Goarch: "i386",
Binary: "bar", Binaries: []string{"bar"},
Dockerfile: "Dockerfile.foo", Dockerfile: "Dockerfile.foo",
Image: "my/image", Image: "my/image",
}, },
@@ -746,69 +743,52 @@ func TestDefaultWithImage(t *testing.T) {
var docker = ctx.Config.Dockers[0] var docker = ctx.Config.Dockers[0]
assert.Equal(t, "windows", docker.Goos) assert.Equal(t, "windows", docker.Goos)
assert.Equal(t, "i386", docker.Goarch) assert.Equal(t, "i386", docker.Goarch)
assert.Equal(t, "bar", docker.Binary) assert.Equal(t, "bar", docker.Binaries[0])
assert.Equal(t, []string{"{{ .Version }}"}, docker.TagTemplates) assert.Equal(t, []string{"{{ .Version }}"}, docker.TagTemplates)
assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
assert.Equal(t, []string{"my/image:{{ .Version }}"}, docker.ImageTemplates)
} }
func Test_processImageTemplates(t *testing.T) { func Test_processImageTemplates(t *testing.T) {
var ctx = &context.Context{
var table = map[string]struct { Config: config.Project{
image string Dockers: []config.Docker{
tagTemplates []string {
imageTemplates []string Binaries: []string{"foo"},
expectImages []string Dockerfile: "Dockerfile.foo",
}{ ImageTemplates: []string{
"with image templates": { "user/image:{{.Tag}}",
imageTemplates: []string{"user/image:{{.Tag}}", "gcr.io/image:{{.Tag}}-{{.Env.FOO}}", "gcr.io/image:v{{.Major}}.{{.Minor}}"}, "gcr.io/image:{{.Tag}}-{{.Env.FOO}}",
expectImages: []string{"user/image:v1.0.0", "gcr.io/image:v1.0.0-123", "gcr.io/image:v1.0"}, "gcr.io/image:v{{.Major}}.{{.Minor}}",
},
"with image name and tag template": {
image: "my/image",
tagTemplates: []string{"{{.Tag}}-{{.Env.FOO}}", "v{{.Major}}.{{.Minor}}"},
expectImages: []string{"my/image:v1.0.0-123", "my/image:v1.0"},
},
}
for name, tt := range table {
t.Run(name, func(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Dockers: []config.Docker{
{
Binary: "foo",
Image: tt.image,
Dockerfile: "Dockerfile.foo",
ImageTemplates: tt.imageTemplates,
SkipPush: true,
TagTemplates: tt.tagTemplates,
},
}, },
SkipPush: true,
}, },
} },
ctx.SkipPublish = true },
ctx.Env = map[string]string{ }
"FOO": "123", ctx.SkipPublish = true
} ctx.Env = map[string]string{
ctx.Version = "1.0.0" "FOO": "123",
ctx.Git = context.GitInfo{ }
CurrentTag: "v1.0.0", ctx.Version = "1.0.0"
Commit: "a1b2c3d4", ctx.Git = context.GitInfo{
} CurrentTag: "v1.0.0",
Commit: "a1b2c3d4",
assert.NoError(t, Pipe{}.Default(ctx))
assert.Len(t, ctx.Config.Dockers, 1)
docker := ctx.Config.Dockers[0]
assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
images, err := processImageTemplates(ctx, docker, artifact.Artifact{})
assert.NoError(t, err)
assert.Equal(t, tt.expectImages, images)
})
} }
assert.NoError(t, Pipe{}.Default(ctx))
assert.Len(t, ctx.Config.Dockers, 1)
docker := ctx.Config.Dockers[0]
assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
images, err := processImageTemplates(ctx, docker)
assert.NoError(t, err)
assert.Equal(t, []string{
"user/image:v1.0.0",
"gcr.io/image:v1.0.0-123",
"gcr.io/image:v1.0",
}, images)
} }
func TestLinkFile(t *testing.T) { func TestLinkFile(t *testing.T) {

View File

@@ -1,3 +1,2 @@
FROM nope FROM nope
ADD mybin / ADD mybin /

View File

@@ -0,0 +1,3 @@
FROM scratch
ADD mybin /
ADD anotherbin /

View File

@@ -242,6 +242,7 @@ type Checksum struct {
// Docker image config // Docker image config
type Docker struct { type Docker struct {
Binary string `yaml:",omitempty"` Binary string `yaml:",omitempty"`
Binaries []string `yaml:",omitempty"`
Goos string `yaml:",omitempty"` Goos string `yaml:",omitempty"`
Goarch string `yaml:",omitempty"` Goarch string `yaml:",omitempty"`
Goarm string `yaml:",omitempty"` Goarm string `yaml:",omitempty"`

View File

@@ -11,6 +11,51 @@ Deprecate code will be removed after ~6 months from the time it was deprecated.
# Active deprecation notices # Active deprecation notices
<!--
Template for new deprecations:
## property
> since yyyy-mm-dd
Description.
Change this:
```yaml
```
to this:
```yaml
```
-->
## docker.binary
> since 2018-10-01
You can now create a Docker image with multiple binaries.
Change this:
```yaml
dockers:
- image: foo/bar
binary: foo
```
to this:
```yaml
dockers:
- image: foo/bar
binaries:
- foo
```
## docker.image ## docker.image
> since 2018-10-20 > since 2018-10-20
@@ -60,29 +105,6 @@ dockers:
- 'foo/bar:{{ .Tag }}' - 'foo/bar:{{ .Tag }}'
``` ```
<!--
Template for new deprecations:
## property
> since yyyy-mm-dd
Description.
Change this:
```yaml
```
to this:
```yaml
```
-->
## git.short_hash ## git.short_hash
> since 2018-10-03 > since 2018-10-03

View File

@@ -54,8 +54,9 @@ dockers:
goarch: amd64 goarch: amd64
# GOARM of the built binary that should be used. # GOARM of the built binary that should be used.
goarm: '' goarm: ''
# Name of the built binary that should be used. # Name of the built binaries that should be used.
binary: mybinary binaries:
- mybinary
# Templates of the Docker image names. # Templates of the Docker image names.
image_templates: image_templates:
- "myuser/myimage:latest" - "myuser/myimage:latest"
@@ -103,7 +104,8 @@ That can be accomplished simply by adding template language in the definition:
project: foo project: foo
dockers: dockers:
- -
binary: mybinary binaries:
- mybinary
image_templates: image_templates:
- "myuser/{{.ProjectName}}" - "myuser/{{.ProjectName}}"
``` ```
@@ -124,7 +126,8 @@ accomplished by using multiple `image_templates`:
# .goreleaser.yml # .goreleaser.yml
dockers: dockers:
- -
binary: mybinary binaries:
- mybinary
image_templates: image_templates:
- "myuser/myimage:{{ .Tag }}" - "myuser/myimage:{{ .Tag }}"
- "myuser/myimage:v{{ .Major }}" - "myuser/myimage:v{{ .Major }}"
@@ -153,7 +156,8 @@ accomplished by using multiple `image_templates`:
# .goreleaser.yml # .goreleaser.yml
dockers: dockers:
- -
binary: mybinary binaries:
- mybinary
image_templates: image_templates:
- "docker.io/myuser/myimage:{{ .Tag }}" - "docker.io/myuser/myimage:{{ .Tag }}"
- "docker.io/myuser/myimage:latest" - "docker.io/myuser/myimage:latest"
@@ -175,9 +179,10 @@ valid docker build flags.
# .goreleaser.yml # .goreleaser.yml
dockers: dockers:
- -
binary: mybinary binaries:
- mybinary
image_templates: image_templates:
- "myuser/myimage" - "myuser/myimage"
build_flag_templates: build_flag_templates:
- "--label=org.label-schema.schema-version=1.0" - "--label=org.label-schema.schema-version=1.0"
- "--label=org.label-schema.version={{.Version}}" - "--label=org.label-schema.version={{.Version}}"