diff --git a/internal/pipe/docker/api.go b/internal/pipe/docker/api.go index 4a210471f9b..63bb9399ce9 100644 --- a/internal/pipe/docker/api.go +++ b/internal/pipe/docker/api.go @@ -40,7 +40,7 @@ type imager interface { // manifester is something that can create and push docker manifests. type manifester interface { Create(ctx *context.Context, manifest string, images, flags []string) error - Push(ctx *context.Context, manifest string, flags []string) error + Push(ctx *context.Context, manifest string, flags []string) (digest string, err error) } // nolint: unparam diff --git a/internal/pipe/docker/api_docker.go b/internal/pipe/docker/api_docker.go index 26e4f7a63c1..90e614e35cf 100644 --- a/internal/pipe/docker/api_docker.go +++ b/internal/pipe/docker/api_docker.go @@ -31,13 +31,18 @@ func (m dockerManifester) Create(ctx *context.Context, manifest string, images, return nil } -func (m dockerManifester) Push(ctx *context.Context, manifest string, flags []string) error { +func (m dockerManifester) Push(ctx *context.Context, manifest string, flags []string) (string, error) { args := []string{"manifest", "push", manifest} args = append(args, flags...) - if err := runCommand(ctx, ".", "docker", args...); err != nil { - return fmt.Errorf("failed to push %s: %w", manifest, err) + bts, err := runCommandWithOutput(ctx, ".", "docker", args...) + if err != nil { + return "", fmt.Errorf("failed to push %s: %w", manifest, err) } - return nil + digest := dockerDigestPattern.FindString(string(bts)) + if digest == "" { + return "", fmt.Errorf("failed to find docker digest in docker push output: %s", string(bts)) + } + return digest, nil } type dockerImager struct { @@ -46,18 +51,15 @@ type dockerImager struct { var dockerDigestPattern = regexp.MustCompile("sha256:[a-z0-9]{64}") -func (i dockerImager) Push(ctx *context.Context, image string, flags []string) (digest string, err error) { - outBytes, err := runCommandWithOutput(ctx, ".", "docker", "push", image) +func (i dockerImager) Push(ctx *context.Context, image string, flags []string) (string, error) { + bts, err := runCommandWithOutput(ctx, ".", "docker", "push", image) if err != nil { return "", fmt.Errorf("failed to push %s: %w", image, err) } - - out := string(outBytes) - digest = dockerDigestPattern.FindString(out) + digest := dockerDigestPattern.FindString(string(bts)) if digest == "" { - return "", fmt.Errorf("failed to find docker digest in docker push output: %v", out) + return "", fmt.Errorf("failed to find docker digest in docker push output: %s", string(bts)) } - return digest, nil } diff --git a/internal/pipe/docker/docker_test.go b/internal/pipe/docker/docker_test.go index a6d1d845c07..ad556097bb8 100644 --- a/internal/pipe/docker/docker_test.go +++ b/internal/pipe/docker/docker_test.go @@ -1093,10 +1093,15 @@ func TestRunPipe(t *testing.T) { require.NoError(t, rmi(img), "could not delete image %s", img) } - _ = ctx.Artifacts.Filter(artifact.ByType(artifact.DockerImage)).Visit(func(a *artifact.Artifact) error { + _ = ctx.Artifacts.Filter( + artifact.Or( + artifact.ByType(artifact.DockerImage), + artifact.ByType(artifact.DockerManifest), + ), + ).Visit(func(a *artifact.Artifact) error { digest, err := artifact.Extra[string](*a, artifact.ExtraDigest) require.NoError(t, err) - require.NotEmpty(t, digest) + require.NotEmpty(t, digest, "missing digest for "+a.Name) return nil }) }) diff --git a/internal/pipe/docker/manifest.go b/internal/pipe/docker/manifest.go index 5c99dcc7619..bb1caa97a0e 100644 --- a/internal/pipe/docker/manifest.go +++ b/internal/pipe/docker/manifest.go @@ -81,10 +81,15 @@ func (ManifestPipe) Publish(ctx *context.Context) error { if manifest.ID != "" { art.Extra[artifact.ExtraID] = manifest.ID } - ctx.Artifacts.Add(art) log.WithField("manifest", name).Info("pushing") - return manifester.Push(ctx, name, manifest.PushFlags) + digest, err := manifester.Push(ctx, name, manifest.PushFlags) + if err != nil { + return err + } + art.Extra[artifact.ExtraDigest] = digest + ctx.Artifacts.Add(art) + return nil }) } return g.Wait()