@@ -193,27 +193,38 @@ runs:
193193 shell : bash
194194 run : |
195195 CHECK_EXISTING_TAGS="master-${GITHUB_SHA::8} main-${GITHUB_SHA::8}"
196- CONTENT_TYPE="application/vnd.docker.distribution.manifest.v2+json"
196+ # Accept both single-arch manifests and multi-arch manifest lists/indexes
197+ ACCEPT_HEADER="application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json"
197198
198199 echo "CHECK_EXISTING_TAGS: ${CHECK_EXISTING_TAGS}"
199200 echo "RELEASE_TAG: ${RELEASE_TAG:1}"
200201 echo "Check if an image already exists for ${{ inputs.docker-image }}:main|master-${GITHUB_SHA::8} 🐋 ⬇"
201202
202203 foundImage=false
204+ DETECTED_CONTENT_TYPE=""
205+ DIGEST=""
203206
204207 end=$((SECONDS+300))
205208 while [ $SECONDS -lt $end ]; do
206209
207210 MANIFEST=""
208211 for tag in $CHECK_EXISTING_TAGS; do
209- MANIFEST=$(curl -H "Accept: ${CONTENT_TYPE}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${tag}")
212+ # Dump headers to file to extract Content-Type and Digest later
213+ MANIFEST=$(curl -s -D headers.txt -H "Accept: ${ACCEPT_HEADER}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${tag}")
210214
211215 if [[ $MANIFEST == *"errors"* ]]; then
212216 echo "No image found for ${{ inputs.docker-image }}:${tag} 🚫"
213217 continue
214218 else
215219 echo "Image found for ${{ inputs.docker-image }}:${tag} 🐋 ⬇"
216220 foundImage=true
221+
222+ # Extract the Content-Type returned by registry
223+ DETECTED_CONTENT_TYPE=$(grep -i "^Content-Type:" headers.txt | cut -d' ' -f2 | tr -d '\r')
224+
225+ # Extract the correct digest from headers (works for lists and single images)
226+ DIGEST=$(grep -i "^Docker-Content-Digest:" headers.txt | cut -d' ' -f2 | tr -d '\r')
227+
217228 break 2
218229 fi
219230 done
@@ -227,11 +238,12 @@ runs:
227238 fi
228239
229240 echo "Retagging image with release version and :latest tags for ${{ inputs.docker-image }} 🏷"
230- curl --fail-with-body -X PUT -H "Content-Type: ${CONTENT_TYPE}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' -d "${MANIFEST}" "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${{ steps.preparation.outputs.tag }}"
231- curl --fail-with-body -X PUT -H "Content-Type: ${CONTENT_TYPE}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' -d "${MANIFEST}" "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${{ steps.preparation.outputs.latest }}"
241+ echo "Using Content-Type: ${DETECTED_CONTENT_TYPE}"
242+
243+ # Use the detected Content-Type to PUT the manifest back
244+ curl --fail-with-body -X PUT -H "Content-Type: ${DETECTED_CONTENT_TYPE}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' -d "${MANIFEST}" "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${{ steps.preparation.outputs.tag }}"
245+ curl --fail-with-body -X PUT -H "Content-Type: ${DETECTED_CONTENT_TYPE}" -u '${{ inputs.docker-username }}:${{ inputs.docker-password }}' -d "${MANIFEST}" "${{ inputs.docker-registry-api }}${{ inputs.docker-image}}/manifests/${{ steps.preparation.outputs.latest }}"
232246
233- # Get the digest of the image
234- DIGEST=$(echo $MANIFEST | jq .config.digest | tr -d '"')
235247 echo "digest=$DIGEST" >> $GITHUB_OUTPUT
236248
237249 - name : Checkout GitOps Repository
0 commit comments