Repository navigation
mcstas-conda-testsuite #426
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: mcstas-conda-testsuite | |
| on: | |
| schedule: | |
| - cron: '00 02 * * *' # 02:00 every day | |
| workflow_dispatch: | |
| inputs: | |
| manual-debugging: | |
| type: boolean | |
| description: Launch manual debugging tmate for inspection (automatic in case of errors) | |
| default: false | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: ubuntu-latest, mpi: 'openmpi', nmpi: 'auto', cogen: 'classic', method: 'conda' } | |
| - { os: ubuntu-latest, mpi: 'openmpi', nmpi: 'auto', cogen: 'antlr', method: 'conda' } | |
| - { os: macos-latest, mpi: 'openmpi', nmpi: '2', cogen: 'classic', method: 'conda' } | |
| - { os: windows-latest, mpi: 'msmpi', nmpi: 'auto', cogen: 'classic', method: 'conda' } | |
| # mccode.org-style .deb packages from buildscripts/build_debs_mcstas, installed | |
| # in /usr with no $MCSTAS set (as for users of the mccode.org apt repo) | |
| - { os: ubuntu-24.04, mpi: 'openmpi', nmpi: 'auto', cogen: 'classic', method: 'debian' } | |
| name: ${{ matrix.os }}.${{ matrix.mpi }}.${{ matrix.cogen }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite | |
| runs-on: ${{ matrix.os }} | |
| defaults: | |
| run: | |
| shell: bash -el {0} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| path: src | |
| - name: Setup VS in shell Intel | |
| if: runner.os == 'Windows' | |
| uses: egor-tensin/vs-shell@v2 | |
| - name: Get conda dependency list | |
| id: conda-deps | |
| if: matrix.method == 'conda' | |
| run: | | |
| ./src/devel/bin/mccode-create-conda-yml -m mcstas -n mcstas -o dependencies.yml | |
| cat dependencies.yml | |
| - uses: mamba-org/setup-micromamba@v3 | |
| if: matrix.method == 'conda' | |
| with: | |
| environment-name: mcstas | |
| environment-file: dependencies.yml | |
| - 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: Configure build and install mcstas | |
| id: mcstas-install | |
| if: matrix.method == 'conda' | |
| run: | | |
| ./src/devel/bin/mccode-build-conda -m mcstas -s $PWD/src -b $PWD/build_mcstas | |
| - name: Build and install mccode.org-style .deb packages (debian) | |
| id: mcstas-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 python3-venv | |
| cd src | |
| ./buildscripts/build_debs_mcstas 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') | |
| # KDSource is not packaged for Debian, pip is the only route (as for Debian users). | |
| # Install it into its own venv, so its pip dependencies (numpy, scipy, mcpl-core, ...) | |
| # do not shadow the apt-installed ones, and expose only kdsource-config (used for | |
| # KDSOURCEFLAGS) on PATH. libkdsource then resolves libmcpl from the mcpl .deb. | |
| sudo python3 -m venv /opt/kdsource | |
| sudo /opt/kdsource/bin/python -m pip install kdsource | |
| sudo ln -sf /opt/kdsource/bin/kdsource-config /usr/local/bin/kdsource-config | |
| kdsource-config --show buildflags | |
| which -a mcpl-config | |
| # Same openmpi transport settings as in the basictest source builds | |
| sudo sed -i.bak 's/"mpirun/"mpirun --mca btl self,vader,tcp/g' /usr/share/mcstas/tools/Python/mccodelib/mccode_config.json | |
| test -x /usr/bin/mcstas | |
| test -x /usr/bin/mctest | |
| test -d /usr/share/mcstas/resources/data | |
| - name: Setup mcstas-antlr | |
| id: setup-mcstas-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 mcstas-antlr | |
| MCCODE_CONFIG=`mcrun --write-user-config | cut -f4 -d\ ` | |
| sed -i.bak s+\"MCCOGEN\"\:\ \"mcstas\",+\"MCCOGEN\"\:\ \"mcstas-antlr\ -I\$\{CONDA_PREFIX\}/share/mcstas/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 mcstas --no-strict --check-hashes | |
| fi | |
| - name: Validate build output | |
| 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 mcstas executable..." | |
| test -f ${CONDA_PREFIX}/bin/mcstas || test -f ${CONDA_PREFIX}/bin/mcstas.bat || { echo "ERROR: mcstas not found"; exit 1; } | |
| echo "Checking for mctest executable..." | |
| test -f ${CONDA_PREFIX}/bin/mctest.bat || { echo "ERROR: mctest.bat not found"; ls -la ${CONDA_PREFIX}/bin/ | grep -i mctest || echo "No mctest found"; exit 1; } | |
| else | |
| echo "Validating Unix build output..." | |
| test -f ${CONDA_PREFIX}/bin/mcstas || { echo "ERROR: mcstas not found"; exit 1; } | |
| test -f ${CONDA_PREFIX}/bin/mctest || { echo "ERROR: mctest not found"; exit 1; } | |
| fi | |
| - name: Post install openmpi hacks macOS | |
| id: post-install-openmpi-hacks-macOS | |
| if: 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/mcstas/tools/Python/mccodelib/mccode_config.json | |
| fi | |
| - name: Test suite, up to 2-core MPI | |
| id: test-suite | |
| run: | | |
| # Create and cd to directory for test output data | |
| mkdir run_test-suite && cd run_test-suite | |
| # Test script name | |
| export MCTEST_EXECUTABLE="mctest" | |
| if [ "$RUNNER_OS" == "Windows" ]; | |
| then | |
| export MCTEST_EXECUTABLE="mctest.bat" | |
| fi | |
| # Workaround for warning about "too long" tmpdir name on macOS/openmpi | |
| if [ "$RUNNER_OS" == "macOS" ]; | |
| then | |
| mkdir ${HOME}/tmp | |
| export TMPDIR=${HOME}/tmp | |
| fi | |
| if [ "${{ matrix.method }}" == "debian" ]; | |
| then | |
| # Use the system python3 the .deb tools are installed for, and make | |
| # sure the resource dir is NOT given via the environment | |
| export PATH=/usr/bin:$PATH | |
| unset MCSTAS | |
| test "$(command -v mctest)" == "/usr/bin/mctest" | |
| fi | |
| # Run the test with 2 core mpi | |
| ${MCTEST_EXECUTABLE} --verbose --nsigma 5 --testdir $PWD --suffix ${{ matrix.cogen }}_${{ matrix.os }}_${{ matrix.mpi }}${{ matrix.method == 'debian' && '_debian' || '' }} --mpi=${{ matrix.nmpi }} --uid=${MYWORKERID} | |
| - 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 mcstas-${{ matrix.cogen }}.${{ matrix.os }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite_output.tgz run_test-suite | |
| - name: 'Upload Artifact' | |
| id: tar-upload | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: mcstas-artefacts-${{ matrix.os }}.${{ matrix.cogen }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite | |
| path: "mcstas-${{ matrix.cogen }}.${{ matrix.os }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite_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: mcstas-conda-testsuite-comparison | |
| needs: build | |
| if: always() | |
| 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 mcstas -n mcstas -o dependencies.yml | |
| - uses: mamba-org/setup-micromamba@v3 | |
| with: | |
| environment-name: mcstas | |
| environment-file: dependencies.yml | |
| - name: Configure build and install mcstas | |
| id: mcstas-install | |
| run: | | |
| # Only the Python tooling (mcviewtest, mcplotdiff-html, mcplot-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 mcstas -s $PWD/src -b $PWD/build_mcstas | |
| - name: 'Download all platform test artifacts' | |
| id: download | |
| uses: actions/download-artifact@v6 | |
| with: | |
| # matches mcstas-artefacts-ubuntu-latest.openmpi.conda-testsuite, | |
| # mcstas-artefacts-macos-latest.openmpi.conda-testsuite, | |
| # mcstas-artefacts-windows-latest.msmpi.conda-testsuite - by pattern | |
| # rather than hardcoded names, so this keeps working if the build | |
| # matrix gains/loses a platform | |
| pattern: mcstas-artefacts-*.conda-testsuite | |
| path: downloaded_artifacts | |
| - name: 'Merge platform columns into one shared testdir' | |
| id: merge | |
| run: | | |
| set -e | |
| set -u | |
| set -x | |
| mkdir mcstas-nightly | |
| REFLABEL="" | |
| # Each platform's tarball contains exactly one label directory | |
| # directly under run_test-suite/ (e.g. | |
| # mcstas-3.99.99_mpi_x_2_ubuntu-latest_openmpi_<ncount>_Linux_<datetime>). | |
| # mcviewtest treats each such directory as one comparison "column", | |
| # so merging them as siblings under one shared testdir is all that's | |
| # needed to make them comparable. | |
| for tgz in downloaded_artifacts/*/*.tgz; do | |
| work=$(mktemp -d) | |
| tar xzf "$tgz" -C "$work" | |
| artifact_name=$(basename "$(dirname "$tgz")") | |
| for labeldir in "$work"/run_test-suite/*/; do | |
| if [[ "$artifact_name" == *"ubuntu-latest"* ]]; then | |
| REFLABEL=$(basename "$labeldir") | |
| fi | |
| mv $labeldir mcstas-nightly/ | |
| done | |
| done | |
| rm -rf "$work" | |
| 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 mcviewtest across all platform columns' | |
| id: viewtest | |
| run: | | |
| cd "$PWD/mcstas-nightly" | |
| if [ -z "$REFLABEL" ]; then | |
| mcviewtest --reflabel "$REFLABEL" --nobrowse | |
| else | |
| mcviewtest --reflabel --nobrowse | |
| fi | |
| - name: 'Tar mcstas-nightly output (all platform folders + comparison table)' | |
| id: tar-package | |
| if: always() | |
| run: | | |
| tar cvfz mcstas-conda-testsuite-comparison.tgz mcstas-nightly | |
| - name: 'Upload comparison artifact' | |
| id: comparison-upload | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: mcstas-testsuite-comparison | |
| path: mcstas-conda-testsuite-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 |