Skip to content

Commit eca7fa1

Browse files
committed
Simplify multi-arch publish and verify both index and manifest cases
--all on the existing oci-archive: transport is sufficient to publish the full multi-arch index; the tar/oci: directory extraction isn't needed. Also fix the verification so it doesn't silently pass for the single-arch precompiled builds (ubuntu22.04, ubuntu26.04, and ubuntu24.04 azure-fde all build amd64-only per multi-arch.mk) by comparing manifest digests structurally instead of an empty manifests[] list against another empty list. Signed-off-by: Abrar Shivani <ashivani@nvidia.com>
1 parent df08d06 commit eca7fa1

1 file changed

Lines changed: 29 additions & 12 deletions

File tree

.github/workflows/precompiled.yaml

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -495,16 +495,35 @@ jobs:
495495
IMAGE="${PRIVATE_REGISTRY}/nvidia/driver:${{ matrix.driver_branch }}-${{ env.KERNEL_VERSION }}"
496496
echo "uploading $image_path"
497497
if [[ "${{ github.ref == 'refs/heads/main' }}" == "true" ]]; then
498-
mkdir -p /tmp/oci-image
499-
tar -xf "${image_path}" -C /tmp/oci-image
500-
skopeo copy --all --authfile "${REGISTRY_AUTH_FILE}" "oci:/tmp/oci-image" docker://${IMAGE}
501-
502-
# Verify published manifest matches the built OCI artifact by comparing
503-
# platform digests — ensures skopeo copy pushed all manifests correctly
504-
LOCAL=$(skopeo inspect --raw "oci:/tmp/oci-image" | \
505-
jq -c '[.manifests[]? | {arch: .platform.architecture, digest: .digest}] | sort_by(.arch)')
506-
REMOTE=$(skopeo inspect --raw "docker://${IMAGE}" | \
507-
jq -c '[.manifests[]? | {arch: .platform.architecture, digest: .digest}] | sort_by(.arch)')
498+
skopeo copy --all --authfile "${REGISTRY_AUTH_FILE}" "oci-archive:${image_path}" "docker://${IMAGE}"
499+
500+
# Verify the registry actually holds what we built — skopeo copy can
501+
# succeed while silently publishing an incomplete result (missing --all
502+
# drops non-native-arch manifests without erroring), so compare the
503+
# published manifest against the local artifact rather than trusting
504+
# the exit code alone. Index and single-arch images need different
505+
# comparisons: an index has no useful top-level digest of its own, so
506+
# we compare per-platform digests instead; a plain manifest has no
507+
# platform list, so we compare its config/layer digests directly.
508+
LOCAL_RAW=$(skopeo inspect --raw "oci-archive:${image_path}")
509+
REMOTE_RAW=$(skopeo inspect --raw --authfile "${REGISTRY_AUTH_FILE}" "docker://${IMAGE}")
510+
511+
if echo "$LOCAL_RAW" | jq -e '.manifests' >/dev/null 2>&1; then
512+
# Multi-arch index: compare platform+digest pairs. Attestation
513+
# manifests (no real platform, arch reported as "unknown") are
514+
# excluded so they don't pad out an otherwise-empty comparison.
515+
JQ_FILTER='[.manifests[] | select(.platform.architecture and .platform.architecture != "unknown") | {arch: .platform.architecture, digest: .digest}] | sort_by(.arch)'
516+
LOCAL=$(echo "$LOCAL_RAW" | jq -c "$JQ_FILTER")
517+
REMOTE=$(echo "$REMOTE_RAW" | jq -c "$JQ_FILTER")
518+
else
519+
# Single-arch manifest: compare config + layer digests structurally
520+
# rather than raw bytes, since the registry may re-serialize the
521+
# manifest on push without changing its actual content.
522+
JQ_FILTER='{config: .config.digest, layers: [.layers[].digest]}'
523+
LOCAL=$(echo "$LOCAL_RAW" | jq -c "$JQ_FILTER")
524+
REMOTE=$(echo "$REMOTE_RAW" | jq -c "$JQ_FILTER")
525+
fi
526+
508527
if [[ "$LOCAL" == "$REMOTE" ]]; then
509528
echo "OK: published manifest matches built artifact"
510529
else
@@ -513,8 +532,6 @@ jobs:
513532
echo "Remote: $REMOTE"
514533
exit 1
515534
fi
516-
517-
rm -rf /tmp/oci-image
518535
else
519536
echo "Skipping image push for non-main branch ${{ github.ref }}"
520537
fi

0 commit comments

Comments
 (0)