@@ -135,56 +135,58 @@ func publishContainerImage<Source: ImageSource, Destination: ImageDestination>(
135135 )
136136 }
137137
138- // MARK: Upload application manifest
139-
140- let manifestDescriptor = try await destination. putManifest (
141- repository: destinationImage. repository,
142- reference: destinationImage. reference,
143- manifest: manifest
144- )
145-
146- if verbose {
147- log ( " manifest: \( manifestDescriptor. digest) ( \( manifestDescriptor. size) bytes) " )
138+ // Determine the tags to push. Always include the reference from --repository (defaults to 'latest').
139+ // If --tag is provided and differs from the repository reference, push to both.
140+ var tagsToPublish : [ any ImageReference . Reference ] = [ destinationImage. reference]
141+ if let tag {
142+ let tagReference = try ImageReference . Tag ( tag)
143+ // Avoid duplicates if --tag matches the reference already in --repository
144+ if " \( tagReference) " != " \( destinationImage. reference) " {
145+ tagsToPublish. insert ( tagReference, at: 0 )
146+ }
148147 }
149148
150- // MARK: Create application index
149+ // MARK: Upload application manifest and index for each tag
151150
152- let index = ImageIndex (
153- schemaVersion: 2 ,
154- mediaType: " application/vnd.oci.image.index.v1+json " ,
155- manifests: [
156- ContentDescriptor (
157- mediaType: manifestDescriptor. mediaType,
158- digest: manifestDescriptor. digest,
159- size: Int64 ( manifestDescriptor. size) ,
160- platform: . init( architecture: architecture, os: os)
161- )
162- ]
163- )
151+ for tagReference in tagsToPublish {
152+ let manifestDescriptor = try await destination. putManifest (
153+ repository: destinationImage. repository,
154+ reference: tagReference,
155+ manifest: manifest
156+ )
164157
165- // MARK: Upload application manifest
158+ if verbose {
159+ log ( " manifest ( \( tagReference) ): \( manifestDescriptor. digest) ( \( manifestDescriptor. size) bytes) " )
160+ }
166161
167- let indexDescriptor = try await destination. putIndex (
168- repository: destinationImage. repository,
169- reference: destinationImage. reference,
170- index: index
171- )
162+ let index = ImageIndex (
163+ schemaVersion: 2 ,
164+ mediaType: " application/vnd.oci.image.index.v1+json " ,
165+ manifests: [
166+ ContentDescriptor (
167+ mediaType: manifestDescriptor. mediaType,
168+ digest: manifestDescriptor. digest,
169+ size: Int64 ( manifestDescriptor. size) ,
170+ platform: . init( architecture: architecture, os: os)
171+ )
172+ ]
173+ )
172174
173- if verbose {
174- log ( " index: \( indexDescriptor. digest) ( \( indexDescriptor. size) bytes) " )
175- }
175+ let indexDescriptor = try await destination. putIndex (
176+ repository: destinationImage. repository,
177+ reference: tagReference,
178+ index: index
179+ )
176180
177- // Use the index digest if the user did not provide a human-readable tag
178- // To support multiarch images, we should also create an an index pointing to
179- // this manifest.
180- let reference : ImageReference . Reference
181- if let tag {
182- reference = try ImageReference . Tag ( tag)
183- } else {
184- reference = try ImageReference . Digest ( indexDescriptor. digest)
181+ if verbose {
182+ log ( " index ( \( tagReference) ): \( indexDescriptor. digest) ( \( indexDescriptor. size) bytes) " )
183+ }
185184 }
186185
186+ // Return the primary tag (--tag if provided, otherwise the repository reference)
187187 var result = destinationImage
188- result. reference = reference
188+ if let tag {
189+ result. reference = try ImageReference . Tag ( tag)
190+ }
189191 return result
190192}
0 commit comments