diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 1e8e0560e64..85e8c1c644d 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -105,6 +105,8 @@ func filterArtifacts(artifacts artifact.Artifacts, publisher config.Publisher) [ artifact.ByType(artifact.UploadableFile), artifact.ByType(artifact.LinuxPackage), artifact.ByType(artifact.UploadableBinary), + artifact.ByType(artifact.DockerImage), + artifact.ByType(artifact.DockerManifest), } if publisher.Checksum { diff --git a/internal/exec/exec_test.go b/internal/exec/exec_test.go index 9e0c4e733d0..7d094667556 100644 --- a/internal/exec/exec_test.go +++ b/internal/exec/exec_test.go @@ -35,7 +35,6 @@ func TestExecute(t *testing.T) { ext string typ artifact.Type }{ - {"docker", "---", artifact.DockerImage}, {"debpkg", "deb", artifact.LinuxPackage}, {"binary", "bin", artifact.Binary}, {"archive", "tar", artifact.UploadableArchive}, @@ -57,6 +56,25 @@ func TestExecute(t *testing.T) { }) } + ctx.Artifacts.Add(&artifact.Artifact{ + Name: "foo/bar:amd64", + Goos: "linux", + Goarch: "amd64", + Path: "foo/bar:amd64", + Type: artifact.DockerImage, + Extra: map[string]interface{}{ + "ID": "img", + }, + }) + ctx.Artifacts.Add(&artifact.Artifact{ + Name: "foo/bar", + Path: "foo/bar", + Type: artifact.DockerManifest, + Extra: map[string]interface{}{ + "ID": "mnf", + }, + }) + osEnv := func(ignores ...string) []string { var result []string outer: @@ -108,6 +126,8 @@ func TestExecute(t *testing.T) { {ExpectedArgs: []string{"a.deb"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()}, }, }), }, @@ -129,6 +149,8 @@ func TestExecute(t *testing.T) { {ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.sum"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()}, }, }), }, @@ -150,6 +172,27 @@ func TestExecute(t *testing.T) { {ExpectedArgs: []string{"a.ubi"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.tar"}, ExitCode: 0, ExpectedEnv: osEnv()}, {ExpectedArgs: []string{"a.sig"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()}, + }, + }), + }, + }, + }, + nil, + }, + { + "docker", + []config.Publisher{ + { + Name: "test", + IDs: []string{"img", "mnf"}, + Cmd: MockCmd + " {{ .ArtifactName }}", + Env: []string{ + MarshalMockEnv(&MockData{ + AnyOf: []MockCall{ + {ExpectedArgs: []string{"foo/bar"}, ExitCode: 0, ExpectedEnv: osEnv()}, + {ExpectedArgs: []string{"foo/bar:amd64"}, ExitCode: 0, ExpectedEnv: osEnv()}, }, }), }, diff --git a/internal/pipe/docker/docker.go b/internal/pipe/docker/docker.go index 25e97f108dc..e031ed37f52 100644 --- a/internal/pipe/docker/docker.go +++ b/internal/pipe/docker/docker.go @@ -13,6 +13,7 @@ import ( "github.com/goreleaser/goreleaser/internal/artifact" "github.com/goreleaser/goreleaser/internal/deprecate" "github.com/goreleaser/goreleaser/internal/gio" + "github.com/goreleaser/goreleaser/internal/ids" "github.com/goreleaser/goreleaser/internal/pipe" "github.com/goreleaser/goreleaser/internal/semerrgroup" "github.com/goreleaser/goreleaser/internal/tmpl" @@ -36,9 +37,13 @@ func (Pipe) String() string { // Default sets the pipe defaults. func (Pipe) Default(ctx *context.Context) error { + ids := ids.New("dockers") for i := range ctx.Config.Dockers { docker := &ctx.Config.Dockers[i] + if docker.ID != "" { + ids.Inc(docker.ID) + } if docker.Goos == "" { docker.Goos = "linux" } @@ -66,7 +71,7 @@ func (Pipe) Default(ctx *context.Context) error { } } } - return nil + return ids.Validate() } func validateImager(use string) error { @@ -238,13 +243,18 @@ func dockerPush(ctx *context.Context, image *artifact.Artifact) error { if err := imagers[docker.Use].Push(ctx, image.Name, docker.PushFlags); err != nil { return err } - ctx.Artifacts.Add(&artifact.Artifact{ + art := &artifact.Artifact{ Type: artifact.DockerImage, Name: image.Name, Path: image.Path, Goarch: image.Goarch, Goos: image.Goos, Goarm: image.Goarm, - }) + Extra: map[string]interface{}{}, + } + if docker.ID != "" { + art.Extra["ID"] = docker.ID + } + ctx.Artifacts.Add(art) return nil } diff --git a/internal/pipe/docker/docker_test.go b/internal/pipe/docker/docker_test.go index 57cb258829f..148454fdfb6 100644 --- a/internal/pipe/docker/docker_test.go +++ b/internal/pipe/docker/docker_test.go @@ -1136,6 +1136,27 @@ func TestDefault(t *testing.T) { require.Equal(t, useDocker, ctx.Config.DockerManifests[1].Use) } +func TestDefaultDuplicateID(t *testing.T) { + ctx := &context.Context{ + Config: config.Project{ + Dockers: []config.Docker{ + {ID: "foo"}, + { /* empty */ }, + {ID: "bar"}, + {ID: "foo"}, + }, + DockerManifests: []config.DockerManifest{ + {ID: "bar"}, + { /* empty */ }, + {ID: "bar"}, + {ID: "foo"}, + }, + }, + } + require.EqualError(t, Pipe{}.Default(ctx), "found 2 dockers with the ID 'foo', please fix your config") + require.EqualError(t, ManifestPipe{}.Default(ctx), "found 2 docker_manifests with the ID 'bar', please fix your config") +} + func TestDefaultInvalidUse(t *testing.T) { ctx := &context.Context{ Config: config.Project{ diff --git a/internal/pipe/docker/manifest.go b/internal/pipe/docker/manifest.go index 02b246135a1..40af5697ad9 100644 --- a/internal/pipe/docker/manifest.go +++ b/internal/pipe/docker/manifest.go @@ -7,6 +7,7 @@ import ( "github.com/apex/log" "github.com/goreleaser/goreleaser/internal/artifact" + "github.com/goreleaser/goreleaser/internal/ids" "github.com/goreleaser/goreleaser/internal/pipe" "github.com/goreleaser/goreleaser/internal/semerrgroup" "github.com/goreleaser/goreleaser/internal/tmpl" @@ -24,8 +25,12 @@ func (ManifestPipe) String() string { // Default sets the pipe defaults. func (ManifestPipe) Default(ctx *context.Context) error { + ids := ids.New("docker_manifests") for i := range ctx.Config.DockerManifests { manifest := &ctx.Config.DockerManifests[i] + if manifest.ID != "" { + ids.Inc(manifest.ID) + } if manifest.Use == "" { manifest.Use = useDocker } @@ -33,7 +38,7 @@ func (ManifestPipe) Default(ctx *context.Context) error { return err } } - return nil + return ids.Validate() } // Publish the docker manifests. @@ -69,11 +74,16 @@ func (ManifestPipe) Publish(ctx *context.Context) error { if err := manifester.Create(ctx, name, images, manifest.CreateFlags); err != nil { return err } - ctx.Artifacts.Add(&artifact.Artifact{ - Type: artifact.DockerManifest, - Name: name, - Path: name, - }) + art := &artifact.Artifact{ + Type: artifact.DockerManifest, + Name: name, + Path: name, + Extra: map[string]interface{}{}, + } + if manifest.ID != "" { + art.Extra["ID"] = manifest.ID + } + ctx.Artifacts.Add(art) log.WithField("manifest", name).Info("pushing docker manifest") return manifester.Push(ctx, name, manifest.PushFlags) diff --git a/pkg/config/config.go b/pkg/config/config.go index a0f85a50ffb..49afa62c9e5 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -541,6 +541,7 @@ type Checksum struct { // Docker image config. type Docker struct { + ID string `yaml:"id,omitempty"` IDs []string `yaml:"ids,omitempty"` Goos string `yaml:",omitempty"` Goarch string `yaml:",omitempty"` @@ -557,6 +558,7 @@ type Docker struct { // DockerManifest config. type DockerManifest struct { + ID string `yaml:"id,omitempty"` NameTemplate string `yaml:"name_template,omitempty"` SkipPush string `yaml:"skip_push,omitempty"` ImageTemplates []string `yaml:"image_templates,omitempty"` diff --git a/www/docs/customization/docker.md b/www/docs/customization/docker.md index f0ddd26c2a5..6ac14c084a4 100644 --- a/www/docs/customization/docker.md +++ b/www/docs/customization/docker.md @@ -48,6 +48,9 @@ Of course, you can customize a lot of things: dockers: # You can have multiple Docker images. - + # ID of the image, needed if you want to filter by it later on (e.g. on custom publishers). + id: myimg + # GOOS of the built binaries/packages that should be used. goos: linux diff --git a/www/docs/customization/docker_manifest.md b/www/docs/customization/docker_manifest.md index 2a0f7d88cb3..d25e18941c1 100644 --- a/www/docs/customization/docker_manifest.md +++ b/www/docs/customization/docker_manifest.md @@ -28,6 +28,9 @@ options available: docker_manifests: # You can have multiple Docker manifests. - + # ID of the manifest, needed if you want to filter by it later on (e.g. on custom publishers). + id: myimg + # Name template for the manifest. # Defaults to empty. name_template: foo/bar:{{ .Version }}