diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 4db906b6..aa11fe86 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -28,6 +28,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: false +permissions: + contents: read + packages: write + env: ## Default versions are specified in packages.yaml but can be overridden ## note: nightly builds will always use the master/main branch @@ -42,7 +46,7 @@ env: ## GitHub registry GH_REGISTRY: ghcr.io GH_REGISTRY_USER: eic - GH_PUSH: 1 + GH_PUSH: 1 # required ## Number of jobs to start during container builds JOBS: 4 @@ -52,40 +56,96 @@ env: jobs: base: - runs-on: ubuntu-latest + name: Build base on ${{ matrix.arch }} + runs-on: ${{ matrix.runner }} strategy: matrix: include: - BASE_IMAGE: debian:stable-slim BUILD_IMAGE: debian_stable_base - PLATFORM: linux/amd64 + PLATFORM: linux/amd64 + runner: ubuntu-latest + arch: amd64 + - BASE_IMAGE: debian:stable-slim + BUILD_IMAGE: debian_stable_base + PLATFORM: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 steps: - - name: Checkout + - name: Checkout uses: actions/checkout@v4 + - name: Inject enhanced GitHub environment variables + uses: rlespinasse/github-slug-action@v5 + - name: Load spack version and cherry-picks + id: spack + shell: bash + run: | + source spack.sh + echo "orgrepo=${SPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT + echo "version=${SPACK_VERSION}" | tee -a $GITHUB_OUTPUT + echo "cherrypicks=${SPACK_CHERRYPICKS//$'\n'/ }" | tee -a $GITHUB_OUTPUT + echo "cherrypicks_files=${SPACK_CHERRYPICKS_FILES//$'\n'/ }" | tee -a $GITHUB_OUTPUT + - name: Load spack-packages version and cherry-picks + id: spack-packages + shell: bash + run: | + source spack-packages.sh + echo "orgrepo=${SPACKPACKAGES_ORGREPO}" | tee -a $GITHUB_OUTPUT + echo "version=${SPACKPACKAGES_VERSION}" | tee -a $GITHUB_OUTPUT + echo "cherrypicks=${SPACKPACKAGES_CHERRYPICKS//$'\n'/ }" | tee -a $GITHUB_OUTPUT + echo "cherrypicks_files=${SPACKPACKAGES_CHERRYPICKS_FILES//$'\n'/ }" | tee -a $GITHUB_OUTPUT + - name: Load key4hep-spack version + id: key4hep-spack + run: | + source key4hep-spack.sh + echo "orgrepo=${KEY4HEPSPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT + echo "version=${KEY4HEPSPACK_VERSION}" | tee -a $GITHUB_OUTPUT + - name: Load eic-spack version + id: eic-spack + run: | + source eic-spack.sh + echo "orgrepo=${EICSPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT + echo "version=${EICSPACK_VERSION}" | tee -a $GITHUB_OUTPUT - name: Set up QEMU uses: docker/setup-qemu-action@v3 with: platforms: linux/amd64,linux/arm64 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + id: buildx + - name: Cache build mounts + # Cache mount contents (ccache, apt cache, spack cache) using GitHub Actions cache + # This is separate from the registry cache which stores image layers + # Reference: https://docs.docker.com/build/ci/github-actions/cache/#cache-mounts + # Implementation: https://github.com/reproducible-containers/buildkit-cache-dance + uses: actions/cache@v4 + id: cache-base-mounts + with: + path: cache-mount-base-${{ matrix.arch }} + key: ${{ matrix.arch }}-base-mounts-${{ github.ref_name }} + restore-keys: | + ${{ matrix.arch }}-base-mounts-main + ${{ matrix.arch }}-base-mounts- + - name: Inject cache mounts into builder + uses: reproducible-containers/buildkit-cache-dance@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + cache-dir: cache-mount-base-${{ matrix.arch }} + cache-map: | + { + "var-cache-apt": "/var/cache/apt", + "var-lib-apt": "/var/lib/apt", + "var-cache-spack": "/var/cache/spack" + } + skip-extraction: ${{ steps.cache-base-mounts.outputs.cache-hit }} - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: | - name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }},enable=${{ env.DH_PUSH != 0 }} - name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }},enable=${{ env.GH_PUSH != 0 }} + name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }} tags: | - ${{ env.INTERNAL_TAG }} - type=schedule - type=ref,prefix=unstable-pr-,event=pr - - name: Login to Docker Hub - uses: docker/login-action@v3 - if: ${{ env.DH_PUSH == '1' }} - with: - registry: ${{ env.DH_REGISTRY }} - username: ${{ env.DH_REGISTRY_USER }} - password: ${{ secrets.DH_EICWEB_TOKEN }} + type=sha,prefix=${{ matrix.arch }}- - name: Login to GitHub Container Registry uses: docker/login-action@v3 if: ${{ env.GH_PUSH == '1' }} @@ -95,30 +155,144 @@ jobs: password: ${{ secrets.GHCR_REGISTRY_TOKEN }} - name: Build and push uses: docker/build-push-action@v5 + id: build with: - file: containers/debian/base.Dockerfile + file: containers/debian/Dockerfile context: containers/debian platforms: ${{ matrix.PLATFORM }} - push: true - tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }},push-by-digest=true,name-canonical=true,push=true build-args: | BASE_IMAGE=${{ matrix.BASE_IMAGE }} BUILD_IMAGE=${{ matrix.BUILD_IMAGE }} - cache-from: type=gha,scope=${{ github.workflow }} - cache-to: type=gha,mode=max,scope=${{ github.workflow }} + SPACK_ORGREPO=${{ steps.spack.outputs.orgrepo }} + SPACK_VERSION=${{ steps.spack.outputs.version }} + SPACK_CHERRYPICKS=${{ steps.spack.outputs.cherrypicks }} + SPACK_CHERRYPICKS_FILES=${{ steps.spack.outputs.cherrypicks_files }} + SPACKPACKAGES_ORGREPO=${{ steps.spack-packages.outputs.orgrepo }} + SPACKPACKAGES_VERSION=${{ steps.spack-packages.outputs.version }} + SPACKPACKAGES_CHERRYPICKS=${{ steps.spack-packages.outputs.cherrypicks }} + SPACKPACKAGES_CHERRYPICKS_FILES=${{ steps.spack-packages.outputs.cherrypicks_files }} + KEY4HEPSPACK_ORGREPO=${{ steps.key4hep-spack.outputs.orgrepo }} + KEY4HEPSPACK_VERSION=${{ steps.key4hep-spack.outputs.version }} + EICSPACK_ORGREPO=${{ steps.eic-spack.outputs.orgrepo }} + EICSPACK_VERSION=${{ steps.eic-spack.outputs.version }} + jobs=${{ env.JOBS }} + cache-from: | + type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}-${{ env.GITHUB_HEAD_REF_SLUG }}-${{ matrix.arch }} + type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}-${{ env.GITHUB_BASE_REF_SLUG }}-${{ matrix.arch }} + cache-to: type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}-${{ env.GITHUB_HEAD_REF_SLUG }}-${{ matrix.arch }},mode=max + - name: Export digest to file + # The build-push action outputs the digest at steps.build.outputs.digest + # We write this to a file for the next job + run: | + mkdir -p /tmp/digests + echo "${{ steps.meta.outputs.tags }}@${{ steps.build.outputs.digest }}" > /tmp/digests/${{ matrix.arch }}.digest + - name: Upload digest as artifact + uses: actions/upload-artifact@v4 + with: + name: base-${{ matrix.arch }}-digest + path: /tmp/digests/${{ matrix.arch }}.digest + retention-days: 1 - dev: + base-manifest: + name: Push base manifest runs-on: ubuntu-latest needs: base + steps: + - name: Set up QEMU (for imagetools) + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + if: ${{ env.DH_PUSH == '1' }} + with: + registry: ${{ env.DH_REGISTRY }} + username: ${{ env.DH_REGISTRY_USER }} + password: ${{ secrets.DH_EICWEB_TOKEN }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: ${{ env.GH_PUSH == '1' }} + with: + registry: ${{ env.GH_REGISTRY }} + username: ${{ secrets.GHCR_REGISTRY_USER }} + password: ${{ secrets.GHCR_REGISTRY_TOKEN }} + - name: Download all digest artifacts + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: base-*-digest + merge-multiple: true + - name: Analyze digest artifacts + id: digests + run: | + # Read the digests from the files + DIGEST_AMD64=$(cat /tmp/digests/amd64.digest) + DIGEST_ARM64=$(cat /tmp/digests/arm64.digest) + # Get the base image name from the digests (they'll be the same) + REGISTRY_IMAGE_TAG=$(echo $DIGEST_AMD64 | cut -d'@' -f1) + REGISTRY_IMAGE=$(echo $REGISTRY_IMAGE_TAG | cut -d':' -f1) + REGISTRY=$(echo $REGISTRY_IMAGE | cut -d'/' -f1-2) + IMAGE=$(echo $REGISTRY_IMAGE | cut -d'/' -f3) + TAG=$(echo $REGISTRY_IMAGE_TAG | cut -d':' -f2) + echo "Registry Name: $REGISTRY" + echo "Image Name: $IMAGE" + echo "Tag Name: $TAG" + echo "AMD64 Digest: $DIGEST_AMD64" + echo "ARM64 Digest: $DIGEST_ARM64" + echo "registry=$REGISTRY" >> $GITHUB_OUTPUT + echo "image=$IMAGE" >> $GITHUB_OUTPUT + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "amd64=$DIGEST_AMD64" >> $GITHUB_OUTPUT + echo "arm64=$DIGEST_ARM64" >> $GITHUB_OUTPUT + - name: Extract Docker metadata for final tags + id: meta + uses: docker/metadata-action@v5 + with: + images: | + name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/${{ steps.digests.outputs.image }},enable=${{ env.DH_PUSH != 0 }} + name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ steps.digests.outputs.image }},enable=${{ env.GH_PUSH != 0 }} + tags: | + ${{ env.INTERNAL_TAG }} + type=ref,prefix=unstable-pr-,event=pr + type=match,pattern=^v(\d+\.\d+\.\d+-.*)$,group=1 + - name: Create and push manifest list + run: | + # Create tag arguments from the multi-line 'tags' output from the meta step + TAG_ARGS="" + while read -r line; do + TAG_ARGS="$TAG_ARGS --tag $line" + done <<< "${{ steps.meta.outputs.tags }}" + # Create the manifest list and tag it with the final tags + docker buildx imagetools create \ + $TAG_ARGS \ + ${{ steps.digests.outputs.amd64 }} \ + ${{ steps.digests.outputs.arm64 }} + + eic: + name: Build eic on ${{ matrix.arch }} + runs-on: ${{ matrix.runner }} + needs: base-manifest strategy: matrix: include: - - BUILDER_IMAGE: debian_stable_base + - BUILD_IMAGE: eic_ + ENV: xl + BUILD_TYPE: default + BUILDER_IMAGE: debian_stable_base RUNTIME_IMAGE: debian_stable_base - BUILD_IMAGE: dev PLATFORM: linux/amd64 - ENV: dev + runner: ubuntu-latest + arch: amd64 + - BUILD_IMAGE: eic_ + ENV: xl + BUILD_TYPE: default + BUILDER_IMAGE: debian_stable_base + RUNTIME_IMAGE: debian_stable_base + PLATFORM: linux/arm64 + runner: ubuntu-24.04-arm + arch: arm64 steps: - name: Free Disk Space (Ubuntu) uses: jlumbroso/free-disk-space@v1.3.1 @@ -127,59 +301,57 @@ jobs: dotnet: true - name: Checkout uses: actions/checkout@v4 - - name: Load spack version and cherry-picks - id: spack - shell: bash - run: | - source spack.sh - echo "orgrepo=${SPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT - echo "version=${SPACK_VERSION}" | tee -a $GITHUB_OUTPUT - echo "cherrypicks=${SPACK_CHERRYPICKS//$'\n'/ }" | tee -a $GITHUB_OUTPUT - echo "cherrypicks_files=${SPACK_CHERRYPICKS_FILES//$'\n'/ }" | tee -a $GITHUB_OUTPUT - - name: Load key4hep-spack version - id: key4hep-spack - run: | - source key4hep-spack.sh - echo "orgrepo=${KEY4HEPSPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT - echo "version=${KEY4HEPSPACK_VERSION}" | tee -a $GITHUB_OUTPUT - - name: Load eic-spack version - id: eic-spack - run: | - source eic-spack.sh - echo "orgrepo=${EICSPACK_ORGREPO}" | tee -a $GITHUB_OUTPUT - echo "version=${EICSPACK_VERSION}" | tee -a $GITHUB_OUTPUT - name: Load secrets into mirrors.yaml id: mirrors run: | - source spack.sh + source spack-packages.sh export SPACKPACKAGES_VERSION export CI_REGISTRY=ghcr.io export CI_PROJECT_PATH=eic - export CI_REGISTRY_USER=${{ secrets.GHCR_REGISTRY_USER }} - export CI_REGISTRY_PASSWORD=${{ secrets.GHCR_REGISTRY_TOKEN }} - export GITHUB_REGISTRY_USER=${{ secrets.GHCR_REGISTRY_USER }} - export GITHUB_REGISTRY_TOKEN=${{ secrets.GHCR_REGISTRY_TOKEN }} - export S3RW_ACCESS_KEY=${{ secrets.S3RW_ACCESS_KEY }} - export S3RW_SECRET_KEY=${{ secrets.S3RW_SECRET_KEY }} cat mirrors.yaml.in | envsubst > mirrors.yaml + - name: Inject enhanced GitHub environment variables + uses: rlespinasse/github-slug-action@v5 - name: Set up QEMU uses: docker/setup-qemu-action@v3 with: - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + id: buildx + - name: Cache build mounts + # Cache mount contents (ccache, apt cache, spack cache) using GitHub Actions cache + # This is separate from the registry cache which stores image layers + # Reference: https://docs.docker.com/build/ci/github-actions/cache/#cache-mounts + # Implementation: https://github.com/reproducible-containers/buildkit-cache-dance + uses: actions/cache@v4 + id: cache-eic-mounts + with: + path: cache-mount-eic-${{ matrix.arch }} + key: ${{ matrix.arch }}-eic-${{ matrix.ENV }}-mounts-${{ github.ref_name }} + restore-keys: | + ${{ matrix.arch }}-eic-${{ matrix.ENV }}-mounts-main + ${{ matrix.arch }}-eic-${{ matrix.ENV }}-mounts- + ${{ matrix.arch }}-eic-mounts- + - name: Inject cache mounts into builder + uses: reproducible-containers/buildkit-cache-dance@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + cache-dir: cache-mount-eic-${{ matrix.arch }} + cache-map: | + { + "ccache": "/ccache", + "var-cache-spack": "/var/cache/spack" + } + skip-extraction: ${{ steps.cache-eic-mounts.outputs.cache-hit }} - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: | - name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/eic_${{ matrix.BUILD_IMAGE }},enable=${{ env.DH_PUSH != 0 }} - name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/eic_${{ matrix.BUILD_IMAGE }},enable=${{ env.GH_PUSH != 0 }} + name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }},enable=${{ env.DH_PUSH != 0 }} + name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }},enable=${{ env.GH_PUSH != 0 }} tags: | - ${{ env.INTERNAL_TAG }} - type=schedule,pattern={{date 'YYYY-MM-DD'}} - type=ref,prefix=unstable-pr-,event=pr - type=match,pattern=^v(\d+\.\d+\.\d+-.*)$,group=1 + type=sha,prefix=${{ matrix.arch }}- - name: Login to Docker Hub uses: docker/login-action@v3 if: ${{ env.DH_PUSH == '1' }} @@ -196,74 +368,57 @@ jobs: password: ${{ secrets.GHCR_REGISTRY_TOKEN }} - name: Build and push uses: docker/build-push-action@v5 + id: build with: - file: containers/jug/dev.Dockerfile - context: containers/jug + file: containers/eic/Dockerfile + context: containers/eic build-contexts: | spack-environment=spack-environment + secrets: | + "CI_REGISTRY_USER=${{ secrets.GHCR_REGISTRY_USER }}" + "CI_REGISTRY_PASSWORD=${{ secrets.GHCR_REGISTRY_TOKEN }}" + "GITHUB_REGISTRY_USER=${{ secrets.GHCR_REGISTRY_USER }}" + "GITHUB_REGISTRY_TOKEN=${{ secrets.GHCR_REGISTRY_TOKEN }}" secret-files: | mirrors=mirrors.yaml platforms: ${{ matrix.PLATFORM }} - push: true - tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }},push-by-digest=true,name-canonical=true,push=true build-args: | DOCKER_REGISTRY=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/ BUILDER_IMAGE=${{ matrix.BUILDER_IMAGE }} RUNTIME_IMAGE=${{ matrix.RUNTIME_IMAGE }} - BUILD_IMAGE=eic_${{ matrix.BUILD_IMAGE }} INTERNAL_TAG=${{ env.INTERNAL_TAG }} - SPACK_ORGREPO=${{ steps.spack.outputs.orgrepo }} - SPACK_VERSION=${{ steps.spack.outputs.version }} - SPACK_CHERRYPICKS=${{ steps.spack.outputs.cherrypicks }} - SPACK_CHERRYPICKS_FILES=${{ steps.spack.outputs.cherrypicks_files }} - KEY4HEPSPACK_ORGREPO=${{ steps.eic-spack.outputs.orgrepo }} - KEY4HEPSPACK_VERSION=${{ steps.eic-spack.outputs.version }} - EICSPACK_ORGREPO=${{ steps.eic-spack.outputs.orgrepo }} - EICSPACK_VERSION=${{ steps.eic-spack.outputs.version }} - KEY4HEPSPACK_ORGREPO=${{ steps.key4hep-spack.outputs.orgrepo }} - KEY4HEPSPACK_VERSION=${{ steps.key4hep-spack.outputs.version }} - S3_ACCESS_KEY=${{ secrets.S3_ACCESS_KEY }} - S3_SECRET_KEY=${{ secrets.S3_SECRET_KEY }} - jobs=${{ env.JOBS }} - cache-from: type=gha,scope=${{ github.workflow }} - cache-to: type=gha,mode=max,scope=${{ github.workflow }} + ENV=${{ matrix.ENV }} + cache-from: | + type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}-${{ env.GITHUB_HEAD_REF_SLUG }}-${{ matrix.arch }} + type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}-${{ env.GITHUB_BASE_REF_SLUG }}-${{ matrix.arch }} + cache-to: type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}-${{ env.GITHUB_HEAD_REF_SLUG }}-${{ matrix.arch }},mode=max + - name: Export digest to file + # The build-push action outputs the digest at steps.build.outputs.digest + # We write this to a file for the next job + run: | + mkdir -p /tmp/digests + echo "${{ steps.meta.outputs.tags }}@${{ steps.build.outputs.digest }}" > /tmp/digests/${{ matrix.arch }}.digest + - name: Upload digest as artifact + uses: actions/upload-artifact@v4 + with: + name: eic-${{ matrix.ENV }}-${{ matrix.arch }}-digest + path: /tmp/digests/${{ matrix.arch }}.digest + retention-days: 1 - xl: + eic-manifest: + name: Push eic manifest runs-on: ubuntu-latest - needs: dev + needs: eic strategy: matrix: - include: - - BASE_IMAGE: dev - BUILD_IMAGE: xl - PLATFORM: linux/amd64 + ENV: [xl] steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@v1.3.1 - with: - android: true - dotnet: true - - name: Checkout - uses: actions/checkout@v4 - - name: Set up QEMU + - name: Set up QEMU (for imagetools) uses: docker/setup-qemu-action@v3 - with: - platforms: linux/amd64 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: | - name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/eic_${{ matrix.BUILD_IMAGE }},enable=${{ env.DH_PUSH != 0 }} - name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/eic_${{ matrix.BUILD_IMAGE }},enable=${{ env.GH_PUSH != 0 }} - tags: | - ${{ env.INTERNAL_TAG }} - type=schedule,pattern={{date 'YYYY-MM-DD'}} - type=ref,prefix=unstable-pr-,event=pr - type=match,pattern=^v(\d+\.\d+\.\d+-.*)$,group=1 - name: Login to Docker Hub uses: docker/login-action@v3 if: ${{ env.DH_PUSH == '1' }} @@ -278,22 +433,54 @@ jobs: registry: ${{ env.GH_REGISTRY }} username: ${{ secrets.GHCR_REGISTRY_USER }} password: ${{ secrets.GHCR_REGISTRY_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v5 + - name: Download all digest artifacts + uses: actions/download-artifact@v4 with: - file: containers/jug/xl.Dockerfile - context: containers/jug - build-contexts: | - detectors=. - platforms: ${{ matrix.PLATFORM }} - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - DOCKER_REGISTRY=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/ - BASE_IMAGE=eic_${{ matrix.BASE_IMAGE }} - BUILD_IMAGE=eic_${{ matrix.BUILD_IMAGE }} - INTERNAL_TAG=${{ env.INTERNAL_TAG }} - jobs=${{ env.JOBS }} - cache-from: type=gha,scope=${{ github.workflow }} - cache-to: type=gha,mode=max,scope=${{ github.workflow }} + path: /tmp/digests + pattern: eic-${{ matrix.ENV }}-*-digest + merge-multiple: true + - name: Analyze digest artifacts + id: digests + run: | + # Read the digests from the files + DIGEST_AMD64=$(cat /tmp/digests/amd64.digest) + DIGEST_ARM64=$(cat /tmp/digests/arm64.digest) + # Get the base image name from the digests (they'll be the same) + REGISTRY_IMAGE_TAG=$(echo $DIGEST_AMD64 | cut -d'@' -f1) + REGISTRY_IMAGE=$(echo $REGISTRY_IMAGE_TAG | cut -d':' -f1) + REGISTRY=$(echo $REGISTRY_IMAGE | cut -d'/' -f1-2) + IMAGE=$(echo $REGISTRY_IMAGE | cut -d'/' -f3) + TAG=$(echo $REGISTRY_IMAGE_TAG | cut -d':' -f2) + echo "Registry Name: $REGISTRY" + echo "Image Name: $IMAGE" + echo "Tag Name: $TAG" + echo "AMD64 Digest: $DIGEST_AMD64" + echo "ARM64 Digest: $DIGEST_ARM64" + echo "registry=$REGISTRY" >> $GITHUB_OUTPUT + echo "image=$IMAGE" >> $GITHUB_OUTPUT + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "amd64=$DIGEST_AMD64" >> $GITHUB_OUTPUT + echo "arm64=$DIGEST_ARM64" >> $GITHUB_OUTPUT + - name: Extract Docker metadata for final tags + id: meta + uses: docker/metadata-action@v5 + with: + images: | + name=${{ env.DH_REGISTRY }}/${{ env.DH_REGISTRY_USER }}/${{ steps.digests.outputs.image }},enable=${{ env.DH_PUSH != 0 }} + name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ steps.digests.outputs.image }},enable=${{ env.GH_PUSH != 0 }} + tags: | + ${{ env.INTERNAL_TAG }} + type=ref,prefix=unstable-pr-,event=pr + type=match,pattern=^v(\d+\.\d+\.\d+-.*)$,group=1 + - name: Create and push manifest list + run: | + # Create tag arguments from the multi-line 'tags' output from the meta step + TAG_ARGS="" + while read -r line; do + TAG_ARGS="$TAG_ARGS --tag $line" + done <<< "${{ steps.meta.outputs.tags }}" + # Create the manifest list and tag it with the final tags + docker buildx imagetools create \ + $TAG_ARGS \ + ${{ steps.digests.outputs.amd64 }} \ + ${{ steps.digests.outputs.arm64 }} diff --git a/.github/workflows/mirror.yaml b/.github/workflows/mirror.yaml index 187069e5..9042a4ff 100644 --- a/.github/workflows/mirror.yaml +++ b/.github/workflows/mirror.yaml @@ -23,6 +23,7 @@ jobs: with: fetch-depth: 0 - name: Push to EICweb + if: ${{ github.event_name == 'push' }} uses: eic/gitlab-sync@master with: url: https://eicweb.phy.anl.gov/containers/eic_container.git/ diff --git a/containers/debian/Dockerfile b/containers/debian/Dockerfile index 196453b0..0e58ead3 100644 --- a/containers/debian/Dockerfile +++ b/containers/debian/Dockerfile @@ -165,7 +165,9 @@ RUN <