From 87d59d6a0faec37a30b0f9eeaf0bb465d2de3d20 Mon Sep 17 00:00:00 2001 From: the-braveknight Date: Fri, 5 Dec 2025 17:17:33 +0300 Subject: [PATCH] Fix --tag parameter to properly push tags and update latest The --tag parameter was accepted but not used when pushing the manifest and index to the registry. The code was always using destinationImage.reference (which defaults to 'latest') instead of the user-provided tag. This fix: - Pushes to both the specified --tag and the default reference (latest) - Avoids duplicate pushes if --tag matches the repository reference - Returns the correct reference in the result --- .../Extensions/RegistryClient+publish.swift | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/Sources/containertool/Extensions/RegistryClient+publish.swift b/Sources/containertool/Extensions/RegistryClient+publish.swift index 8a6864c..0aed247 100644 --- a/Sources/containertool/Extensions/RegistryClient+publish.swift +++ b/Sources/containertool/Extensions/RegistryClient+publish.swift @@ -135,56 +135,58 @@ func publishContainerImage( ) } - // MARK: Upload application manifest - - let manifestDescriptor = try await destination.putManifest( - repository: destinationImage.repository, - reference: destinationImage.reference, - manifest: manifest - ) - - if verbose { - log("manifest: \(manifestDescriptor.digest) (\(manifestDescriptor.size) bytes)") + // Determine the tags to push. Always include the reference from --repository (defaults to 'latest'). + // If --tag is provided and differs from the repository reference, push to both. + var tagsToPublish: [any ImageReference.Reference] = [destinationImage.reference] + if let tag { + let tagReference = try ImageReference.Tag(tag) + // Avoid duplicates if --tag matches the reference already in --repository + if "\(tagReference)" != "\(destinationImage.reference)" { + tagsToPublish.insert(tagReference, at: 0) + } } - // MARK: Create application index + // MARK: Upload application manifest and index for each tag - let index = ImageIndex( - schemaVersion: 2, - mediaType: "application/vnd.oci.image.index.v1+json", - manifests: [ - ContentDescriptor( - mediaType: manifestDescriptor.mediaType, - digest: manifestDescriptor.digest, - size: Int64(manifestDescriptor.size), - platform: .init(architecture: architecture, os: os) - ) - ] - ) + for tagReference in tagsToPublish { + let manifestDescriptor = try await destination.putManifest( + repository: destinationImage.repository, + reference: tagReference, + manifest: manifest + ) - // MARK: Upload application manifest + if verbose { + log("manifest (\(tagReference)): \(manifestDescriptor.digest) (\(manifestDescriptor.size) bytes)") + } - let indexDescriptor = try await destination.putIndex( - repository: destinationImage.repository, - reference: destinationImage.reference, - index: index - ) + let index = ImageIndex( + schemaVersion: 2, + mediaType: "application/vnd.oci.image.index.v1+json", + manifests: [ + ContentDescriptor( + mediaType: manifestDescriptor.mediaType, + digest: manifestDescriptor.digest, + size: Int64(manifestDescriptor.size), + platform: .init(architecture: architecture, os: os) + ) + ] + ) - if verbose { - log("index: \(indexDescriptor.digest) (\(indexDescriptor.size) bytes)") - } + let indexDescriptor = try await destination.putIndex( + repository: destinationImage.repository, + reference: tagReference, + index: index + ) - // Use the index digest if the user did not provide a human-readable tag - // To support multiarch images, we should also create an an index pointing to - // this manifest. - let reference: ImageReference.Reference - if let tag { - reference = try ImageReference.Tag(tag) - } else { - reference = try ImageReference.Digest(indexDescriptor.digest) + if verbose { + log("index (\(tagReference)): \(indexDescriptor.digest) (\(indexDescriptor.size) bytes)") + } } + // Return the primary tag (--tag if provided, otherwise the repository reference) var result = destinationImage - result.reference = reference + if let tag { + result.reference = try ImageReference.Tag(tag) + } return result }