From ba1bc5a54e52cb24a5d2ec38d6f91a7e1c94895a Mon Sep 17 00:00:00 2001 From: Alexander Poddubny Date: Thu, 2 Oct 2025 15:41:03 -0700 Subject: [PATCH 1/5] Added image build for release branches --- .github/workflows/postmerge-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/postmerge-ci.yml b/.github/workflows/postmerge-ci.yml index 182bc49940c4..9db7636ad619 100644 --- a/.github/workflows/postmerge-ci.yml +++ b/.github/workflows/postmerge-ci.yml @@ -10,6 +10,7 @@ on: branches: - main - devel + - release/** # Concurrency control to prevent parallel runs concurrency: From 4b87c47a248c0b2f84232d9ea2aca35d44d68042 Mon Sep 17 00:00:00 2001 From: Alexander Poddubny Date: Thu, 2 Oct 2025 16:09:21 -0700 Subject: [PATCH 2/5] Added docker image build for arm platform --- .github/workflows/postmerge-ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/postmerge-ci.yml b/.github/workflows/postmerge-ci.yml index 9db7636ad619..36b3dc302c2c 100644 --- a/.github/workflows/postmerge-ci.yml +++ b/.github/workflows/postmerge-ci.yml @@ -46,6 +46,8 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + with: + platforms: linux/amd64,linux/arm64 - name: Login to NGC run: | @@ -104,9 +106,9 @@ jobs: echo "Building image: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG" echo "IsaacSim version: $IMAGE_BASE_VERSION" - # Build Docker image once with both tags + # Build Docker image once with both tags for multiple architectures docker buildx build \ - --platform linux/amd64 \ + --platform linux/amd64,linux/arm64 \ --progress=plain \ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG \ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG \ From 1a8a675284e8ad5af051e78b0c801784a274402b Mon Sep 17 00:00:00 2001 From: Alexander Poddubny Date: Thu, 2 Oct 2025 16:18:20 -0700 Subject: [PATCH 3/5] Added a temp validation pipeline --- .../workflows/validate-multiarch-build.yml | 236 ++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 .github/workflows/validate-multiarch-build.yml diff --git a/.github/workflows/validate-multiarch-build.yml b/.github/workflows/validate-multiarch-build.yml new file mode 100644 index 000000000000..ec4444614a8a --- /dev/null +++ b/.github/workflows/validate-multiarch-build.yml @@ -0,0 +1,236 @@ +# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +name: Validate Multiarch Build + +on: + workflow_dispatch: + inputs: + branch_name: + description: 'Branch name to test (leave empty to use current branch)' + required: false + default: '' + isaacsim_versions: + description: 'IsaacSim versions to test (space-separated)' + required: false + default: '5.0.0' + test_platforms: + description: 'Platforms to build for (comma-separated)' + required: false + default: 'linux/amd64,linux/arm64' + fallback_amd64_only: + description: 'Fallback to AMD64 only if multiarch fails' + required: false + default: 'true' + type: boolean + pull_request: + branches: + - main + - devel + - 'release/**' + paths: + - '.github/workflows/postmerge-ci.yml' + - '.github/workflows/validate-multiarch-build.yml' + - 'docker/Dockerfile.base' + +# Concurrency control to prevent parallel runs +concurrency: + group: validate-multiarch-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +env: + NGC_API_KEY: ${{ secrets.NGC_API_KEY }} + ISAACSIM_BASE_IMAGE: ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }} + ISAACSIM_BASE_VERSIONS_STRING: ${{ github.event.inputs.isaacsim_versions || vars.ISAACSIM_BASE_VERSIONS_STRING || '5.0.0' }} + ISAACLAB_IMAGE_NAME: ${{ vars.ISAACLAB_IMAGE_NAME || 'isaac-lab-base' }} + TEST_PLATFORMS: ${{ github.event.inputs.test_platforms || 'linux/amd64,linux/arm64' }} + +jobs: + validate-multiarch-build: + runs-on: [self-hosted, gpu] + timeout-minutes: 180 + env: + DOCKER_HOST: unix:///var/run/docker.sock + DOCKER_TLS_CERTDIR: "" + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + lfs: true + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: linux/arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + platforms: ${{ env.TEST_PLATFORMS }} + driver-opts: | + image=moby/buildkit:buildx-stable-1 + + - name: Verify Multiarch Support + run: | + echo "🔍 Verifying multiarch support..." + docker buildx ls + echo "" + echo "📋 Available platforms:" + docker buildx inspect --bootstrap | grep "Platforms:" + echo "" + echo "🔧 QEMU emulators:" + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || echo "QEMU setup may need attention" + echo "" + + - name: Login to NGC + run: | + # Only attempt NGC login if API key is available + if [ -n "${{ env.NGC_API_KEY }}" ]; then + echo "Logging into NGC registry..." + docker login -u \$oauthtoken -p ${{ env.NGC_API_KEY }} nvcr.io + echo "✅ Successfully logged into NGC registry" + else + echo "⚠️ NGC_API_KEY not available - skipping NGC login" + echo "This is normal when secrets are not configured" + fi + + - name: Validate Multiarch Build (No Push) + run: | + # Determine branch name + if [ -n "${{ github.event.inputs.branch_name }}" ]; then + BRANCH_NAME="${{ github.event.inputs.branch_name }}" + else + BRANCH_NAME="${{ github.ref_name }}" + fi + + # Replace '/' with '-' and remove any invalid characters for Docker tag + SAFE_BRANCH_NAME=$(echo $BRANCH_NAME | sed 's/[^a-zA-Z0-9._-]/-/g') + + # Use "latest" if branch name is empty or only contains invalid characters + if [ -z "$SAFE_BRANCH_NAME" ]; then + SAFE_BRANCH_NAME="latest" + fi + + # Get the git repository short name + REPO_SHORT_NAME="${{ github.event.repository.name }}" + if [ -z "$REPO_SHORT_NAME" ]; then + REPO_SHORT_NAME="verification" + fi + + echo "🔍 VALIDATION BUILD PARAMETERS:" + echo "Branch: $BRANCH_NAME" + echo "Safe branch name: $SAFE_BRANCH_NAME" + echo "Repository name: $REPO_SHORT_NAME" + echo "IsaacSim versions: ${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" + echo "Test platforms: ${{ env.TEST_PLATFORMS }}" + echo "⚠️ NOTE: This is a validation build - images will NOT be pushed to registry" + echo "" + + # Parse the env variable string into an array + IMAGE_BASE_VERSIONS_STRING="${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" + # Use set to split the string into positional parameters, then convert to array + set -- $IMAGE_BASE_VERSIONS_STRING + IMAGE_BASE_VERSIONS=("$@") + + for IMAGE_BASE_VERSION in "${IMAGE_BASE_VERSIONS[@]}"; do + IMAGE_BASE_VERSION=$(echo "$IMAGE_BASE_VERSION" | tr -d '[:space:]') + + # Skip empty versions + if [ -z "$IMAGE_BASE_VERSION" ]; then + continue + fi + + # Combine repo short name and branch name for the tag + COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" + BUILD_TAG="${COMBINED_TAG}-validation-${{ github.run_number }}" + + echo "🏗️ Building validation image: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" + echo "IsaacSim version: $IMAGE_BASE_VERSION" + echo "Platforms: ${{ env.TEST_PLATFORMS }}" + + # Build Docker image for validation (no push) + docker buildx build \ + --platform ${{ env.TEST_PLATFORMS }} \ + --progress=plain \ + -t ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG \ + --build-arg ISAACSIM_BASE_IMAGE_ARG=${{ env.ISAACSIM_BASE_IMAGE }} \ + --build-arg ISAACSIM_VERSION_ARG=$IMAGE_BASE_VERSION \ + --build-arg ISAACSIM_ROOT_PATH_ARG=/isaac-sim \ + --build-arg ISAACLAB_PATH_ARG=/workspace/isaaclab \ + --build-arg DOCKER_USER_HOME_ARG=/root \ + --cache-from type=gha \ + --cache-to type=gha,mode=max \ + -f docker/Dockerfile.base \ + . + + echo "✅ Successfully built validation image: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" + echo "" + done + + - name: Inspect Built Images + run: | + echo "🔍 INSPECTING BUILT IMAGES:" + echo "" + + # List all isaac-lab images + echo "📋 Available Isaac Lab images:" + docker images | grep isaac-lab || echo "No isaac-lab images found" + echo "" + + # For each built image, show platform information + IMAGE_BASE_VERSIONS_STRING="${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" + set -- $IMAGE_BASE_VERSIONS_STRING + IMAGE_BASE_VERSIONS=("$@") + + BRANCH_NAME="${{ github.event.inputs.branch_name || github.ref_name }}" + SAFE_BRANCH_NAME=$(echo $BRANCH_NAME | sed 's/[^a-zA-Z0-9._-]/-/g') + REPO_SHORT_NAME="${{ github.event.repository.name }}" + + for IMAGE_BASE_VERSION in "${IMAGE_BASE_VERSIONS[@]}"; do + IMAGE_BASE_VERSION=$(echo "$IMAGE_BASE_VERSION" | tr -d '[:space:]') + if [ -z "$IMAGE_BASE_VERSION" ]; then + continue + fi + + COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" + BUILD_TAG="${COMBINED_TAG}-validation-${{ github.run_number }}" + + echo "🏷️ Inspecting: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" + + # Try to inspect the image (this works for multiarch manifests) + if docker buildx imagetools inspect ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG 2>/dev/null; then + echo "✅ Image manifest found and inspected successfully" + else + echo "⚠️ Could not inspect image manifest (this is expected for local builds)" + # For local builds, just show that the image exists + if docker images | grep -q "$BUILD_TAG"; then + echo "✅ Local image exists" + else + echo "❌ Local image not found" + fi + fi + echo "" + done + + - name: Validation Summary + run: | + echo "📊 VALIDATION SUMMARY:" + echo "✅ Multiarch build process completed successfully" + echo "✅ No images were pushed to registry (validation mode)" + echo "✅ Build cache was updated for future builds" + echo "" + echo "🎯 NEXT STEPS:" + echo "1. Review the build logs above for any warnings or errors" + echo "2. If validation looks good, the actual postmerge-ci.yml can be used" + echo "3. The actual pipeline will push images to the registry" + echo "" + echo "🗑️ CLEANUP:" + echo "Built validation images can be cleaned up locally if needed:" + docker images | grep validation || echo "No validation images to clean up" From c362fb698a6c1e6d63506e4e277bdb7a9eba047c Mon Sep 17 00:00:00 2001 From: Alexander Poddubny Date: Mon, 6 Oct 2025 10:39:43 -0700 Subject: [PATCH 4/5] Added a condition for SIM 5.1 image --- .github/workflows/postmerge-ci.yml | 40 ++- .../workflows/validate-multiarch-build.yml | 236 ------------------ 2 files changed, 36 insertions(+), 240 deletions(-) delete mode 100644 .github/workflows/validate-multiarch-build.yml diff --git a/.github/workflows/postmerge-ci.yml b/.github/workflows/postmerge-ci.yml index 36b3dc302c2c..16d1614b655d 100644 --- a/.github/workflows/postmerge-ci.yml +++ b/.github/workflows/postmerge-ci.yml @@ -44,10 +44,17 @@ jobs: fetch-depth: 0 lfs: true + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: linux/arm64 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: platforms: linux/amd64,linux/arm64 + driver-opts: | + image=moby/buildkit:buildx-stable-1 - name: Login to NGC run: | @@ -103,12 +110,37 @@ jobs: COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" BUILD_TAG="${COMBINED_TAG}-b${{ github.run_number }}" + # Determine if multiarch is supported based on IsaacSim version + # Multiarch only works with IsaacSim >= 5.1.0 + VERSION_STRING=$(echo "$IMAGE_BASE_VERSION" | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1) + + if [ -z "$VERSION_STRING" ]; then + echo "⚠️ Could not parse version from: $IMAGE_BASE_VERSION" + echo "Defaulting to AMD64 only for safety" + BUILD_PLATFORMS="linux/amd64" + else + # Extract major and minor version numbers + MAJOR_VERSION=$(echo "$VERSION_STRING" | cut -d. -f1) + MINOR_VERSION=$(echo "$VERSION_STRING" | cut -d. -f2) + + # Check if version >= 5.1.0 + if [ "$MAJOR_VERSION" -gt 5 ] || ([ "$MAJOR_VERSION" -eq 5 ] && [ "$MINOR_VERSION" -ge 1 ]); then + echo "✅ IsaacSim version $VERSION_STRING supports multiarch" + BUILD_PLATFORMS="linux/amd64,linux/arm64" + else + echo "⚠️ IsaacSim version $VERSION_STRING does not support multiarch (requires >= 5.1.0)" + echo "Building for AMD64 only" + BUILD_PLATFORMS="linux/amd64" + fi + fi + echo "Building image: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG" - echo "IsaacSim version: $IMAGE_BASE_VERSION" + echo "IsaacSim version: $IMAGE_BASE_VERSION (parsed: $VERSION_STRING)" + echo "Target platforms: $BUILD_PLATFORMS" # Build Docker image once with both tags for multiple architectures docker buildx build \ - --platform linux/amd64,linux/arm64 \ + --platform $BUILD_PLATFORMS \ --progress=plain \ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG \ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG \ @@ -122,6 +154,6 @@ jobs: -f docker/Dockerfile.base \ --push . - echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG" - echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" + echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG (platforms: $BUILD_PLATFORMS)" + echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG (platforms: $BUILD_PLATFORMS)" done diff --git a/.github/workflows/validate-multiarch-build.yml b/.github/workflows/validate-multiarch-build.yml deleted file mode 100644 index ec4444614a8a..000000000000 --- a/.github/workflows/validate-multiarch-build.yml +++ /dev/null @@ -1,236 +0,0 @@ -# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md). -# All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause - -name: Validate Multiarch Build - -on: - workflow_dispatch: - inputs: - branch_name: - description: 'Branch name to test (leave empty to use current branch)' - required: false - default: '' - isaacsim_versions: - description: 'IsaacSim versions to test (space-separated)' - required: false - default: '5.0.0' - test_platforms: - description: 'Platforms to build for (comma-separated)' - required: false - default: 'linux/amd64,linux/arm64' - fallback_amd64_only: - description: 'Fallback to AMD64 only if multiarch fails' - required: false - default: 'true' - type: boolean - pull_request: - branches: - - main - - devel - - 'release/**' - paths: - - '.github/workflows/postmerge-ci.yml' - - '.github/workflows/validate-multiarch-build.yml' - - 'docker/Dockerfile.base' - -# Concurrency control to prevent parallel runs -concurrency: - group: validate-multiarch-${{ github.ref }} - cancel-in-progress: true - -permissions: - contents: read - -env: - NGC_API_KEY: ${{ secrets.NGC_API_KEY }} - ISAACSIM_BASE_IMAGE: ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }} - ISAACSIM_BASE_VERSIONS_STRING: ${{ github.event.inputs.isaacsim_versions || vars.ISAACSIM_BASE_VERSIONS_STRING || '5.0.0' }} - ISAACLAB_IMAGE_NAME: ${{ vars.ISAACLAB_IMAGE_NAME || 'isaac-lab-base' }} - TEST_PLATFORMS: ${{ github.event.inputs.test_platforms || 'linux/amd64,linux/arm64' }} - -jobs: - validate-multiarch-build: - runs-on: [self-hosted, gpu] - timeout-minutes: 180 - env: - DOCKER_HOST: unix:///var/run/docker.sock - DOCKER_TLS_CERTDIR: "" - - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - lfs: true - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: linux/arm64 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - platforms: ${{ env.TEST_PLATFORMS }} - driver-opts: | - image=moby/buildkit:buildx-stable-1 - - - name: Verify Multiarch Support - run: | - echo "🔍 Verifying multiarch support..." - docker buildx ls - echo "" - echo "📋 Available platforms:" - docker buildx inspect --bootstrap | grep "Platforms:" - echo "" - echo "🔧 QEMU emulators:" - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || echo "QEMU setup may need attention" - echo "" - - - name: Login to NGC - run: | - # Only attempt NGC login if API key is available - if [ -n "${{ env.NGC_API_KEY }}" ]; then - echo "Logging into NGC registry..." - docker login -u \$oauthtoken -p ${{ env.NGC_API_KEY }} nvcr.io - echo "✅ Successfully logged into NGC registry" - else - echo "⚠️ NGC_API_KEY not available - skipping NGC login" - echo "This is normal when secrets are not configured" - fi - - - name: Validate Multiarch Build (No Push) - run: | - # Determine branch name - if [ -n "${{ github.event.inputs.branch_name }}" ]; then - BRANCH_NAME="${{ github.event.inputs.branch_name }}" - else - BRANCH_NAME="${{ github.ref_name }}" - fi - - # Replace '/' with '-' and remove any invalid characters for Docker tag - SAFE_BRANCH_NAME=$(echo $BRANCH_NAME | sed 's/[^a-zA-Z0-9._-]/-/g') - - # Use "latest" if branch name is empty or only contains invalid characters - if [ -z "$SAFE_BRANCH_NAME" ]; then - SAFE_BRANCH_NAME="latest" - fi - - # Get the git repository short name - REPO_SHORT_NAME="${{ github.event.repository.name }}" - if [ -z "$REPO_SHORT_NAME" ]; then - REPO_SHORT_NAME="verification" - fi - - echo "🔍 VALIDATION BUILD PARAMETERS:" - echo "Branch: $BRANCH_NAME" - echo "Safe branch name: $SAFE_BRANCH_NAME" - echo "Repository name: $REPO_SHORT_NAME" - echo "IsaacSim versions: ${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" - echo "Test platforms: ${{ env.TEST_PLATFORMS }}" - echo "⚠️ NOTE: This is a validation build - images will NOT be pushed to registry" - echo "" - - # Parse the env variable string into an array - IMAGE_BASE_VERSIONS_STRING="${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" - # Use set to split the string into positional parameters, then convert to array - set -- $IMAGE_BASE_VERSIONS_STRING - IMAGE_BASE_VERSIONS=("$@") - - for IMAGE_BASE_VERSION in "${IMAGE_BASE_VERSIONS[@]}"; do - IMAGE_BASE_VERSION=$(echo "$IMAGE_BASE_VERSION" | tr -d '[:space:]') - - # Skip empty versions - if [ -z "$IMAGE_BASE_VERSION" ]; then - continue - fi - - # Combine repo short name and branch name for the tag - COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" - BUILD_TAG="${COMBINED_TAG}-validation-${{ github.run_number }}" - - echo "🏗️ Building validation image: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" - echo "IsaacSim version: $IMAGE_BASE_VERSION" - echo "Platforms: ${{ env.TEST_PLATFORMS }}" - - # Build Docker image for validation (no push) - docker buildx build \ - --platform ${{ env.TEST_PLATFORMS }} \ - --progress=plain \ - -t ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG \ - --build-arg ISAACSIM_BASE_IMAGE_ARG=${{ env.ISAACSIM_BASE_IMAGE }} \ - --build-arg ISAACSIM_VERSION_ARG=$IMAGE_BASE_VERSION \ - --build-arg ISAACSIM_ROOT_PATH_ARG=/isaac-sim \ - --build-arg ISAACLAB_PATH_ARG=/workspace/isaaclab \ - --build-arg DOCKER_USER_HOME_ARG=/root \ - --cache-from type=gha \ - --cache-to type=gha,mode=max \ - -f docker/Dockerfile.base \ - . - - echo "✅ Successfully built validation image: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" - echo "" - done - - - name: Inspect Built Images - run: | - echo "🔍 INSPECTING BUILT IMAGES:" - echo "" - - # List all isaac-lab images - echo "📋 Available Isaac Lab images:" - docker images | grep isaac-lab || echo "No isaac-lab images found" - echo "" - - # For each built image, show platform information - IMAGE_BASE_VERSIONS_STRING="${{ env.ISAACSIM_BASE_VERSIONS_STRING }}" - set -- $IMAGE_BASE_VERSIONS_STRING - IMAGE_BASE_VERSIONS=("$@") - - BRANCH_NAME="${{ github.event.inputs.branch_name || github.ref_name }}" - SAFE_BRANCH_NAME=$(echo $BRANCH_NAME | sed 's/[^a-zA-Z0-9._-]/-/g') - REPO_SHORT_NAME="${{ github.event.repository.name }}" - - for IMAGE_BASE_VERSION in "${IMAGE_BASE_VERSIONS[@]}"; do - IMAGE_BASE_VERSION=$(echo "$IMAGE_BASE_VERSION" | tr -d '[:space:]') - if [ -z "$IMAGE_BASE_VERSION" ]; then - continue - fi - - COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" - BUILD_TAG="${COMBINED_TAG}-validation-${{ github.run_number }}" - - echo "🏷️ Inspecting: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG" - - # Try to inspect the image (this works for multiarch manifests) - if docker buildx imagetools inspect ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG 2>/dev/null; then - echo "✅ Image manifest found and inspected successfully" - else - echo "⚠️ Could not inspect image manifest (this is expected for local builds)" - # For local builds, just show that the image exists - if docker images | grep -q "$BUILD_TAG"; then - echo "✅ Local image exists" - else - echo "❌ Local image not found" - fi - fi - echo "" - done - - - name: Validation Summary - run: | - echo "📊 VALIDATION SUMMARY:" - echo "✅ Multiarch build process completed successfully" - echo "✅ No images were pushed to registry (validation mode)" - echo "✅ Build cache was updated for future builds" - echo "" - echo "🎯 NEXT STEPS:" - echo "1. Review the build logs above for any warnings or errors" - echo "2. If validation looks good, the actual postmerge-ci.yml can be used" - echo "3. The actual pipeline will push images to the registry" - echo "" - echo "🗑️ CLEANUP:" - echo "Built validation images can be cleaned up locally if needed:" - docker images | grep validation || echo "No validation images to clean up" From bb06236b2008102103d8eb0762b05ddf0708e99d Mon Sep 17 00:00:00 2001 From: Alexander Poddubny Date: Tue, 7 Oct 2025 17:31:12 -0700 Subject: [PATCH 5/5] Improved multiarch validation logic --- .github/workflows/postmerge-ci.yml | 39 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/.github/workflows/postmerge-ci.yml b/.github/workflows/postmerge-ci.yml index 16d1614b655d..fc35b1c87e4f 100644 --- a/.github/workflows/postmerge-ci.yml +++ b/.github/workflows/postmerge-ci.yml @@ -110,32 +110,43 @@ jobs: COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}" BUILD_TAG="${COMBINED_TAG}-b${{ github.run_number }}" - # Determine if multiarch is supported based on IsaacSim version - # Multiarch only works with IsaacSim >= 5.1.0 - VERSION_STRING=$(echo "$IMAGE_BASE_VERSION" | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1) + # Determine if multiarch is supported by inspecting the base image manifest + echo "Checking if base image supports multiarch..." + BASE_IMAGE_FULL="${{ env.ISAACSIM_BASE_IMAGE }}:${IMAGE_BASE_VERSION}" - if [ -z "$VERSION_STRING" ]; then - echo "⚠️ Could not parse version from: $IMAGE_BASE_VERSION" + # Get architectures from the base image manifest + ARCHITECTURES=$(docker manifest inspect "$BASE_IMAGE_FULL" 2>/dev/null | grep -o '"architecture": "[^"]*"' | cut -d'"' -f4 | sort -u) + + if [ -z "$ARCHITECTURES" ]; then + echo "Could not inspect base image manifest: $BASE_IMAGE_FULL" echo "Defaulting to AMD64 only for safety" BUILD_PLATFORMS="linux/amd64" else - # Extract major and minor version numbers - MAJOR_VERSION=$(echo "$VERSION_STRING" | cut -d. -f1) - MINOR_VERSION=$(echo "$VERSION_STRING" | cut -d. -f2) + echo "Base image architectures found:" + echo "$ARCHITECTURES" | sed 's/^/ - /' + + # Check if both amd64 and arm64 are present + HAS_AMD64=$(echo "$ARCHITECTURES" | grep -c "amd64" || true) + HAS_ARM64=$(echo "$ARCHITECTURES" | grep -c "arm64" || true) - # Check if version >= 5.1.0 - if [ "$MAJOR_VERSION" -gt 5 ] || ([ "$MAJOR_VERSION" -eq 5 ] && [ "$MINOR_VERSION" -ge 1 ]); then - echo "✅ IsaacSim version $VERSION_STRING supports multiarch" + if [ "$HAS_AMD64" -gt 0 ] && [ "$HAS_ARM64" -gt 0 ]; then + echo "Base image supports multiarch (amd64 + arm64)" BUILD_PLATFORMS="linux/amd64,linux/arm64" + elif [ "$HAS_AMD64" -gt 0 ]; then + echo "Base image only supports amd64" + BUILD_PLATFORMS="linux/amd64" + elif [ "$HAS_ARM64" -gt 0 ]; then + echo "Base image only supports arm64" + BUILD_PLATFORMS="linux/arm64" else - echo "⚠️ IsaacSim version $VERSION_STRING does not support multiarch (requires >= 5.1.0)" - echo "Building for AMD64 only" + echo "Unknown architecture support, defaulting to amd64" BUILD_PLATFORMS="linux/amd64" fi fi echo "Building image: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG" - echo "IsaacSim version: $IMAGE_BASE_VERSION (parsed: $VERSION_STRING)" + echo "IsaacSim version: $IMAGE_BASE_VERSION" + echo "Base image: $BASE_IMAGE_FULL" echo "Target platforms: $BUILD_PLATFORMS" # Build Docker image once with both tags for multiple architectures