build-push #3451
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: build-push | |
| on: | |
| schedule: | |
| - cron: "30 */6 * * *" | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| EDM4EIC_VERSION: | |
| required: false | |
| default: '' | |
| type: string | |
| EICRECON_VERSION: | |
| required: false | |
| default: '' | |
| type: string | |
| JUGGLER_VERSION: | |
| required: false | |
| default: '' | |
| type: string | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| ## CUDA version and container operating system | |
| CUDA_VERSION: 12.5.1 | |
| CUDA_OS: ubuntu24.04 | |
| ## Default versions are specified in packages.yaml but can be overridden | |
| ## note: nightly builds will always use the master/main branch | |
| EDM4EIC_VERSION: ${{ inputs.EDM4EIC_VERSION }} | |
| EICRECON_VERSION: ${{ inputs.EICRECON_VERSION }} | |
| JUGGLER_VERSION: ${{ inputs.JUGGLER_VERSION }} | |
| ## Dockerhub registry | |
| DH_REGISTRY: docker.io | |
| DH_REGISTRY_USER: eicweb | |
| DH_PUSH: 0 | |
| ## GitHub registry | |
| GH_REGISTRY: ghcr.io | |
| GH_REGISTRY_USER: eic | |
| GH_PUSH: 1 # required | |
| ## Number of jobs to start during container builds | |
| JOBS: 4 | |
| ## Internal tag used for the CI | |
| INTERNAL_TAG: pipeline-${{ github.run_id }} | |
| ## Compressed image size caps (GiB). Fail the build if a final image exceeds | |
| ## these limits to catch regressions early (e.g. accidental Spack-built LLVM). | |
| ## To update: measure the compressed sizes of the published master images, | |
| ## add ~15% headroom, round up, and update here and in .gitlab-ci.yml | |
| ## variables. | |
| SIZE_LIMIT_DEBIAN_STABLE_BASE_GIB: 0.9 | |
| SIZE_LIMIT_EIC_CI_GIB: 3.1 | |
| SIZE_LIMIT_EIC_XL_GIB: 4.6 | |
| jobs: | |
| env: | |
| ## The env context is not available in matrix, only in steps, | |
| ## so this job is merely to transfer env to job outputs which | |
| ## can be used in matrix. | |
| name: Turn env into outputs | |
| runs-on: ubuntu-latest | |
| outputs: | |
| CUDA_VERSION: ${{ steps.env.outputs.CUDA_VERSION }} | |
| CUDA_OS: ${{ steps.env.outputs.CUDA_OS }} | |
| BUILDWEEK: ${{ steps.env.outputs.BUILDWEEK }} | |
| steps: | |
| - name: Turn env into outputs | |
| id: env | |
| run: | | |
| echo "CUDA_VERSION=${{ env.CUDA_VERSION }}" >> $GITHUB_OUTPUT | |
| echo "CUDA_OS=${{ env.CUDA_OS }}" >> $GITHUB_OUTPUT | |
| echo "BUILDWEEK=$(date +%Yw%V)" >> $GITHUB_OUTPUT | |
| base: | |
| name: Build ${{ matrix.BUILD_IMAGE }} on ${{ matrix.arch }} | |
| runs-on: ${{ matrix.runner }} | |
| needs: env | |
| strategy: | |
| matrix: | |
| include: | |
| - BASE_IMAGE: debian:stable-slim | |
| BUILD_IMAGE: debian_stable_base | |
| PLATFORM: linux/amd64 | |
| runner: ubuntu-latest | |
| arch: amd64 | |
| - BASE_IMAGE: debian:stable-slim | |
| BUILD_IMAGE: debian_stable_base | |
| PLATFORM: linux/amd64/v3 | |
| runner: ubuntu-latest | |
| arch: amd64_v3 | |
| - BASE_IMAGE: debian:stable-slim | |
| BUILD_IMAGE: debian_stable_base | |
| PLATFORM: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| arch: arm64 | |
| - BASE_IMAGE: nvidia/cuda:${{ needs.env.outputs.CUDA_VERSION }}-devel-${{ needs.env.outputs.CUDA_OS }} | |
| BUILD_IMAGE: cuda_devel | |
| PLATFORM: linux/amd64 | |
| runner: ubuntu-latest | |
| arch: amd64 | |
| - BASE_IMAGE: nvidia/cuda:${{ needs.env.outputs.CUDA_VERSION }}-runtime-${{ needs.env.outputs.CUDA_OS }} | |
| BUILD_IMAGE: cuda_runtime | |
| PLATFORM: linux/amd64 | |
| runner: ubuntu-latest | |
| arch: amd64 | |
| fail-fast: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Inject enhanced GitHub environment variables | |
| uses: rlespinasse/github-slug-action@v5 | |
| - name: Load NVIDIA visible devices and driver capabilities | |
| id: nvidia | |
| shell: bash | |
| run: | | |
| case "${{ matrix.BUILD_IMAGE }}" in | |
| cuda*) | |
| NVIDIA_VISIBLE_DEVICES=all | |
| NVIDIA_DRIVER_CAPABILITIES=all | |
| ;; | |
| esac | |
| echo "visible_devices=${NVIDIA_VISIBLE_DEVICES}" | tee -a $GITHUB_OUTPUT | |
| echo "driver_capabilities=${NVIDIA_DRIVER_CAPABILITIES}" | tee -a $GITHUB_OUTPUT | |
| - 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 "sha=$(.ci/resolve_git_ref ${SPACK_ORGREPO} ${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 "sha=$(.ci/resolve_git_ref ${SPACKPACKAGES_ORGREPO} ${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 | |
| echo "sha=$(.ci/resolve_git_ref ${KEY4HEPSPACK_ORGREPO} ${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 | |
| echo "sha=$(.ci/resolve_git_ref ${EICSPACK_ORGREPO} ${EICSPACK_VERSION})" | tee -a $GITHUB_OUTPUT | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| with: | |
| platforms: linux/amd64,linux/amd64/v3,linux/arm64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| 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@v6 | |
| id: cache-base-mounts | |
| with: | |
| path: cache-mount-base-${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }} | |
| key: ${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }}-base-mounts-${{ github.ref_name }}-${{ needs.env.outputs.BUILDWEEK }} | |
| restore-keys: | | |
| ${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }}-base-mounts-main-${{ needs.env.outputs.BUILDWEEK }} | |
| ${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }}-base-mounts-main | |
| ${{ matrix.BUILD_IMAGE }}-${{ 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.BUILD_IMAGE }}-${{ 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@v6 | |
| with: | |
| images: | | |
| name=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${{ matrix.BUILD_IMAGE }} | |
| tags: | | |
| type=sha,prefix=${{ matrix.arch }}- | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| if: ${{ env.GH_PUSH == '1' }} | |
| with: | |
| registry: ${{ env.GH_REGISTRY }} | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| - name: Build and push | |
| uses: docker/build-push-action@v7 | |
| id: build | |
| with: | |
| file: containers/debian/Dockerfile | |
| context: containers/debian | |
| platforms: ${{ matrix.PLATFORM }} | |
| 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 }} | |
| NVIDIA_VISIBLE_DEVICES=${{ steps.nvidia.outputs.visible_devices }} | |
| NVIDIA_DRIVER_CAPABILITIES=${{ steps.nvidia.outputs.driver_capabilities }} | |
| SPACK_ORGREPO=${{ steps.spack.outputs.orgrepo }} | |
| SPACK_VERSION=${{ steps.spack.outputs.version }} | |
| SPACK_SHA=${{ steps.spack.outputs.sha }} | |
| 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_SHA=${{ steps.spack-packages.outputs.sha }} | |
| 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 }} | |
| KEY4HEPSPACK_SHA=${{ steps.key4hep-spack.outputs.sha }} | |
| EICSPACK_ORGREPO=${{ steps.eic-spack.outputs.orgrepo }} | |
| EICSPACK_VERSION=${{ steps.eic-spack.outputs.version }} | |
| EICSPACK_SHA=${{ steps.eic-spack.outputs.sha }} | |
| jobs=${{ env.JOBS }} | |
| BUILDWEEK=${{ needs.env.outputs.BUILDWEEK }} | |
| cache-from: | | |
| type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}-${{ env.GITHUB_REF_POINT_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_REF_POINT_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.BUILD_IMAGE }}-${{ matrix.arch }}.digest | |
| - name: Check image size | |
| run: | | |
| FULLNAME="${{ matrix.BUILD_IMAGE }}" | |
| LIMIT_VAR="SIZE_LIMIT_$(printf '%s' "${FULLNAME}" | tr '[:lower:]' '[:upper:]')_GIB" | |
| LIMIT="${!LIMIT_VAR}" | |
| if [ -n "${LIMIT}" ]; then | |
| .ci/check_image_size \ | |
| "${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${FULLNAME}@${{ steps.build.outputs.digest }}" \ | |
| "${LIMIT}" | |
| else | |
| echo "No size limit configured for ${FULLNAME}, skipping check." | |
| fi | |
| - name: Upload digest as artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: base-${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }}-digest | |
| path: /tmp/digests/${{ matrix.BUILD_IMAGE }}-${{ matrix.arch }}.digest | |
| retention-days: 1 | |
| base-manifest: | |
| name: Push ${{ matrix.BUILD_IMAGE }} manifest | |
| runs-on: ubuntu-latest | |
| needs: base | |
| strategy: | |
| matrix: | |
| include: | |
| - BUILD_IMAGE: debian_stable_base | |
| - BUILD_IMAGE: cuda_devel | |
| - BUILD_IMAGE: cuda_runtime | |
| steps: | |
| - name: Set up QEMU (for imagetools) | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v4 | |
| 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@v4 | |
| 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@v8 | |
| with: | |
| path: /tmp/digests | |
| pattern: base-${{ matrix.BUILD_IMAGE }}-*-digest | |
| merge-multiple: true | |
| - name: Analyze digest artifacts | |
| id: digests | |
| run: | | |
| # Loop over all available architecture artifacts | |
| ALL_DIGESTS="" | |
| FIRST_DIGEST="" | |
| shopt -s nullglob | |
| for digest_file in /tmp/digests/${{ matrix.BUILD_IMAGE }}-*.digest; do | |
| DIGEST=$(cat "$digest_file") | |
| echo "Found digest: $DIGEST" | |
| if [ -z "$ALL_DIGESTS" ]; then | |
| ALL_DIGESTS="$DIGEST" | |
| else | |
| ALL_DIGESTS="$ALL_DIGESTS $DIGEST" | |
| fi | |
| if [ -z "$FIRST_DIGEST" ]; then | |
| FIRST_DIGEST="$DIGEST" | |
| fi | |
| done | |
| shopt -u nullglob | |
| # Check if at least one digest was found | |
| if [ -z "$FIRST_DIGEST" ]; then | |
| echo "Error: No digest files found" | |
| exit 1 | |
| fi | |
| # Get the base image name from the first digest | |
| REGISTRY_IMAGE_TAG=$(echo $FIRST_DIGEST | 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 "All Digests: $ALL_DIGESTS" | |
| echo "registry=$REGISTRY" >> $GITHUB_OUTPUT | |
| echo "image=$IMAGE" >> $GITHUB_OUTPUT | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "all=$ALL_DIGESTS" >> $GITHUB_OUTPUT | |
| - name: Extract Docker metadata for final tags | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| 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.all }} | |
| eic: | |
| name: Build ${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }} on ${{ matrix.arch }} | |
| runs-on: ${{ matrix.runner }} | |
| needs: base-manifest | |
| strategy: | |
| matrix: | |
| include: | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: ci | |
| arch: amd64 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: ci | |
| arch: amd64_v3 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64/v3 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: ci | |
| arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| PLATFORM: linux/arm64 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: xl | |
| arch: amd64 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: xl | |
| arch: amd64_v3 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64/v3 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: debian_stable_base | |
| RUNTIME_IMAGE: debian_stable_base | |
| ENV: xl | |
| arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| PLATFORM: linux/arm64 | |
| target: final | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: cuda_devel | |
| RUNTIME_IMAGE: cuda_devel | |
| ENV: cuda | |
| arch: amd64 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64 | |
| target: builder_concretization_default | |
| - BUILD_IMAGE: eic_ | |
| BUILD_TYPE: default | |
| BUILDER_IMAGE: cuda_devel | |
| RUNTIME_IMAGE: cuda_runtime | |
| ENV: tf | |
| arch: amd64 | |
| runner: ubuntu-latest | |
| PLATFORM: linux/amd64 | |
| target: builder_concretization_default | |
| fail-fast: false | |
| steps: | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@v1.3.1 | |
| with: | |
| android: true | |
| dotnet: true | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Resolve benchmarks versions | |
| id: benchmarks | |
| shell: bash | |
| run: | | |
| echo "common_bench=$(.ci/resolve_git_ref https://github.com/eic/common_bench.git master)" | tee -a $GITHUB_OUTPUT | |
| echo "detector_benchmarks=$(.ci/resolve_git_ref https://github.com/eic/detector_benchmarks.git master)" | tee -a $GITHUB_OUTPUT | |
| echo "physics_benchmarks=$(.ci/resolve_git_ref https://github.com/eic/physics_benchmarks.git master)" | tee -a $GITHUB_OUTPUT | |
| - name: Resolve campaign versions | |
| id: campaigns | |
| shell: bash | |
| run: | | |
| echo "simulation_campaign_hepmc3=$(.ci/resolve_git_ref eic/simulation_campaign_hepmc3 main)" | tee -a $GITHUB_OUTPUT | |
| echo "job_submission_condor=$(.ci/resolve_git_ref eic/job_submission_condor main)" | tee -a $GITHUB_OUTPUT | |
| echo "job_submission_slurm=$(.ci/resolve_git_ref eic/job_submission_slurm main)" | tee -a $GITHUB_OUTPUT | |
| - name: Load secrets into mirrors.yaml | |
| id: mirrors | |
| run: | | |
| source spack-packages.sh | |
| export SPACKPACKAGES_VERSION | |
| export CI_REGISTRY=ghcr.io | |
| export CI_PROJECT_PATH=eic | |
| 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@v4 | |
| with: | |
| platforms: linux/amd64,linux/amd64/v3,linux/arm64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| 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@v6 | |
| 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@v6 | |
| with: | |
| images: | | |
| 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: | | |
| type=sha,prefix=${{ matrix.arch }}- | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v4 | |
| 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@v4 | |
| if: ${{ env.GH_PUSH == '1' }} | |
| with: | |
| registry: ${{ env.GH_REGISTRY }} | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| - name: Build and push | |
| uses: docker/build-push-action@v7 | |
| id: build | |
| with: | |
| 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 }} | |
| target: ${{ matrix.target }} | |
| 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: | | |
| BENCHMARK_COM_SHA=${{ steps.benchmarks.outputs.common_bench }} | |
| BENCHMARK_DET_SHA=${{ steps.benchmarks.outputs.detector_benchmarks }} | |
| BENCHMARK_PHY_SHA=${{ steps.benchmarks.outputs.physics_benchmarks }} | |
| CAMPAIGNS_HEPMC3_SHA=${{ steps.campaigns.outputs.simulation_campaign_hepmc3 }} | |
| CAMPAIGNS_CONDOR_SHA=${{ steps.campaigns.outputs.job_submission_condor }} | |
| CAMPAIGNS_SLURM_SHA=${{ steps.campaigns.outputs.job_submission_slurm }} | |
| DOCKER_REGISTRY=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/ | |
| BUILDER_IMAGE=${{ matrix.BUILDER_IMAGE }} | |
| RUNTIME_IMAGE=${{ matrix.RUNTIME_IMAGE }} | |
| INTERNAL_TAG=${{ env.INTERNAL_TAG }} | |
| ENV=${{ matrix.ENV }} | |
| cache-from: | | |
| type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}-${{ matrix.BUILD_TYPE }}-${{ env.GITHUB_REF_POINT_SLUG }}-${{ matrix.arch }} | |
| type=registry,ref=${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/buildcache:${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}-${{ matrix.BUILD_TYPE }}-${{ 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 }}-${{ matrix.BUILD_TYPE }}-${{ env.GITHUB_REF_POINT_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: Check image size | |
| # Only check final images; concretization-only targets (cuda, tf) don't produce a full image | |
| if: ${{ matrix.target == 'final' }} | |
| run: | | |
| FULLNAME="${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }}" | |
| LIMIT_VAR="SIZE_LIMIT_$(printf '%s' "${FULLNAME}" | tr '[:lower:]' '[:upper:]')_GIB" | |
| LIMIT="${!LIMIT_VAR}" | |
| if [ -n "${LIMIT}" ]; then | |
| .ci/check_image_size \ | |
| "${{ env.GH_REGISTRY }}/${{ env.GH_REGISTRY_USER }}/${FULLNAME}@${{ steps.build.outputs.digest }}" \ | |
| "${LIMIT}" | |
| else | |
| echo "No size limit configured for ${FULLNAME}, skipping check." | |
| fi | |
| - name: Upload digest as artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: eic-${{ matrix.ENV }}-${{ matrix.arch }}-digest | |
| path: /tmp/digests/${{ matrix.arch }}.digest | |
| retention-days: 1 | |
| eic-manifest: | |
| name: Push ${{ matrix.BUILD_IMAGE }}${{ matrix.ENV }} manifest | |
| runs-on: ubuntu-latest | |
| needs: eic | |
| strategy: | |
| matrix: | |
| BUILD_IMAGE: [eic_] | |
| ENV: [ci, xl] | |
| steps: | |
| - name: Set up QEMU (for imagetools) | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v4 | |
| 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@v4 | |
| 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@v8 | |
| with: | |
| path: /tmp/digests | |
| pattern: eic-${{ matrix.ENV }}-*-digest | |
| merge-multiple: true | |
| - name: Analyze digest artifacts | |
| id: digests | |
| run: | | |
| # Loop over all available architecture artifacts | |
| ALL_DIGESTS="" | |
| FIRST_DIGEST="" | |
| shopt -s nullglob | |
| for digest_file in /tmp/digests/*.digest; do | |
| DIGEST=$(cat "$digest_file") | |
| echo "Found digest: $DIGEST" | |
| if [ -z "$ALL_DIGESTS" ]; then | |
| ALL_DIGESTS="$DIGEST" | |
| else | |
| ALL_DIGESTS="$ALL_DIGESTS $DIGEST" | |
| fi | |
| if [ -z "$FIRST_DIGEST" ]; then | |
| FIRST_DIGEST="$DIGEST" | |
| fi | |
| done | |
| shopt -u nullglob | |
| # Check if at least one digest was found | |
| if [ -z "$FIRST_DIGEST" ]; then | |
| echo "Error: No digest files found" | |
| exit 1 | |
| fi | |
| # Get the base image name from the first digest | |
| REGISTRY_IMAGE_TAG=$(echo $FIRST_DIGEST | 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 "All Digests: $ALL_DIGESTS" | |
| echo "registry=$REGISTRY" >> $GITHUB_OUTPUT | |
| echo "image=$IMAGE" >> $GITHUB_OUTPUT | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "all=$ALL_DIGESTS" >> $GITHUB_OUTPUT | |
| - name: Extract Docker metadata for final tags | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| 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.all }} | |
| npsim-gun: | |
| name: npsim (gun, ${{ matrix.particle }}, ${{ matrix.detector_config }}, ${{ matrix.arch }}) | |
| runs-on: ${{ matrix.runner }} | |
| needs: eic-manifest | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| particle: [pi, e] | |
| detector_config: [epic_craterlake] | |
| arch: [amd64, arm64] | |
| include: | |
| - arch: amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - name: Produce simulation files | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| source /opt/detector/epic-main/bin/thisepic.sh | |
| npsim \ | |
| --compactFile ${DETECTOR_PATH}/${{ matrix.detector_config }}.xml \ | |
| -G --random.seed 1 \ | |
| --random.enableEventSeed \ | |
| --gun.particle "${{ matrix.particle }}-" \ | |
| --gun.momentumMin "1*GeV" --gun.momentumMax "20*GeV" \ | |
| --gun.distribution "uniform" \ | |
| -N 100 \ | |
| --outputFile sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root \ | |
| -v WARNING | |
| - id: upload_new_artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| path: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root | |
| if-no-files-found: error | |
| - name: Download previous artifact | |
| id: download_previous_artifact | |
| uses: dawidd6/action-download-artifact@v21 | |
| with: | |
| branch: ${{ github.base_ref || github.event.merge_group.base_ref || github.ref_name }} | |
| path: ref/ | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "success" | |
| if_no_artifact_found: warn | |
| - name: Compare to previous artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| shopt -s nullglob | |
| capybara bara ref/sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root* sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root | |
| mv capybara-reports sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| touch .sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| - name: Write artifact metadata | |
| env: | |
| NEW_URL: ${{ steps.upload_new_artifact.outputs.artifact-url }} | |
| FOUND_ARTIFACT: ${{ steps.download_previous_artifact.outputs.found_artifact }} | |
| REF_ARTIFACTS: ${{ steps.download_previous_artifact.outputs.artifacts }} | |
| REPOSITORY: ${{ github.repository }} | |
| run: | | |
| REF_URL="" | |
| if [ "$FOUND_ARTIFACT" = "true" ]; then | |
| REF_ART_ID=$(echo "$REF_ARTIFACTS" | jq -r '.[0].id // empty') | |
| REF_RUN_ID=$(echo "$REF_ARTIFACTS" | jq -r '.[0].workflow_run.id // empty') | |
| if [ -n "$REF_ART_ID" ] && [ -n "$REF_RUN_ID" ]; then | |
| REF_URL="https://github.com/$REPOSITORY/actions/runs/${REF_RUN_ID}/artifacts/${REF_ART_ID}" | |
| fi | |
| fi | |
| jq -nc --arg new "$NEW_URL" --arg ref "$REF_URL" '{new: $new, ref: $ref}' \ | |
| > sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}/meta.json | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.capy | |
| path: | | |
| .sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}/ | |
| if-no-files-found: error | |
| npsim-dis: | |
| name: npsim (DIS, ${{ matrix.beam }}, minQ2=${{ matrix.minq2 }}, ${{ matrix.detector_config }}, ${{ matrix.arch }}) | |
| runs-on: ${{ matrix.runner }} | |
| needs: eic-manifest | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| beam: [5x41, 10x100, 18x275] | |
| minq2: [1, 1000] | |
| detector_config: [epic_craterlake] | |
| arch: [amd64, arm64] | |
| include: | |
| - arch: amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| exclude: | |
| - beam: 5x41 | |
| minq2: 1000 | |
| - beam: 10x100 | |
| minq2: 1 | |
| arch: arm64 | |
| - beam: 10x100 | |
| minq2: 1000 | |
| arch: arm64 | |
| - beam: 18x275 | |
| minq2: 1 | |
| arch: arm64 | |
| - beam: 18x275 | |
| minq2: 1000 | |
| arch: arm64 | |
| steps: | |
| - name: Produce simulation files | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| source /opt/detector/epic-main/bin/thisepic.sh | |
| url=root://dtn-eic.jlab.org//volatile/eic/EPIC/EVGEN/DIS/NC/${{ matrix.beam }}/minQ2=${{ matrix.minq2 }}/pythia8NCDIS_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_beamEffects_xAngle=-0.025_hiDiv_1.hepmc3.tree.root | |
| npsim \ | |
| --compactFile ${DETECTOR_PATH}/${{ matrix.detector_config }}.xml \ | |
| -N 100 --inputFiles ${url} --random.seed 1 \ | |
| --outputFile sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root \ | |
| -v WARNING | |
| - id: upload_new_artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| path: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root | |
| if-no-files-found: error | |
| - name: Download previous artifact | |
| id: download_previous_artifact | |
| uses: dawidd6/action-download-artifact@v21 | |
| with: | |
| branch: ${{ github.base_ref || github.event.merge_group.base_ref || github.ref_name }} | |
| path: ref/ | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "success" | |
| if_no_artifact_found: warn | |
| - name: Compare to previous artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| shopt -s nullglob | |
| capybara bara ref/sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root* sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root | |
| mv capybara-reports sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| touch .sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| - name: Write artifact metadata | |
| env: | |
| NEW_URL: ${{ steps.upload_new_artifact.outputs.artifact-url }} | |
| FOUND_ARTIFACT: ${{ steps.download_previous_artifact.outputs.found_artifact }} | |
| REF_ARTIFACTS: ${{ steps.download_previous_artifact.outputs.artifacts }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| REF_URL="" | |
| if [ "$FOUND_ARTIFACT" = "true" ]; then | |
| REF_ART_ID=$(echo "$REF_ARTIFACTS" | jq -r '.[0].id // empty') | |
| REF_RUN_ID=$(echo "$REF_ARTIFACTS" | jq -r '.[0].workflow_run.id // empty') | |
| if [ -n "$REF_ART_ID" ] && [ -n "$REF_RUN_ID" ]; then | |
| REF_URL="https://github.com/$GITHUB_REPOSITORY/actions/runs/${REF_RUN_ID}/artifacts/${REF_ART_ID}" | |
| fi | |
| fi | |
| jq -nc --arg new "$NEW_URL" --arg ref "$REF_URL" '{new: $new, ref: $ref}' \ | |
| > sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}/meta.json | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.capy | |
| path: | | |
| .sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}/ | |
| if-no-files-found: error | |
| eicrecon-gun: | |
| name: eicrecon (gun, ${{ matrix.particle }}, ${{ matrix.detector_config }}, ${{ matrix.arch }}) | |
| runs-on: ${{ matrix.runner }} | |
| needs: [eic-manifest, npsim-gun] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| particle: [pi, e] | |
| detector_config: [epic_craterlake] | |
| arch: [amd64, arm64] | |
| include: | |
| - arch: amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| - name: Run EICrecon | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| source /opt/detector/epic-main/bin/thisepic.sh | |
| export DETECTOR_CONFIG=${{ matrix.detector_config }} | |
| eicrecon \ | |
| -Ppodio:output_file=rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root \ | |
| sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root | |
| - id: upload_new_artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4eic.root | |
| path: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root | |
| if-no-files-found: error | |
| - name: Download previous artifact | |
| id: download_previous_artifact | |
| uses: dawidd6/action-download-artifact@v21 | |
| with: | |
| branch: ${{ github.base_ref || github.event.merge_group.base_ref || github.ref_name }} | |
| path: ref/ | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4eic.root | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "success" | |
| if_no_artifact_found: warn | |
| - name: Compare to previous artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| mkdir new | |
| ln -sf ../rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root new/ | |
| shopt -s nullglob | |
| capybara bara ref/rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root* new/rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root | |
| mv capybara-reports rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| touch .rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| - name: Write artifact metadata | |
| env: | |
| NEW_URL: ${{ steps.upload_new_artifact.outputs.artifact-url }} | |
| FOUND_ARTIFACT: ${{ steps.download_previous_artifact.outputs.found_artifact }} | |
| REF_ARTIFACTS_JSON: ${{ steps.download_previous_artifact.outputs.artifacts }} | |
| GITHUB_REPOSITORY_NAME: ${{ github.repository }} | |
| run: | | |
| REF_URL="" | |
| if [ "$FOUND_ARTIFACT" = "true" ]; then | |
| REF_ART_ID=$(echo "$REF_ARTIFACTS_JSON" | jq -r '.[0].id // empty') | |
| REF_RUN_ID=$(echo "$REF_ARTIFACTS_JSON" | jq -r '.[0].workflow_run.id // empty') | |
| if [ -n "$REF_ART_ID" ] && [ -n "$REF_RUN_ID" ]; then | |
| REF_URL="https://github.com/${GITHUB_REPOSITORY_NAME}/actions/runs/${REF_RUN_ID}/artifacts/${REF_ART_ID}" | |
| fi | |
| fi | |
| jq -nc --arg new "$NEW_URL" --arg ref "$REF_URL" '{new: $new, ref: $ref}' \ | |
| > rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}/meta.json | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}.capy | |
| path: | | |
| .rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_${{ matrix.arch }}/ | |
| if-no-files-found: error | |
| eicrecon-dis: | |
| name: eicrecon (DIS, ${{ matrix.beam }}, minQ2=${{ matrix.minq2 }}, ${{ matrix.detector_config }}, ${{ matrix.arch }}) | |
| runs-on: ${{ matrix.runner }} | |
| needs: [eic-manifest, npsim-dis] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| beam: [5x41, 10x100, 18x275] | |
| minq2: [1, 1000] | |
| detector_config: [epic_craterlake] | |
| arch: [amd64, arm64] | |
| include: | |
| - arch: amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| exclude: | |
| - beam: 5x41 | |
| minq2: 1000 | |
| - beam: 10x100 | |
| minq2: 1 | |
| arch: arm64 | |
| - beam: 10x100 | |
| minq2: 1000 | |
| arch: arm64 | |
| - beam: 18x275 | |
| minq2: 1 | |
| arch: arm64 | |
| - beam: 18x275 | |
| minq2: 1000 | |
| arch: arm64 | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4hep.root | |
| - name: Run EICrecon | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| source /opt/detector/epic-main/bin/thisepic.sh | |
| export DETECTOR_CONFIG=${{ matrix.detector_config }} | |
| eicrecon \ | |
| -Ppodio:output_file=rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root \ | |
| sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root | |
| - id: upload_new_artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4eic.root | |
| path: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root | |
| if-no-files-found: error | |
| - name: Download previous artifact | |
| id: download_previous_artifact | |
| uses: dawidd6/action-download-artifact@v21 | |
| with: | |
| branch: ${{ github.base_ref || github.event.merge_group.base_ref || github.ref_name }} | |
| path: ref/ | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.edm4eic.root | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "success" | |
| if_no_artifact_found: warn | |
| - name: Compare to previous artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| mkdir new | |
| ln -sf ../rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root new/ | |
| shopt -s nullglob | |
| capybara bara ref/rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root* new/rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root | |
| mv capybara-reports rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| touch .rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| - name: Write artifact metadata | |
| env: | |
| NEW_URL: ${{ steps.upload_new_artifact.outputs.artifact-url }} | |
| FOUND_ARTIFACT: ${{ steps.download_previous_artifact.outputs.found_artifact }} | |
| REF_ARTIFACTS_JSON: ${{ steps.download_previous_artifact.outputs.artifacts }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| REF_URL="" | |
| if [ "$FOUND_ARTIFACT" = "true" ]; then | |
| REF_ART_ID=$(echo "$REF_ARTIFACTS_JSON" | jq -r '.[0].id // empty') | |
| REF_RUN_ID=$(echo "$REF_ARTIFACTS_JSON" | jq -r '.[0].workflow_run.id // empty') | |
| if [ -n "$REF_ART_ID" ] && [ -n "$REF_RUN_ID" ]; then | |
| REF_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${REF_RUN_ID}/artifacts/${REF_ART_ID}" | |
| fi | |
| fi | |
| jq -nc --arg new "$NEW_URL" --arg ref "$REF_URL" '{new: $new, ref: $ref}' \ | |
| > rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}/meta.json | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}.capy | |
| path: | | |
| .rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }} | |
| rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_${{ matrix.arch }}/ | |
| if-no-files-found: error | |
| npsim-dis-cross-arch: | |
| name: capybara (npsim DIS, ${{ matrix.beam }}, minQ2=${{ matrix.minq2 }}, ${{ matrix.detector_config }}, amd64 vs arm64) | |
| runs-on: ubuntu-latest | |
| needs: [eic-manifest, npsim-dis] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| beam: [5x41] | |
| minq2: [1] | |
| detector_config: [epic_craterlake] | |
| steps: | |
| - name: Download amd64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64.edm4hep.root | |
| path: amd64/ | |
| - name: Download arm64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_arm64.edm4hep.root | |
| path: arm64/ | |
| - name: Compare amd64 vs arm64 artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| capybara bara amd64/sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root arm64/sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.root | |
| mv capybara-reports sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| touch .sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64.capy | |
| path: | | |
| .sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64/ | |
| if-no-files-found: error | |
| eicrecon-dis-cross-arch: | |
| name: capybara (eicrecon DIS, ${{ matrix.beam }}, minQ2=${{ matrix.minq2 }}, ${{ matrix.detector_config }}, amd64 vs arm64) | |
| runs-on: ubuntu-latest | |
| needs: [eic-manifest, eicrecon-dis] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| beam: [5x41] | |
| minq2: [1] | |
| detector_config: [epic_craterlake] | |
| steps: | |
| - name: Download amd64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64.edm4eic.root | |
| path: amd64/ | |
| - name: Download arm64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_arm64.edm4eic.root | |
| path: arm64/ | |
| - name: Compare amd64 vs arm64 artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| capybara bara amd64/rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root arm64/rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4eic.root | |
| mv capybara-reports rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| touch .rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64.capy | |
| path: | | |
| .rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| rec_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}_amd64_vs_arm64/ | |
| if-no-files-found: error | |
| npsim-gun-cross-arch: | |
| name: capybara (npsim gun, ${{ matrix.particle }}, ${{ matrix.detector_config }}, amd64 vs arm64) | |
| runs-on: ubuntu-latest | |
| needs: [eic-manifest, npsim-gun] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| particle: [pi, e] | |
| detector_config: [epic_craterlake] | |
| steps: | |
| - name: Download amd64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64.edm4hep.root | |
| path: amd64/ | |
| - name: Download arm64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_arm64.edm4hep.root | |
| path: arm64/ | |
| - name: Compare amd64 vs arm64 artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| capybara bara amd64/sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root arm64/sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4hep.root | |
| mv capybara-reports sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| touch .sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64.capy | |
| path: | | |
| .sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| sim_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64/ | |
| if-no-files-found: error | |
| eicrecon-gun-cross-arch: | |
| name: capybara (eicrecon gun, ${{ matrix.particle }}, ${{ matrix.detector_config }}, amd64 vs arm64) | |
| runs-on: ubuntu-latest | |
| needs: [eic-manifest, eicrecon-gun] | |
| container: | |
| image: ghcr.io/eic/eic_ci:pipeline-${{ github.run_id }} | |
| credentials: | |
| username: ${{ secrets.GHCR_REGISTRY_USER }} | |
| password: ${{ secrets.GHCR_REGISTRY_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| particle: [pi, e] | |
| detector_config: [epic_craterlake] | |
| steps: | |
| - name: Download amd64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64.edm4eic.root | |
| path: amd64/ | |
| - name: Download arm64 artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_arm64.edm4eic.root | |
| path: arm64/ | |
| - name: Compare amd64 vs arm64 artifacts | |
| shell: bash --login -eo pipefail {0} | |
| run: | | |
| mkdir capybara-reports | |
| capybara bara amd64/rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root arm64/rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}.edm4eic.root | |
| mv capybara-reports rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| touch .rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64.capy | |
| path: | | |
| .rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64 | |
| rec_${{ matrix.particle }}_1GeV_20GeV_${{ matrix.detector_config }}_amd64_vs_arm64/ | |
| if-no-files-found: error | |
| merge-capybara: | |
| name: Merge capybara reports | |
| runs-on: ubuntu-latest | |
| needs: [npsim-gun, npsim-gun-cross-arch, npsim-dis, npsim-dis-cross-arch, eicrecon-gun, eicrecon-gun-cross-arch, eicrecon-dis, eicrecon-dis-cross-arch] | |
| steps: | |
| - uses: actions/upload-artifact/merge@v7 | |
| with: | |
| name: capybara-report | |
| pattern: "*.capy" | |
| delete-merged: true | |
| list-open-prs: | |
| uses: eic/actions/.github/workflows/list-open-prs.yml@main | |
| get-docs-from-open-prs: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - list-open-prs | |
| - merge-capybara | |
| if: always() && !cancelled() | |
| strategy: | |
| matrix: ${{ fromJSON(needs.list-open-prs.outputs.json) }} | |
| fail-fast: false | |
| max-parallel: 4 | |
| steps: | |
| - name: Download capybara artifact (other PRs) | |
| id: download_capybara | |
| uses: dawidd6/action-download-artifact@v21 | |
| if: github.event.pull_request.number != matrix.pr | |
| with: | |
| commit: ${{ matrix.head_sha }} | |
| path: publishing_docs/pr/${{ matrix.pr }}/capybara/ | |
| name: capybara-report | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "completed" | |
| if_no_artifact_found: ignore | |
| - name: Download capybara artifact (this PR) | |
| uses: actions/download-artifact@v8 | |
| if: github.event.pull_request.number == matrix.pr | |
| with: | |
| name: capybara-report | |
| path: publishing_docs/pr/${{ matrix.pr }}/capybara/ | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: github-pages-staging-pr-${{ matrix.pr }} | |
| path: publishing_docs/ | |
| if-no-files-found: ignore | |
| get-docs-from-main: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - merge-capybara | |
| if: always() && !cancelled() | |
| steps: | |
| - name: Download capybara artifact (in PR) | |
| id: download_capybara | |
| uses: dawidd6/action-download-artifact@v21 | |
| if: github.ref_name != 'master' | |
| with: | |
| branch: master | |
| path: publishing_docs/capybara/ | |
| name: capybara-report | |
| workflow: ".github/workflows/build-push.yml" | |
| workflow_conclusion: "completed" | |
| if_no_artifact_found: ignore | |
| - name: Download capybara artifact (on master) | |
| uses: actions/download-artifact@v8 | |
| if: github.ref_name == 'master' | |
| with: | |
| name: capybara-report | |
| path: publishing_docs/capybara/ | |
| - name: Populate capybara summary (on master) | |
| if: github.ref_name == 'master' || steps.download_capybara.outputs.found_artifact == 'true' | |
| run: | | |
| echo "### Capybara summary for master" >> publishing_docs/capybara/index.md | |
| while IFS= read -r dir; do | |
| name=$(basename "$dir") | |
| line="- [${name}](https://eic.github.io/containers/capybara/${name}/index.html)" | |
| if [ -f "${dir}/meta.json" ]; then | |
| new_url=$(jq -r '.new // empty' "${dir}/meta.json" 2>/dev/null || true) | |
| ref_url=$(jq -r '.ref // empty' "${dir}/meta.json" 2>/dev/null || true) | |
| [ -n "$new_url" ] && line="${line} ([new artifact](${new_url}))" | |
| [ -n "$ref_url" ] && line="${line} ([ref artifact](${ref_url}))" | |
| fi | |
| echo "$line" | |
| done < <(find publishing_docs/capybara/ -mindepth 1 -maxdepth 1 -type d | sort) \ | |
| >> publishing_docs/capybara/index.md | |
| - name: Create capybara step summary (on master) | |
| if: github.ref_name == 'master' | |
| run: | | |
| cat publishing_docs/capybara/index.md >> $GITHUB_STEP_SUMMARY | |
| - name: Ensure publishing_docs is non-empty | |
| run: mkdir -p publishing_docs && touch publishing_docs/.keep | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: github-pages-staging-main | |
| path: publishing_docs/ | |
| if-no-files-found: error | |
| include-hidden-files: true | |
| build-artifacts-page: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - get-docs-from-open-prs | |
| - get-docs-from-main | |
| if: always() && !cancelled() && !failure() | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download artifacts for pages | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: artifacts/ | |
| - name: Assemble site | |
| run: | | |
| mkdir -p publishing_docs | |
| cp -r docs/. publishing_docs/ | |
| for dir in artifacts/github-pages-staging-*/; do | |
| [ -d "$dir" ] && cp -r "$dir"/. publishing_docs/ || true | |
| done | |
| - name: Make PR summary page | |
| run: | | |
| mkdir -p publishing_docs/pr | |
| echo "### PRs" >> publishing_docs/pr/index.md | |
| find publishing_docs/pr -mindepth 1 -maxdepth 1 -type d \ | |
| -printf "- [%f](%f/index.md)\n" | sort >> publishing_docs/pr/index.md | |
| - name: List content to publish | |
| run: find publishing_docs/ | |
| - uses: actions/upload-pages-artifact@v5 | |
| with: | |
| path: publishing_docs/ | |
| retention-days: 7 | |
| - name: Populate capybara summary | |
| if: ${{ github.event_name == 'pull_request' }} | |
| run: | | |
| echo "### Capybara summary for PR ${{ github.event.pull_request.number }}" \ | |
| >> capybara_${{ github.event.pull_request.number }}.md | |
| CAPY_DIR="publishing_docs/pr/${{ github.event.pull_request.number }}/capybara" | |
| if [ -d "$CAPY_DIR" ]; then | |
| while IFS= read -r dir; do | |
| name=$(basename "$dir") | |
| line="- [${name}](https://eic.github.io/containers/pr/${{ github.event.pull_request.number }}/capybara/${name}/index.html)" | |
| if [ -f "${dir}/meta.json" ]; then | |
| new_url=$(jq -r '.new // empty' "${dir}/meta.json" 2>/dev/null || true) | |
| ref_url=$(jq -r '.ref // empty' "${dir}/meta.json" 2>/dev/null || true) | |
| [ -n "$new_url" ] && line="${line} ([new artifact](${new_url}))" | |
| [ -n "$ref_url" ] && line="${line} ([ref artifact](${ref_url}))" | |
| fi | |
| echo "$line" | |
| done < <(find "$CAPY_DIR" -mindepth 1 -maxdepth 1 -type d | sort) \ | |
| >> capybara_${{ github.event.pull_request.number }}.md | |
| fi | |
| echo "<sup><sub>Last updated $(TZ=America/New_York date -Iminutes) ${{ github.event.pull_request.head.sha }}</sub></sup>" \ | |
| >> capybara_${{ github.event.pull_request.number }}.md | |
| - name: Create capybara step summary | |
| if: ${{ github.event_name == 'pull_request' }} | |
| run: cat capybara_${{ github.event.pull_request.number }}.md >> $GITHUB_STEP_SUMMARY | |
| - name: Upload capybara summary | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: capybara_${{ github.event.pull_request.number }}.md | |
| path: capybara_${{ github.event.pull_request.number }}.md | |
| deploy-artifacts-page: | |
| needs: | |
| - build-artifacts-page | |
| if: always() && !cancelled() && !failure() | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: false | |
| permissions: | |
| pages: write | |
| id-token: write | |
| pull-requests: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| continue-on-error: true | |
| uses: actions/deploy-pages@v5 | |
| - name: Find capybara comment | |
| if: ${{ github.event_name == 'pull_request' }} | |
| id: find_comment | |
| uses: peter-evans/find-comment@v4 | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| comment-author: 'github-actions[bot]' | |
| body-includes: Capybara summary | |
| - name: Fetch capybara summary | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: capybara_${{ github.event.pull_request.number }}.md | |
| - name: Create or update capybara comment | |
| if: ${{ github.event_name == 'pull_request' }} | |
| uses: peter-evans/create-or-update-comment@v5 | |
| with: | |
| comment-id: ${{ steps.find_comment.outputs.comment-id }} | |
| issue-number: ${{ github.event.pull_request.number }} | |
| body-file: capybara_${{ github.event.pull_request.number }}.md | |
| edit-mode: replace |