From 61869d4612600686fa7b0dbb82cf9ae417db6ef5 Mon Sep 17 00:00:00 2001 From: "hiroto.toyoda" Date: Fri, 28 Aug 2026 02:46:09 +0900 Subject: [PATCH] fix(publish): warn when push falls back from OCI 1.1 to OCI 1.0 Signed-off-by: hiroto.toyoda --- internal/oci/push.go | 17 ++++++++++------- pkg/compose/publish.go | 5 ++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/internal/oci/push.go b/internal/oci/push.go index 1e2d0f2e95b..883378f4408 100644 --- a/internal/oci/push.go +++ b/internal/oci/push.go @@ -94,12 +94,14 @@ func DescriptorForEnvFile(path string, content []byte) v1.Descriptor { } } -func PushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, error) { +// PushManifest pushes the manifest for a Compose OCI artifact and returns +// the OCI version actually used. +func PushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, api.OCIVersion, error) { // Check if we need an extra empty layer for the manifest config if ociVersion == api.OCIVersion1_1 || ociVersion == "" { err := push(ctx, resolver, named, v1.DescriptorEmptyJSON) if err != nil { - return v1.Descriptor{}, err + return v1.Descriptor{}, "", err } } // prepare to push the manifest by pushing the layers @@ -107,13 +109,14 @@ func PushManifest(ctx context.Context, resolver remotes.Resolver, named referenc for i := range layers { layerDescriptors[i] = layers[i] if err := push(ctx, resolver, named, layers[i]); err != nil { - return v1.Descriptor{}, err + return v1.Descriptor{}, "", err } } if ociVersion != "" { // if a version was explicitly specified, use it - return createAndPushManifest(ctx, resolver, named, layerDescriptors, ociVersion) + descriptor, err := createAndPushManifest(ctx, resolver, named, layerDescriptors, ociVersion) + return descriptor, ociVersion, err } // try to push in the OCI 1.1 format but fallback to OCI 1.0 on 4xx errors @@ -122,10 +125,10 @@ func PushManifest(ctx context.Context, resolver remotes.Resolver, named referenc descriptor, err := createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_1) var pushErr pusherrors.ErrUnexpectedStatus if errors.As(err, &pushErr) && isNonAuthClientError(pushErr.StatusCode) { - // TODO(milas): show a warning here (won't work with logrus) - return createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_0) + descriptor, err = createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_0) + return descriptor, api.OCIVersion1_0, err } - return descriptor, err + return descriptor, api.OCIVersion1_1, err } func push(ctx context.Context, resolver remotes.Resolver, ref reference.Named, descriptor v1.Descriptor) error { diff --git a/pkg/compose/publish.go b/pkg/compose/publish.go index f0fb5c2313b..8293f8f45ed 100644 --- a/pkg/compose/publish.go +++ b/pkg/compose/publish.go @@ -119,7 +119,7 @@ func (s *composeService) pushComposeArtifact(ctx context.Context, project *types resolver := oci.NewResolver(s.configFile(), desktop.ProxyTransportFor(ctx, s.apiClient()), insecureRegistries...) - descriptor, err := oci.PushManifest(ctx, resolver, named, layers, options.OCIVersion) + descriptor, usedOCIVersion, err := oci.PushManifest(ctx, resolver, named, layers, options.OCIVersion) if err != nil { s.events.On(api.Resource{ ID: repository, @@ -128,6 +128,9 @@ func (s *composeService) pushComposeArtifact(ctx context.Context, project *types }) return err } + if options.OCIVersion == "" && usedOCIVersion == api.OCIVersion1_0 { + logrus.Warn("registry does not support OCI 1.1 artifacts; falling back to OCI 1.0 format") + } if options.Application { return pushApplicationIndex(ctx, resolver, named, descriptor, project)