Repository navigation
PowderN fix potential edge cases #6074
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: mcxtrace-basictest | |
| on: | |
| push: | |
| pull_request: | |
| schedule: | |
| - cron: '55 23 * * 0' # 23:55 every Sunday | |
| workflow_dispatch: | |
| inputs: | |
| manual-debugging: | |
| type: boolean | |
| description: Launch manual debugging tmate for inspection (automatic in case of errors) | |
| default: false | |
| plots: | |
| type: boolean | |
| description: Generate test plots (mctest without --noplots) and run mxviewtest comparison tables | |
| default: false | |
| # Plots and mxviewtest are off by default (push/PR/schedule); request them via | |
| # the "plots" tickbox when running the workflow manually | |
| env: | |
| NOPLOTS: ${{ inputs.plots && '' || '--noplots' }} | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # --- built from source via cmake --- | |
| - { method: source, os: ubuntu-24.04, CC: gcc-13, CXX: g++-13, python: '3.13', mpi: 'openmpi', nmpi: 'auto', cogen: 'classic'} | |
| - { method: source, os: ubuntu-24.04, CC: clang, CXX: clang++, python: '3.13', mpi: 'openmpi', nmpi: 'auto', cogen: 'classic'} | |
| # --- mccode.org-style .deb packages (buildscripts/build_debs_mcxtrace), apt-installed | |
| # in /usr, no $MCXTRACE set - as for users of the mccode.org apt repo --- | |
| - { method: debian, os: ubuntu-24.04, CC: gcc, CXX: g++, python: '3.12', mpi: 'openmpi', nmpi: 'auto', cogen: 'classic'} | |
| # --- built via conda --- | |
| - { method: conda, os: ubuntu-latest, CC: gcc, CXX: g++, python: '3.13', mpi: 'openmpi', nmpi: 'auto', cogen: 'classic'} | |
| # - { method: conda, os: ubuntu-latest, CC: gcc, CXX: g++, python: '3.13', mpi: 'openmpi', nmpi: 'auto', cogen: 'antlr'} | |
| - { method: conda, os: macos-latest, CC: clang, CXX: clang++, python: '3.13', mpi: 'openmpi', nmpi: '2', cogen: 'classic'} | |
| - { method: conda, os: windows-latest, CC: CL, CXX: CL, python: "3.13", mpi: 'msmpi', nmpi: 'auto', cogen: 'classic'} | |
| name: ${{ matrix.os }}.${{ matrix.method }}.${{ matrix.cogen }}.${{ matrix.CC || 'default' }}.${{ matrix.mpi }} | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| CC: ${{ matrix.CC }} | |
| CXX: ${{ matrix.CXX }} | |
| defaults: | |
| run: | |
| shell: bash -el {0} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| path: src | |
| # Full history (rather than the old fetch-depth: 2) is needed so the | |
| # "Check for modified instruments" step below can diff against the | |
| # actual merge-base with main / the pre-push SHA, rather than just | |
| # the single most recent commit - see that step for why. | |
| fetch-depth: 0 | |
| - name: Setup python | |
| uses: actions/setup-python@v6 | |
| if: matrix.method == 'source' | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - name: Setup VS in shell Intel | |
| if: runner.os == 'Windows' && matrix.os != 'windows-11-arm' | |
| uses: egor-tensin/vs-shell@v2 | |
| - name: Setup VS in shell arm64 | |
| if: runner.os == 'Windows' && matrix.os == 'windows-11-arm' | |
| uses: egor-tensin/vs-shell@v2 | |
| with: | |
| arch: arm64 | |
| - name: Setup MPI | |
| uses: mpi4py/setup-mpi@v1 | |
| if: matrix.method == 'source' | |
| with: | |
| mpi: ${{ matrix.mpi }} | |
| - name: Setup (Linux, source build) | |
| id: setup-linux | |
| if: matrix.method == 'source' && runner.os == 'Linux' | |
| run: | | |
| sudo apt -y install libgsl-dev libxrl-dev libnexus-dev | |
| - name: Setup (macOS, source build) | |
| id: setup-macos | |
| if: matrix.method == 'source' && runner.os == 'macOS' | |
| # Temporarily disable xraylib runs on macOS, upstream seems to | |
| # cause build-issues. Will soon port basictest scripts to conda | |
| # for Windows/Linux | |
| run: | | |
| brew install bison flex gfortran gsl | |
| #if [ "${{ matrix.os }}" != "macos-15" ]; | |
| #then | |
| # brew tap tschoonj/tap | |
| # brew install xraylib | |
| #fi | |
| - name: Setup (Windows, source build) | |
| id: setup-Windows | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| shell: bash | |
| run: | | |
| cygpath -sm "$MSMPI_INC" > includepath.txt | |
| cygpath -sm "$MSMPI_LIB64" > libpath.txt | |
| choco install winflexbison3 | |
| choco install wget | |
| if [ "$CC" == "gcc.exe" ]; then choco install mingw; fi | |
| pip install mslex PyYAML ply mcpl mcpl-extra kdsource psutil jinja2 | |
| gcc.exe --version | |
| - name: Setup (Windows Intel, source build) | |
| id: setup-Windows-intel | |
| if: matrix.method == 'source' && runner.os == 'Windows' && matrix.os != 'windows-11-arm' | |
| shell: bash | |
| run: | | |
| pip install McStasscript ncrystal | |
| - name: Setup MPI cygpath... | |
| id: setup-Windows-paths | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| run: | | |
| set /p MPIINCVAR=<includepath.txt | |
| set /p MPILIBVAR=<libpath.txt | |
| echo MPIINCVAR=%MPIINCVAR% >> %GITHUB_ENV% | |
| echo MPILIBVAR=%MPILIBVAR% >> %GITHUB_ENV% | |
| - name: Check versions and set worker label | |
| id: version-checks | |
| run: | | |
| which python3 | |
| python3 --version | |
| which cmake | |
| cmake --version | |
| MYWORKERID=`echo ${RUNNER_TRACKING_ID} | md5sum | cut -c1-12` | |
| echo MYWORKERID=${MYWORKERID} >> "$GITHUB_ENV" | |
| - name: Get conda dependency list | |
| id: conda-deps | |
| if: matrix.method == 'conda' | |
| run: | | |
| ./src/devel/bin/mccode-create-conda-yml -m mcxtrace -n mcxtrace -o dependencies.yml | |
| cat dependencies.yml | |
| - uses: mamba-org/setup-micromamba@v3 | |
| if: matrix.method == 'conda' | |
| with: | |
| environment-name: mcxtrace | |
| environment-file: dependencies.yml | |
| - name: Configure build and install mcxtrace (source) | |
| id: mcxtrace-install | |
| if: ${{ matrix.method == 'source' && matrix.CC != 'CL' }} | |
| run: | | |
| if [ "$RUNNER_OS" == "macOS" ]; then mkdir ${HOME}/tmp; fi | |
| if [ "$RUNNER_OS" == "macOS" ]; then export SDKROOT=$(xcrun --sdk macosx --show-sdk-path); fi | |
| set -e | |
| set -u | |
| set -x | |
| mkdir build_mcxtrace | |
| cd build_mcxtrace | |
| export EXTRA_ARGS_FOR_CMAKE="" | |
| if [ "$RUNNER_OS" == "macOS" ] && [ -f "/opt/homebrew/opt/flex/bin/flex" ]; then export HOMEBRW="/opt/homebrew/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/opt/homebrew/lib -I/opt/homebrew/include"; export XRLFLAGS="-lxrl -L/opt/homebrew/lib -I/opt/homebrew/include"; fi | |
| if [ "$RUNNER_OS" == "macOS" ] && [ -f "/usr/local/opt/flex/bin/flex" ]; then export HOMEBRW="/usr/local/opt"; export GSLFLAGS="-lgsl -lgslcblas -L/usr/local/lib -I/usr/local/include"; export XRLFLAGS="-lxrl -L/usr/local/lib -I/usr/local/include"; fi | |
| if [ "$RUNNER_OS" == "macOS" ]; then export EXTRA_ARGS_FOR_CMAKE="-DBISON_EXECUTABLE=${HOMEBRW}/bison/bin/bison -DFLEX_EXECUTABLE=${HOMEBRW}/flex/bin/flex -DCMAKE_Fortran_COMPILER=${HOMEBRW}/gfortran/bin/gfortran"; fi | |
| if [ "$RUNNER_OS" == "Linux" ]; then export EXTRA_ARGS_FOR_CMAKE="-DNEXUSLIB=/usr/lib -DNEXUSINCLUDE=/usr/include/nexus"; fi | |
| if [ "$RUNNER_OS" == "Windows" ]; then export MPIINC=`cygpath -m -s "${MSMPI_INC}"`; export MPILIB=`cygpath -m -s "${MSMPI_LIB64}"`; export EXTRA_ARGS_FOR_CMAKE="-DMPILIBDIR=${MPILIB} -DMPIINCLUDEDIR=${MPIINC}"; fi | |
| cmake \ | |
| -DCMAKE_INSTALL_PREFIX=../install_mcxtrace \ | |
| -S ../src \ | |
| -G "Unix Makefiles" \ | |
| -DMCVERSION="3.99.99" \ | |
| -DMCCODE_BUILD_CONDA_PKG=OFF \ | |
| -DBUILD_SHARED_LIBS=ON \ | |
| -DCMAKE_INSTALL_LIBDIR=lib \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DBUILD_MCXTRACE=ON \ | |
| -DMCCODE_USE_LEGACY_DESTINATIONS=OFF \ | |
| -DBUILD_TOOLS=ON \ | |
| -DENABLE_COMPONENTS=ON \ | |
| -DENSURE_MCPL=OFF \ | |
| -DENSURE_NCRYSTAL=OFF \ | |
| -DENABLE_CIF2HKL=ON \ | |
| -DENABLE_NEUTRONICS=OFF \ | |
| ${EXTRA_ARGS_FOR_CMAKE} | |
| cmake --build . --config Release | |
| cmake --build . --target install --config Release | |
| export MCXTRACE_EXECUTABLE="mcxtrace" | |
| export MXRUN_EXECUTABLE="mxrun" | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export MCXTRACE_EXECUTABLE="mcxtrace.exe" | |
| export MXRUN_EXECUTABLE="mxrun.bat" | |
| fi | |
| test -f "../install_mcxtrace/bin/${MCXTRACE_EXECUTABLE}" | |
| test -f "../install_mcxtrace/bin/${MXRUN_EXECUTABLE}" | |
| test -f "../install_mcxtrace/share/mcxtrace/tools/Python/mccodelib/__init__.py" | |
| test -d "../install_mcxtrace/share/mcxtrace/resources/data" | |
| if [ "${{ matrix.mpi }}" == "openmpi" ]; then sed -i.bak 's/mpirun/mpirun\ --mca\ btl\ self,vader,tcp/g' ../install_mcxtrace/share/mcxtrace/tools/Python/mccodelib/mccode_config.json ; fi | |
| if [ "$RUNNER_OS" == "macOS" ]; then sed -i.bak "s+-lgsl\ -lgslcblas+${GSLFLAGS}+g" ../install_mcxtrace/share/mcxtrace/tools/Python/mccodelib/mccode_config.json ; fi | |
| if [ "$RUNNER_OS" == "macOS" ]; then sed -i.bak "s+-lxrl+${XRLFLAGS}+g" ../install_mcxtrace/share/mcxtrace/tools/Python/mccodelib/mccode_config.json ; fi | |
| echo ******************************************************************************* | |
| echo Resulting mccode_config.json: | |
| echo ******************************************************************************* | |
| cat ../install_mcxtrace/share/mcxtrace/tools/Python/mccodelib/mccode_config.json | |
| echo ******************************************************************************* | |
| - name: Configure build and install mcxtrace on Windows-MSVC (source) | |
| id: mcxtrace-install-windows-msvc | |
| if: ${{ matrix.method == 'source' && matrix.CC != 'gcc.exe' && runner.os == 'Windows' }} | |
| shell: cmd | |
| run: > | |
| cmake -B build -S src | |
| "-DCMAKE_INSTALL_PREFIX=./install_mcxtrace" | |
| -DMCVERSION="3.99.99" | |
| -DMCCODE_BUILD_CONDA_PKG=OFF | |
| -DMCCODE_CONFIG_MCPL2=ON | |
| -DCMAKE_INSTALL_LIBDIR=lib | |
| -DBUILD_MCXTRACE=ON | |
| -DMCCODE_USE_LEGACY_DESTINATIONS=OFF | |
| -DBUILD_TOOLS=ON | |
| -DENABLE_COMPONENTS=ON | |
| -DENABLE_CIF2HKL=OFF | |
| -DENABLE_NEUTRONICS=OFF | |
| -DMPIINCLUDEDIR=%MPIINCVAR% | |
| -DMPILIBDIR=%MPILIBVAR% | |
| - name: CMake build (source, Windows-MSVC) | |
| if: ${{ matrix.method == 'source' && matrix.CC != 'gcc.exe' && runner.os == 'Windows' }} | |
| shell: cmd | |
| run: cmake --build build --config Release -j 2 | |
| - name: CMake install (source, Windows-MSVC) | |
| if: ${{ matrix.method == 'source' && matrix.CC != 'gcc.exe' && runner.os == 'Windows' }} | |
| run: cmake --install build --config Release | |
| - name: set MCXTRACE env var (source, Windows) | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| run: echo MCXTRACE=%CD%\install_mcxtrace\share\mcxtrace\resources >> %GITHUB_ENV% | |
| - name: check MCXTRACE env var (source, Windows) | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| run: echo %MCXTRACE% | |
| - name: Various Windows debugging - McXtrace (source) | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| shell: cmd | |
| run: | | |
| type .\install_mcxtrace\share\mcxtrace\tools\Python\mccodelib\mccode_config.json | |
| .\install_mcxtrace\bin\mxrun -h | |
| .\install_mcxtrace\bin\mcxtrace -v | |
| if [ "${{ matrix.CC }}" != "CL" ]; | |
| then | |
| mcpl-config -s | |
| fi | |
| - name: Various Windows debugging - MCPL (source) | |
| if: matrix.method == 'source' && runner.os == 'Windows' | |
| run: | | |
| mcpl-config -s | |
| - name: Pip install Unix (source) | |
| id: pip-install | |
| if: matrix.method == 'source' && runner.os != 'Windows' | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| if [ "$RUNNER_OS" == "macOS" ]; | |
| then | |
| python3 -mpip install PyYAML pyaml ply McStasScript mcpl mcpl-extra kdsource jinja2 psutil --break-system-packages | |
| fi | |
| if [ "$RUNNER_OS" == "Linux" ]; | |
| then | |
| python3 -mpip install PyYAML ply McStasscript mcpl mcpl-extra kdsource jinja2 psutil | |
| fi | |
| - name: Configure build and install mcxtrace (conda) | |
| id: mcxtrace-install-conda | |
| if: matrix.method == 'conda' | |
| run: | | |
| ./src/devel/bin/mccode-build-conda -m mcxtrace -s $PWD/src -b $PWD/build_mcxtrace | |
| - name: Setup mcxtrace-antlr | |
| id: setup-mcxtrace-antlr | |
| if: matrix.cogen == 'antlr' | |
| continue-on-error: true | |
| run: | | |
| # Cache checkout src/ with mccode-antlr | |
| if [ "${{ matrix.cogen }}" == "antlr" ]; | |
| then | |
| # Set up config file to use mcxtrace-antlr | |
| MCCODE_CONFIG=`mxrun --write-user-config | cut -f4 -d\ ` | |
| sed -i.bak s+\"MCCOGEN\"\:\ \"mcxtrace\",+\"MCCOGEN\"\:\ \"mcxtrace-antlr\ -I\$\{CONDA_PREFIX\}/share/mcxtrace/resources\",+g ${MCCODE_CONFIG} | |
| grep -H COGEN ${MCCODE_CONFIG} | |
| MCCODEANTLR_FLAGS__NEXUS=`grep NEXUSFLAGS ${MCCODE_CONFIG} |cut -f4 -d\"` | |
| echo "MCCODEANTLR_FLAGS__NEXUS=${MCCODEANTLR_FLAGS__NEXUS}" >> "$GITHUB_ENV" | |
| # Pre-poulate mccode-antlr cache | |
| mccode-antlr cache populate --from-path src/ --flavor mcxtrace --no-strict --check-hashes | |
| fi | |
| - name: Validate build output (conda) | |
| id: build-validation | |
| if: always() && matrix.method == 'conda' | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| echo "Validating Windows build output..." | |
| echo "CONDA_PREFIX: $CONDA_PREFIX" | |
| echo "Checking for mcxtrace executable..." | |
| test -f ${CONDA_PREFIX}/bin/mcxtrace || test -f ${CONDA_PREFIX}/bin/mcxtrace.bat || { echo "ERROR: mcxtrace not found"; exit 1; } | |
| echo "Checking for mxtest executable..." | |
| test -f ${CONDA_PREFIX}/bin/mxtest.bat || { echo "ERROR: mxtest.bat not found"; ls -la ${CONDA_PREFIX}/bin/ | grep -i mxtest || echo "No mxtest found"; exit 1; } | |
| else | |
| echo "Validating Unix build output..." | |
| test -f ${CONDA_PREFIX}/bin/mcxtrace || { echo "ERROR: mcxtrace not found"; exit 1; } | |
| test -f ${CONDA_PREFIX}/bin/mxtest || { echo "ERROR: mxtest not found"; exit 1; } | |
| fi | |
| - name: Post install openmpi hacks macOS (conda) | |
| id: post-install-openmpi-hacks-macOS | |
| if: matrix.method == 'conda' && runner.os == 'macOS' | |
| run: | | |
| if [ "${{ matrix.mpi }}" == "openmpi" ]; then | |
| sed -i.bak 's+mpirun+mpirun\ -mca\ regx\ naive\ --verbose\ --mca\ btl_tcp_if_include\ lo0+g' ${CONDA_PREFIX}/share/mcxtrace/tools/Python/mccodelib/mccode_config.json | |
| fi | |
| - name: Build and install mccode.org-style .deb packages (debian) | |
| id: mcxtrace-install-debian | |
| if: matrix.method == 'debian' | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| sudo apt-get update | |
| # Build dependencies, as in dependency-scripts/getdeps_debian (minus LaTeX/equivs: | |
| # the manuals package and the suite metapackage are not needed for testing) | |
| sudo apt-get -y install git cmake gcc g++ gfortran flex bison build-essential rsync libopenmpi-dev openmpi-bin | |
| cd src | |
| ./buildscripts/build_debs_mcxtrace 3.99.99 | |
| ls -l dist | |
| # Install everything that was built, except the manuals package. apt resolves the | |
| # runtime dependencies declared by the packages themselves (python3-*, libxrl-dev, ...) | |
| sudo apt-get -y install $(ls $PWD/dist/*.deb | grep -v -- '-manuals') | |
| # Same openmpi transport settings as for the source builds | |
| sudo sed -i.bak 's/"mpirun/"mpirun --mca btl self,vader,tcp/g' /usr/share/mcxtrace/tools/Python/mccodelib/mccode_config.json | |
| test -x /usr/bin/mcxtrace | |
| test -x /usr/bin/mxtest | |
| test -d /usr/share/mcxtrace/resources/data | |
| # The point of this leg: resources must be found without the environment variable | |
| test -z "${MCXTRACE:-}" | |
| - name: Normalize PATH to installed McXtrace tools | |
| id: normalize-path | |
| run: | | |
| # For source builds, put the freshly-installed bin/ on PATH so the | |
| # shared test steps below can invoke bare `mcxtrace`/`mxtest`/etc, | |
| # exactly like the conda builds already can (conda's own | |
| # environment activation, via `shell: bash -el`, already puts | |
| # $CONDA_PREFIX/bin on PATH every step - nothing extra needed there). | |
| if [ "${{ matrix.method }}" == "source" ]; then | |
| echo "$PWD/install_mcxtrace/bin" >> "$GITHUB_PATH" | |
| fi | |
| # If compiler is clang, set up mpicc to use clang | |
| if [ "${{ matrix.CC }}" == "clang" ]; then | |
| echo "OMPI_CC=clang" >> "$GITHUB_ENV" | |
| echo "OMPI_CXX=clang++" >> "$GITHUB_ENV" | |
| fi | |
| # Start of tests (shared across all 5 matrix legs) | |
| - name: Launch RNG test instrument | |
| id: RNG-test | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| export MD5SUM="md5sum" | |
| if [ "$RUNNER_OS" == "macOS" ]; | |
| then | |
| export MD5SUM="md5" | |
| fi | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export SUFFIX=".bat" | |
| export EXESUFFIX=".exe" | |
| else | |
| export SUFFIX="" | |
| export EXESUFFIX="" | |
| fi | |
| test -n "$(command -v mcxtrace${EXESUFFIX})" | |
| mcxtrace${EXESUFFIX} --version | |
| mxtest${SUFFIX} --verbose ${NOPLOTS} --instr=Test_RNG_rand01 --testdir=run_rngtest --suffix=${{ matrix.cogen }}_${{ matrix.method }} --uid=${MYWORKERID} | |
| export SUM=`find run_rngtest -name rngout.dat | xargs -n1 grep -v \# | ${MD5SUM} | cut -f1 -d\ ` | |
| export EXPECTED="f192ce4609e2225bf9d42ce9c5fa5a86" | |
| if [ "${EXPECTED}" == "${SUM}" ]; | |
| then | |
| echo RNG test success! | |
| true | |
| else | |
| echo RNG test failure! | |
| false | |
| fi | |
| - name: Launch Basic tests | |
| id: basictests | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export SUFFIX=".bat" | |
| export EXESUFFIX=".exe" | |
| else | |
| export SUFFIX="" | |
| export EXESUFFIX="" | |
| fi | |
| test -n "$(command -v mcxtrace${EXESUFFIX})" | |
| mcxtrace${EXESUFFIX} --version | |
| if [ "${{ matrix.nmpi }}" != "0" ]; | |
| then | |
| mxtest${SUFFIX} --verbose ${NOPLOTS} --mpi=${{ matrix.nmpi }} --instr=JJ_SAXS,ESRF_BM29,Test_MCPL_input,Test_MCPL_output,Test_Absorption --testdir=run_basictests --suffix=${{ matrix.cogen }}_${{ matrix.method }}_${{ matrix.CC || 'default' }}_${{ matrix.mpi }} --uid=${MYWORKERID} | |
| fi | |
| - name: Direct binary run without $MCXTRACE (compiled-in resource dir, issue #2759) | |
| id: direct-binary-resourcedir | |
| # Re-uses the Test_Absorption binary built by the basic tests above. Running it | |
| # directly (not via mxrun, which always exports $MCXTRACE), with $MCXTRACE | |
| # removed and from an unrelated folder, so its material file (data/Mn.txt) can only be | |
| # found via the resource dir baked into the binary by the code generator - | |
| # the situation on mccode.org-style .deb installs, where $MCXTRACE is unset. | |
| # classic only: the antlr code generator embeds a released runtime | |
| if: matrix.cogen == 'classic' && matrix.nmpi != '0' | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| EXE=$(ls run_basictests/*/Test_Absorption/Test_Absorption.out run_basictests/*/Test_Absorption/Test_Absorption.exe 2>/dev/null | head -1 || true) | |
| test -n "$EXE" || { echo "No Test_Absorption binary found below run_basictests"; exit 1; } | |
| EXE="$(cd "$(dirname "$EXE")" && pwd)/$(basename "$EXE")" | |
| # Unrelated folder in the workspace (mktemp -d is not usable on the Windows | |
| # runners: the conda/Git-bash /tmp mappings disagree) | |
| mkdir -p direct_binary_run | |
| cd direct_binary_run | |
| RC=0 | |
| env -u MCXTRACE "$EXE" --yes -n 1000 -d direct_run > direct_run.log 2>&1 || RC=$? | |
| cat direct_run.log | |
| test "$RC" == "0" || { echo "Test_Absorption binary failed (exit code $RC) without \$MCXTRACE"; exit 1; } | |
| if grep -qi "could not" direct_run.log; then | |
| echo "Test_Absorption binary could not locate installed resources without \$MCXTRACE" | |
| exit 1 | |
| fi | |
| # Positive check: the file was really picked up from the installed resources | |
| grep -E "Opening input file '.*resources.*Mn\.txt'" direct_run.log | |
| - name: MPI event-list output regression test | |
| id: mpilisttest | |
| # classic only: the antlr code generator embeds a released runtime | |
| if: matrix.cogen == 'classic' && matrix.nmpi != '0' | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export SUFFIX=".bat" | |
| else | |
| export SUFFIX="" | |
| fi | |
| PY=$(command -v python3 || command -v python) | |
| # h5py is needed to check NeXus output; NeXus is skipped (and reported) without it | |
| ${PY} -m pip install h5py || ${PY} -m pip install h5py --break-system-packages || true | |
| ${PY} src/mcxtrace-comps/examples/Tests/Test_Monitor_nD_list_MPI/test_mpi_lists.py --np 2 --mcrun mxrun${SUFFIX} --workdir run_mpilists | |
| - name: Check for modified instruments | |
| id: instr-test | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| export MXTEST_EXECUTABLE="mxtest" | |
| export MXVIEWTEST_EXECUTABLE="mxviewtest" | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export MXTEST_EXECUTABLE="mxtest.bat" | |
| export MXVIEWTEST_EXECUTABLE="mxviewtest.bat" | |
| fi | |
| export PERMISSIVE=" " | |
| # Determine which base commit to diff against, robustly - this | |
| # replaces the old `git diff --name-only HEAD HEAD~1`, which only | |
| # ever considers the single most recent commit. That silently | |
| # misses changes whenever a PR or push contains more than one | |
| # commit (verified: a 3-commit PR touching 3 different files was | |
| # only detected as a 1-file change under the old logic). | |
| # | |
| # - pull_request / pushes to non-main branches: diff against the | |
| # merge-base with origin/main, so every commit since branching | |
| # off main is considered, however many there are and regardless | |
| # of rebases/force-pushes on the branch itself. | |
| # - direct pushes to main: origin/main already includes this very | |
| # push by the time we fetch it, so merge-base against it would | |
| # wrongly show zero changes. Diff against the pre-push SHA | |
| # (github.event.before) instead, so a multi-commit push to main | |
| # still gets its full set of changes considered. | |
| cd src | |
| git fetch origin main --quiet || true | |
| if [ "${{ github.ref }}" == "refs/heads/main" ] && [ "${{ github.event_name }}" == "push" ]; then | |
| export DIFFBASE="${{ github.event.before }}" | |
| if [ -z "$DIFFBASE" ] || [ "$DIFFBASE" == "0000000000000000000000000000000000000000" ]; then | |
| export DIFFBASE=$(git rev-parse HEAD~1) | |
| fi | |
| else | |
| export DIFFBASE=$(git merge-base origin/main HEAD) | |
| fi | |
| echo "Diffing against: $DIFFBASE" | |
| PY=$(command -v python3 || command -v python) | |
| # Changed components and instruments, in one pass (doc-header-only and | |
| # whitespace-only edits are skipped, see devel/bin/mccode-git-diff-code) | |
| CHANGED=$(${PY} devel/bin/mccode-git-diff-code $DIFFBASE HEAD | grep -E '^mcxtrace-comps/.*\.(comp|instr)$' || true) | |
| CHANGEDCOMPS=$(echo "$CHANGED" | grep '\.comp$' | sed -e 's#.*/##' -e 's#\.comp$##' | sort -u | tr '\n' ',' | sed 's/,$//' || true) | |
| CHANGEDINSTR=$(echo "$CHANGED" | grep '\.instr$' | sed -e 's#.*/##' -e 's#\.instr$##' | sort -u | tr '\n' ',' | sed 's/,$//' || true) | |
| cd - | |
| echo ---- | |
| echo "Changed components: ${CHANGEDCOMPS:-none}" | |
| echo "Changed instruments: ${CHANGEDINSTR:-none}" | |
| echo ---- | |
| # Single mctest run: --instr and --comp together select instruments | |
| # matching either (changed instruments + users of changed components) | |
| SCOPE="" | |
| if [ -n "$CHANGEDINSTR" ]; then SCOPE="--instr=$CHANGEDINSTR"; fi | |
| if [ -n "$CHANGEDCOMPS" ]; then SCOPE="$SCOPE --comp=$CHANGEDCOMPS"; fi | |
| if [ "${#SCOPE}" -gt "6000" ]; then | |
| # Keep within the Windows .bat command-line limit: test everything | |
| echo "Very many changes - testing all instruments" | |
| SCOPE=" " | |
| fi | |
| if [ -n "$SCOPE" ]; then | |
| mkdir -p run_mxtest && cd run_mxtest | |
| ${MXTEST_EXECUTABLE} --verbose ${NOPLOTS} --mpi=${{ matrix.nmpi }} --testdir $PWD $SCOPE --suffix=CHANGES_${{ matrix.cogen }}_${{ matrix.method }}_${{ matrix.CC || 'default' }}_${{ matrix.mpi }} $PERMISSIVE --uid=${MYWORKERID} || { echo "${MXTEST_EXECUTABLE} failed with exit code $?"; exit 1; } | |
| if [ -z "${NOPLOTS}" ]; then ${MXVIEWTEST_EXECUTABLE} --nobrowse $PWD; fi | |
| else | |
| echo "No component or instrument code changes - nothing to test" | |
| fi | |
| - name: 'Tar output files' | |
| id: tar-package | |
| if: always() | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| # Clear out binaries from sim dir and tar up artifact | |
| ls | grep run_ | xargs -n1 ./src/devel/bin/mccode-simdir-cleanfiles -d | |
| tar cvfz mcxtrace-${{ matrix.cogen }}.${{ matrix.method }}.${{ matrix.os }}.${{ matrix.CC }}.${{ matrix.mpi }}.python-${{ matrix.python }}_output.tgz run_* | |
| - name: 'Upload Artifact' | |
| id: tar-upload | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: mcxtrace-artefacts-${{ matrix.cogen }}.${{ matrix.method }}.${{ matrix.os }}.${{ matrix.CC }}.${{ matrix.mpi }}.python-${{ matrix.python }} | |
| path: "mcxtrace-${{ matrix.cogen }}.${{ matrix.method }}.${{ matrix.os }}.${{ matrix.CC }}.${{ matrix.mpi }}.python-${{ matrix.python }}_output.tgz" | |
| - name: Setup tmate session for manual debugging | |
| uses: mxschmitt/action-tmate@v3 | |
| if: always() && (inputs.manual-debugging == true) | |
| with: | |
| limit-access-to-actor: true | |
| compare: | |
| name: mcxtrace-basictest-comparison | |
| needs: build | |
| # Only when plots are requested (manual runs with the "plots" tickbox) | |
| if: always() && inputs.plots | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| shell: bash -el {0} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| path: src | |
| - name: Get conda dependency list | |
| id: conda-deps | |
| run: | | |
| ./src/devel/bin/mccode-create-conda-yml -m mcxtrace -n mcxtrace -o dependencies.yml | |
| - uses: mamba-org/setup-micromamba@v3 | |
| with: | |
| environment-name: mcxtrace | |
| environment-file: dependencies.yml | |
| - name: Configure build and install mcxtrace | |
| id: mcxtrace-install | |
| run: | | |
| # Only the Python tooling (mxviewtest, mxplotdiff-html, mxplot-html) is | |
| # actually needed here - the diff/report generation is platform-agnostic | |
| # regardless of which OS originally produced the monitor data - but we | |
| # reuse the exact same install path as the build job for consistency, | |
| # rather than maintaining a second, lighter-weight install mechanism. | |
| ./src/devel/bin/mccode-build-conda -m mcxtrace -s $PWD/src -b $PWD/build_mcxtrace | |
| - name: 'Download all platform test artifacts' | |
| id: download | |
| uses: actions/download-artifact@v6 | |
| with: | |
| pattern: mcxtrace-artefacts-* | |
| path: downloaded_artifacts | |
| - name: 'Merge changed-instrument columns into one shared testdir' | |
| id: merge | |
| # Plain (non-login) shell here deliberately: this step is pure | |
| # tar/mv/mkdir, no conda activation needed, and a login shell's | |
| # ~/.bash_logout (standard on Debian/Ubuntu images) runs | |
| # `clear_console -q` on exit, which can fail in a non-interactive | |
| # runner and override our own explicit `exit 0`/`exit 1` below, | |
| # making a successful "nothing changed" run report as a failure. | |
| shell: bash {0} | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| mkdir basictests | |
| REFLABEL="" | |
| FOUND_ANY="0" | |
| for tgz in downloaded_artifacts/*/*.tgz; do | |
| work=$(mktemp -d) | |
| tar xzf "$tgz" -C "$work" | |
| FOUND_ANY="1" | |
| artifact_name=$(basename "$(dirname "$tgz")") | |
| if [ -d "$work"/run_mxtest/ ]; then | |
| mkdir -p changes | |
| for labeldir in "$work"/run_mxtest/*/; do | |
| if [[ "$artifact_name" == *"ubuntu-latest"* ]]; then | |
| REFLABEL=$(basename "$labeldir") | |
| fi | |
| mv $labeldir changes/ | |
| done | |
| fi | |
| for labeldir in "$work"/run_basictests/*/; do | |
| mv $labeldir basictests/ | |
| done | |
| rm -rf "$work" | |
| done | |
| echo "FOUND_ANY=$FOUND_ANY" >> "$GITHUB_ENV" | |
| if [ "$FOUND_ANY" == "0" ]; then | |
| echo "No instrument/component changes detected on any platform" | |
| fi | |
| if [ -z "$REFLABEL" ]; then | |
| echo "WARNING: could not identify the ubuntu-latest/conda reference column" | |
| else | |
| echo "REFLABEL=$REFLABEL" >> "$GITHUB_ENV" | |
| echo "Reference column: $REFLABEL" | |
| fi | |
| - name: 'Run mxviewtest across all platform columns' | |
| id: viewtest | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| if [ -d changes/ ]; then | |
| cd changes | |
| if [ -z "$REFLABEL" ]; then | |
| mxviewtest --reflabel "$REFLABEL" --nobrowse | |
| else | |
| mxviewtest --nobrowse | |
| fi | |
| cd - | |
| fi | |
| if [ -d basictests/ ]; then | |
| cd basictests && mxviewtest --nobrowse && ls -l $PWD && cd - | |
| fi | |
| - name: 'Tar output (all platform folders + comparison tables)' | |
| id: tar-package | |
| run: | | |
| if [ -d changes/ ]; then | |
| tar cvfz mcxtrace-basictest-comparison.tgz changes basictests | |
| else | |
| tar cvfz mcxtrace-basictest-comparison.tgz basictests | |
| fi | |
| - name: 'Upload comparison artifact' | |
| id: comparison-upload | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: mcxtrace-basictest-comparison | |
| path: mcxtrace-basictest-comparison.tgz | |
| - name: Setup tmate session for manual debugging | |
| uses: mxschmitt/action-tmate@v3 | |
| if: always() && (inputs.manual-debugging == true) | |
| with: | |
| limit-access-to-actor: true |