Repository navigation
{2026.06}[2026.1] Dependencies of GROMACS 2026.3 #5120
Workflow file for this run
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
| # documentation: https://help.github.com/en/articles/workflow-syntax-for-github-actions | |
| name: Check for missing software installations in software.eessi.io | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read # to fetch code (actions/checkout) | |
| env: | |
| # list below should correspond with table @ https://eessi.io/docs/software_layer/cpu_targets/ | |
| EESSI_CPU_TARGETS: | | |
| 2023.06: | |
| x86_64: | |
| - x86_64/amd/zen2 | |
| - x86_64/amd/zen3 | |
| - x86_64/amd/zen4 | |
| - x86_64/intel/haswell | |
| - x86_64/intel/sapphirerapids | |
| - x86_64/intel/skylake_avx512 | |
| - x86_64/intel/icelake | |
| - x86_64/intel/cascadelake | |
| - x86_64/generic | |
| aarch64: | |
| - aarch64/generic | |
| - aarch64/neoverse_n1 | |
| - aarch64/neoverse_v1 | |
| - aarch64/nvidia/grace | |
| - aarch64/a64fx | |
| 2025.06: | |
| x86_64: | |
| - x86_64/amd/zen2 | |
| - x86_64/amd/zen3 | |
| - x86_64/amd/zen4 | |
| - x86_64/amd/zen5 | |
| - x86_64/intel/haswell | |
| - x86_64/intel/sapphirerapids | |
| - x86_64/intel/skylake_avx512 | |
| - x86_64/intel/icelake | |
| - x86_64/intel/cascadelake | |
| - x86_64/generic | |
| aarch64: | |
| - aarch64/generic | |
| - aarch64/neoverse_n1 | |
| - aarch64/neoverse_v1 | |
| - aarch64/nvidia/grace | |
| - aarch64/a64fx | |
| 2026.06: | |
| x86_64: | |
| - x86_64/amd/zen2 | |
| - x86_64/amd/zen3 | |
| - x86_64/amd/zen4 | |
| - x86_64/amd/zen5 | |
| - x86_64/intel/haswell | |
| - x86_64/intel/sapphirerapids | |
| - x86_64/intel/graniterapids | |
| - x86_64/intel/skylake_avx512 | |
| - x86_64/intel/icelake | |
| - x86_64/intel/cascadelake | |
| - x86_64/generic | |
| aarch64: | |
| - aarch64/generic | |
| - aarch64/neoverse_n1 | |
| - aarch64/neoverse_v1 | |
| - aarch64/nvidia/grace | |
| - aarch64/a64fx | |
| - aarch64/aws/graviton4 | |
| # list below should correspond with table @ https://eessi.io/docs/software_layer/gpu_targets/ | |
| EESSI_ACCELERATOR_TARGETS: | | |
| 2023.06: | |
| # Provide a default set of compute capabilities | |
| default: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| # and then allow for special cases for specific architectures | |
| x86_64/amd/zen2: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| aarch64/a64fx: [] | |
| 2025.06: | |
| default: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| - amd/gfx908 | |
| - amd/gfx90a | |
| - amd/gfx942 | |
| - amd/gfx1030 | |
| - amd/gfx1100 | |
| - amd/gfx1101 | |
| - amd/gfx1200 | |
| - amd/gfx1201 | |
| aarch64/generic: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/neoverse_n1: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/neoverse_v1: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/nvidia/grace: | |
| - nvidia/cc70 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/a64fx: [] | |
| 2026.06: | |
| default: | |
| - nvidia/cc75 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| - amd/gfx908 | |
| - amd/gfx90a | |
| - amd/gfx942 | |
| - amd/gfx1030 | |
| - amd/gfx1100 | |
| - amd/gfx1101 | |
| - amd/gfx1200 | |
| - amd/gfx1201 | |
| aarch64/generic: | |
| - nvidia/cc75 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/neoverse_n1: | |
| - nvidia/cc75 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/neoverse_v1: | |
| - nvidia/cc75 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/nvidia/grace: | |
| - nvidia/cc75 | |
| - nvidia/cc80 | |
| - nvidia/cc90 | |
| - nvidia/cc100 | |
| - nvidia/cc120 | |
| aarch64/a64fx: [] | |
| jobs: | |
| # Checks whether this PR modifies any easystack files and, if so, | |
| # determines which EESSI versions are affected. | |
| # It then stores those versions as a space-separated list in an | |
| # environment variable. | |
| # Finally, it writes that value to GITHUB_OUTPUT using the correct | |
| # heredoc format. | |
| check_EESSI_version_changed_files: | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| EESSI_VERSIONS: ${{ steps.detect.outputs.EESSI_VERSIONS }} | |
| steps: | |
| - name: Check out software-layer repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 # Fetch all history for all branches and tags | |
| - name: Detect EESSI version in modified easystack files | |
| id: detect | |
| run: | | |
| # Fetch base branch explicitly to ensure it's available | |
| git fetch origin ${{ github.base_ref }} | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| changed_files=$(git diff --name-only "${{ github.event.pull_request.base.sha }}...HEAD") | |
| else | |
| changed_files=$(git diff --name-only "${{ github.event.before }}...HEAD") | |
| fi | |
| echo "Files changed: $changed_files" | |
| # Default to not checking missing software for any version | |
| EESSI_VERSIONS="" | |
| # Check for specific versions in the changed easystack files | |
| # The regex pattern matches a prefix, but only returns the part after \K, so that we get only the version | |
| # The sort ensures predictable ordering, and with -u only keeps unique items (neither are probably essential, but both are nice) | |
| # Finally, since the grep returns multiple lines if there are multiple versions that were touched, | |
| # the tr replaces newlines with space, to make this space-separated. | |
| EESSI_VERSIONS=$(printf '%s\n' "$changed_files" \ | |
| | grep -oP 'easystacks/software\.eessi\.io/\K[0-9]+\.[0-9]+' \ | |
| | sort -u \ | |
| | tr '\n' ' ') | |
| echo "PR easystack changes related to EESSI VERSION: $EESSI_VERSIONS" | |
| # Use GITHUB_OUTPUT heredoc correctly | |
| echo "EESSI_VERSIONS<<EOF" >> "$GITHUB_OUTPUT" | |
| echo "$EESSI_VERSIONS" >> "$GITHUB_OUTPUT" | |
| echo "EOF" >> "$GITHUB_OUTPUT" | |
| requires_forced_ci: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-24.04 | |
| needs: check_EESSI_version_changed_files | |
| steps: | |
| - name: Check whether force-ci-checks is required | |
| if: > | |
| needs.check_EESSI_version_changed_files.outputs.EESSI_VERSIONS == '' | |
| && !contains(github.event.pull_request.labels.*.name, 'force-ci-checks') | |
| run: | | |
| echo "::error::No EasyStack changes detected, so missing-installation CI was skipped." | |
| echo "::error::All PRs require missing-installation CI, someone with triage rights needs to add the 'force-ci-checks' label." | |
| exit 1 | |
| - name: Force CI label is present or EasyStack changes detected | |
| if: > | |
| needs.check_EESSI_version_changed_files.outputs.EESSI_VERSIONS != '' | |
| || contains(github.event.pull_request.labels.*.name, 'force-ci-checks') | |
| run: echo "No forced CI required." | |
| check_missing: | |
| if: > | |
| ( | |
| contains(github.event.pull_request.labels.*.name, 'bot:deploy') | |
| || contains(github.event.pull_request.labels.*.name, 'force-ci-checks') | |
| ) | |
| needs: check_EESSI_version_changed_files | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Arm CPU targets (EESSI 2023.06) | |
| - runs_on: ubuntu-24.04-arm | |
| EESSI_VERSION: 2023.06 | |
| # x86_64 CPU targets (EESSI 2023.06) | |
| - runs_on: ubuntu-24.04 | |
| EESSI_VERSION: 2023.06 | |
| # Arm CPU targets (EESSI 2025.06) | |
| - runs_on: ubuntu-24.04-arm | |
| EESSI_VERSION: 2025.06 | |
| # x86_64 CPU targets (EESSI 2025.06) | |
| - runs_on: ubuntu-24.04 | |
| EESSI_VERSION: 2025.06 | |
| # Arm CPU targets (EESSI 2026.06) | |
| - runs_on: ubuntu-24.04-arm | |
| EESSI_VERSION: 2026.06 | |
| # x86_64 CPU targets (EESSI 2026.06) | |
| - runs_on: ubuntu-24.04 | |
| EESSI_VERSION: 2026.06 | |
| runs-on: ${{ matrix.runs_on }} | |
| steps: | |
| - name: Check out software-layer repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 # Fetch all history for all branches and tags | |
| - name: Clone EESSI/software-layer-scripts repository | |
| run: | | |
| git clone https://github.com/EESSI/software-layer-scripts | |
| - name: Show host system info | |
| run: | | |
| echo "/proc/cpuinfo:" | |
| cat /proc/cpuinfo | |
| echo | |
| echo "lscpu:" | |
| lscpu | |
| - name: Mount EESSI CernVM-FS repository | |
| uses: eessi/github-action-eessi@v3 | |
| with: | |
| eessi_stack_version: '${{matrix.EESSI_VERSION}}' | |
| - name: Check for missing installations | |
| if: > | |
| contains(github.event.pull_request.labels.*.name, 'force-ci-checks') | |
| || contains( | |
| needs.check_EESSI_version_changed_files.outputs.EESSI_VERSIONS, | |
| matrix.EESSI_VERSION | |
| ) | |
| run: | | |
| # From this extract the CPUs we need to loop over | |
| cpu_subdirs=$(echo "${EESSI_CPU_TARGETS}" | yq ".\"${EESSI_VERSION}\".\"${EESSI_CPU_FAMILY}\" | .[]") | |
| if [[ -z "${cpu_subdirs}" ]]; then | |
| echo "ERROR: No CPU subdirs resolved for ${EESSI_VERSION} / ${EESSI_CPU_FAMILY}" | |
| exit 1 | |
| fi | |
| cpu_array=($cpu_subdirs) | |
| for ((i=0; i<${#cpu_array[@]}; i+=2)); do | |
| pids=() | |
| labels=() | |
| logs=() | |
| for ((j=i; j<i+2 && j<${#cpu_array[@]}; j++)); do | |
| cpu="${cpu_array[j]}" | |
| safe_cpu="${cpu//\//_}" | |
| log="log_${safe_cpu}.txt" | |
| echo "" | |
| echo "---------------- CPU TARGET ----------------" | |
| echo "$cpu" | |
| echo "-------------------------------------------" | |
| ( | |
| set -e -o pipefail | |
| module --force purge | |
| export EESSI_SOFTWARE_SUBDIR_OVERRIDE="$cpu" | |
| module load EESSI/${{matrix.EESSI_VERSION}} | |
| env | grep ^EESSI | sort | |
| cache_file="${EESSI_SOFTWARE_PATH}/.lmod/cache/spiderT.lua" | |
| if [[ -f "$cache_file" ]]; then | |
| ls -l "$cache_file" | |
| else | |
| echo "ERROR: Lmod cache file is missing for CPU target" | |
| echo "Expected file: $cache_file" | |
| exit 1 | |
| fi | |
| echo "first run check_missing_installations.sh for CPU-only builds" | |
| for easystack_file in $(EESSI_VERSION=${{matrix.EESSI_VERSION}} .github/workflows/scripts/only_latest_easystacks.sh); do | |
| eb_version=$(echo ${easystack_file} | sed 's/.*eb-\([0-9.]*\).*.yml/\1/g') | |
| echo "checking ${easystack_file} with EasyBuild ${eb_version}..." | |
| if [[ "$easystack_file" =~ /(additional_arch|arch_specific)/ ]]; then | |
| if [[ "$easystack_file" != *"/$EESSI_CPU_FAMILY/"* ]]; then | |
| echo "Detected an additional arch or arch-specific easystack with CPU family not matching host ($EESSI_CPU_FAMILY), skipping CI for $easystack_file" | |
| continue | |
| fi | |
| fi | |
| module purge | |
| module load EasyBuild/${eb_version} | |
| which eb | |
| eb --version | |
| software-layer-scripts/check_missing_installations.sh ${easystack_file} | |
| done | |
| echo | |
| echo "now check accelerator builds for ${cpu}" | |
| accelerators=$(echo "${EESSI_ACCELERATOR_TARGETS}" | yq ".\"${{matrix.EESSI_VERSION}}\".\"${cpu}\" // .\"${{matrix.EESSI_VERSION}}\".default | .[]") | |
| if [[ -z "${accelerators}" ]]; then | |
| echo "no accelerator targets defined for ${cpu}" | |
| else | |
| for accel in ${accelerators}; do | |
| module use ${EESSI_SOFTWARE_PATH}/accel/${accel}/modules/all | |
| echo "checking accelerator ${accel}" | |
| for easystack_file in $(EESSI_VERSION=${{matrix.EESSI_VERSION}} ACCEL_EASYSTACKS=1 .github/workflows/scripts/only_latest_easystacks.sh); do | |
| vendor="${accel%%/*}" | |
| if [[ "${easystack_file}" == *"accel/${vendor}"* ]]; then | |
| eb_version=$(echo ${easystack_file} | sed 's/.*eb-\([0-9.]*\).*.yml/\1/g') | |
| module purge | |
| module load EasyBuild/${eb_version} | |
| which eb | |
| eb --version | |
| software-layer-scripts/check_missing_installations.sh ${easystack_file} | |
| else | |
| echo "Skipping ${easystack_file} (vendor mismatch for ${accel})" | |
| fi | |
| done | |
| module unuse ${EESSI_SOFTWARE_PATH}/accel/${accel}/modules/all | |
| done | |
| fi | |
| ) >"$log" 2>&1 & | |
| pids+=($!) | |
| labels+=("$cpu") | |
| logs+=("$log") | |
| done | |
| # wait + report results for this batch of 2 | |
| for ((k=0; k<${#pids[@]}; k++)); do | |
| pid="${pids[k]}" | |
| cpu="${labels[k]}" | |
| log="${logs[k]}" | |
| if ! wait "$pid"; then | |
| echo "========================================" | |
| echo "FAILED CPU TARGET: $cpu" | |
| echo "LOG FILE: $log" | |
| echo "========================================" | |
| cat "$log" | |
| exit 1 | |
| else | |
| echo "SUCCESS: $cpu" | |
| # Show any architectures that were intentionally skipped | |
| grep "Detected an additional arch" "$log" || true | |
| fi | |
| done | |
| done | |
| - name: Test check_missing_installations.sh with missing package (GCC/8.3.0) | |
| run: | | |
| # This is a general check, doesn't need to be run for every CPU, just the host is fine | |
| source /cvmfs/software.eessi.io/versions/${{matrix.EESSI_VERSION}}/init/bash | |
| module load EasyBuild | |
| which eb | |
| eb --version | |
| env | grep ^EESSI | sort | |
| # create dummy easystack file with a single entry (something that is not installed in EESSI) | |
| easystack_file="test.yml" | |
| echo "easyconfigs:" > ${easystack_file} | |
| echo " - GCC-8.3.0:" >> ${easystack_file} | |
| echo "created easystack file '${easystack_file}' with a missing installation (GCC/8.3.0):" | |
| cat ${easystack_file} | |
| # note, check_missing_installations.sh exits 1 if a package was | |
| # missing, which is intepreted as false (exit code based, not | |
| # boolean logic), hence when the script exits 0 if no package was | |
| # missing it is interpreted as true, thus the test did not capture | |
| # the missing package | |
| if software-layer-scripts/check_missing_installations.sh ${easystack_file}; then | |
| echo "did NOT capture missing package; test FAILED" | |
| exit 1 | |
| else | |
| echo "captured missing package; test PASSED" | |
| exit 0 | |
| fi | |
| - name: Compare stacks across architectures | |
| shell: bash | |
| run: | | |
| echo "::group::EESSI ${EESSI_VERSION} / ${EESSI_CPU_FAMILY}" | |
| # Get all CPU targets belonging to this architecture family. | |
| CPU_TARGETS=$(echo "${EESSI_CPU_TARGETS}" \ | |
| | yq -r ".\"${EESSI_VERSION}\".\"${EESSI_CPU_FAMILY}\"[]") | |
| for COMPARISON_ARCH in ${CPU_TARGETS}; do | |
| echo "::group::Compare ${EESSI_VERSION} / ${COMPARISON_ARCH}" | |
| # Use architecture-specific accelerator targets where defined, | |
| # otherwise fall back to the default set. | |
| ALL_ACCELERATOR_TARGETS=$(echo "${EESSI_ACCELERATOR_TARGETS}" \ | |
| | yq ".\"${{ matrix.EESSI_VERSION }}\".\"${COMPARISON_ARCH}\" // .\"${{ matrix.EESSI_VERSION }}\".default | .[]" \ | |
| | tr '\n' ' ') | |
| echo "COMPARISON_ARCH=${COMPARISON_ARCH}" | |
| echo "ACCELERATOR_TARGETS=${ALL_ACCELERATOR_TARGETS}" | |
| for ACCELERATOR_TYPE in nvidia amd; do | |
| ACCELERATOR_TARGETS_TYPE=$(echo "${ALL_ACCELERATOR_TARGETS}" \ | |
| | tr ' ' '\n' \ | |
| | grep "^${ACCELERATOR_TYPE}/" \ | |
| | tr '\n' ' ' || true) | |
| if [[ -z "${ACCELERATOR_TARGETS_TYPE}" ]]; then | |
| continue | |
| fi | |
| export ACCELERATOR_TARGETS="${ACCELERATOR_TARGETS_TYPE}" | |
| echo "Comparing ${ACCELERATOR_TYPE} accelerator targets:" | |
| echo "ACCELERATOR_TARGETS=${ACCELERATOR_TARGETS}" | |
| .github/workflows/scripts/compare_to_generic.sh \ | |
| "${EESSI_PREFIX}/software/${EESSI_OS_TYPE}" \ | |
| "${COMPARISON_ARCH}" | |
| done | |
| echo "::endgroup::" | |
| done |