Skip to content

Actions: Migrate to newer versions of macos #470

Actions: Migrate to newer versions of macos

Actions: Migrate to newer versions of macos #470

name: MHKiT-MATLAB Windows Unit Tests
# Only run tests when MATLAB files or this workflow file changes
on:
push:
branches: [ master, develop ]
paths:
- 'mhkit/**/*.m'
- 'examples/**/*.m'
- '.github/workflows/windows_unit_tests.yml'
pull_request:
branches: [ master, develop ]
paths:
- 'mhkit/**/*.m'
- 'examples/**/*.m'
- '.github/workflows/windows_unit_tests.yml'
jobs:
cache_population:
strategy:
fail-fast: false
matrix:
os: [windows-2025]
python-version: ["3.11"]
matlab-version: [R2023b]
runs-on: ${{ matrix.os }}
env:
mhkit-python-dir: "MHKiT-Python"
MHKIT_PYTHON_VERSION: '1.0.1'
steps:
- name: Install/Setup Miniconda
uses: conda-incubator/setup-miniconda@v3
with:
miniconda-version: latest
auto-update-conda: true
python-version: ${{ matrix.python-version }}
activate-environment: mhkit_conda_env
channels: conda-forge,defaults
# This is necessary to fix any issues with netcdf4 and hdf5 headers
- name: Conda install mhkit
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
conda install -c conda-forge mhkit==$MHKIT_PYTHON_VERSION
- name: Check out MHKiT-MATLAB
uses: actions/checkout@v4
- name: pip install mhkit-python-utils module from source
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip install -e .
# mhkit 1.0.1 requires numpy 2.0+ (uses np.trapezoid)
# scipy 1.14+ is compatible with numpy 2.0
- name: Pin scipy version
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip uninstall -y scipy
pip install scipy==1.14.0
- name: List Installed Python Packages using Conda
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
conda list
- name: List Installed Python Packages using pip
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip list
- name: Check out MHKiT-MATLAB
uses: actions/checkout@v4
# - name: Pin scipy version
# shell: bash -l {0}
# run: |
# conda activate mhkit_conda_env
# pip uninstall -y scipy
# pip install scipy==1.10.1
# Create the cache and add a dummy file
# The dummy file ensures that the artifact download
- name: Setup mhkit_webread_cache
shell: bash -l {0}
run: |
mkdir mhkit_webread_cache
touch mhkit_webread_cache/test.txt
echo "Hello World" > mhkit_webread_cache/test.txt
- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v2
with:
release: ${{ matrix.matlab-version }}
# Set Python environment variables BEFORE any MATLAB/Python interaction
# NOTE: Do NOT set PYTHONHOME - it causes "SRE module mismatch" errors
- name: Configure Python environment for MATLAB
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
# Add site-packages to Python's search path
echo "PYTHONPATH=$CONDA_PREFIX/Lib/site-packages" >> $GITHUB_ENV
# Add conda paths for DLL resolution
echo "$CONDA_PREFIX" >> $GITHUB_PATH
echo "$CONDA_PREFIX/Library/bin" >> $GITHUB_PATH
echo "$CONDA_PREFIX/Scripts" >> $GITHUB_PATH
- name: Set PYBIND11 GIL workaround
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
echo "PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DECREF=1" >> $GITHUB_ENV
# Allow duplicate OpenMP libraries (MATLAB's libiomp5md.dll + numpy's libomp.dll)
echo "KMP_DUPLICATE_LIB_OK=TRUE" >> $GITHUB_ENV
# Generate run.m using Python to avoid shell encoding issues on Windows
- name: Generate run.m
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python -c "
import sys
python_exe = sys.executable.replace('\\\\', '/')
content = f'''pyenv(Version='{python_exe}', ExecutionMode='OutOfProcess')
% Verify Python environment
pe = pyenv;
disp(pe);
% Warm up numpy - must call function to force resolution
py.importlib.import_module('numpy');
dummy = py.numpy.array([1,2,3]);
disp(class(dummy));
clear dummy;
disp('py.numpy.array: resolved');
% Warm up mhkit submodules - force resolution by calling functions
py.importlib.import_module('mhkit');
py.importlib.import_module('mhkit.wave.io.ndbc');
py.importlib.import_module('mhkit.wave.io.swan');
py.importlib.import_module('mhkit.river.resource');
disp('mhkit submodules: imported');
version
pyenv
addpath(genpath('mhkit'))
import matlab.unittest.TestSuite
import matlab.unittest.TestRunner
testFolder = ['mhkit' filesep 'tests'];
suite = TestSuite.fromFolder(testFolder);
runner = TestRunner.withTextOutput;
results = runner.run(suite);
assertSuccess(results)
'''
with open('run.m', 'w', encoding='utf-8', newline='\\n') as f:
f.write(content)
"
- name: Output Run.m
shell: bash
run: cat run.m
- name: Run MHKiT-MATLAB Unit Tests
uses: matlab-actions/run-command@v2
with:
command: run
startup-options: -noFigureWindows
- name: Save mhkit_webread_cache directory as an artifact
uses: actions/upload-artifact@v4
with:
# GitHub Action "Name" of artifact
name: mhkit_webread_cache
# Filesystem path of directory
path: mhkit_webread_cache
main:
needs: cache_population
strategy:
fail-fast: false
matrix:
os: [windows-2025]
python-version: ["3.10", 3.11, 3.12]
# matlab-version: [R2022b, R2023a, R2023b, R2024a, R2024b]
matlab-version: [R2023a, R2023b, R2024a, R2024b]
mhkit-python-version: ["1.0.1"]
exclude:
# Cache population job
- matlab-version: R2023b
python-version: "3.10"
# - matlab-version: R2023b
# python-version: 3.8
# Python 3.12 + MATLAB incompatability
- matlab-version: R2024a
python-version: 3.12
- matlab-version: R2023b
python-version: 3.12
- matlab-version: R2023a
python-version: 3.12
- matlab-version: R2022b
python-version: 3.12
# Python 3.11 + MATLAB incompatability
- matlab-version: R2023a
python-version: 3.11
- matlab-version: R2022b
python-version: 3.11
# Failing Job
# Python Error: ImportError: DLL load failed while importing pyexpat: The operating system cannot run %1
- matlab-version: R2023a
python-version: "3.10"
runs-on: ${{ matrix.os }}
env:
mhkit-python-dir: "MHKiT-Python"
MHKIT_PYTHON_VERSION: ${{ matrix.mhkit-python-version }}
steps:
- name: Install/Setup Miniconda
uses: conda-incubator/setup-miniconda@v3
with:
miniconda-version: latest
auto-update-conda: true
python-version: ${{ matrix.python-version }}
activate-environment: mhkit_conda_env
channels: conda-forge,defaults
# This is necessary to fix any issues with netcdf4 and hdf5 headers
- name: Conda install mhkit
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
conda install -c conda-forge mhkit==$MHKIT_PYTHON_VERSION
- name: Output python executable
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python -c "import sys; print(sys.executable)"
- name: Print Python Version
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python --version
- name: Check out MHKiT-MATLAB
uses: actions/checkout@v4
- name: pip install mhkit-python-utils module from source
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip3 install -e .
# mhkit 1.0.1 requires numpy 2.0+ (uses np.trapezoid)
# scipy 1.14+ is compatible with numpy 2.0
- name: Pin scipy version
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip uninstall -y scipy
pip install scipy==1.14.0
# Some tests fail with:
# Python Error: ImportError: DLL load failed while importing pyexpat: The operating system cannot run %1.
# One potential fix is to install expat and lxml
- name: Install Windows XML dependencies
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
# Simple single package install to avoid solver issues
conda install expat -y
# Alternative: use pip for XML parsing
pip install lxml
- name: List installed pip modules
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
pip3 freeze
- name: Print MHKiT-Python Version
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python -c "import mhkit; print(mhkit.__version__)"
- name: Verify MHKiT-Python Operation
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python -c "import mhkit; [ED, AP] = mhkit.river.performance.circular(30); print(ED); print(AP);"
- name: Download mhkit_webread_cache artifact
uses: actions/download-artifact@v4
with:
name: mhkit_webread_cache
path: mhkit_webread_cache
- name: Display structure mhkit_webread_cache
run: ls -R
working-directory: .
- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v2
with:
release: ${{ matrix.matlab-version }}
# Set Python environment variables BEFORE any MATLAB/Python interaction
# NOTE: Do NOT set PYTHONHOME - it causes "SRE module mismatch" errors
- name: Configure Python environment for MATLAB
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
# Add site-packages to Python's search path
echo "PYTHONPATH=$CONDA_PREFIX/Lib/site-packages" >> $GITHUB_ENV
# Add conda paths for DLL resolution
echo "$CONDA_PREFIX" >> $GITHUB_PATH
echo "$CONDA_PREFIX/Library/bin" >> $GITHUB_PATH
echo "$CONDA_PREFIX/Scripts" >> $GITHUB_PATH
- name: Set PYBIND11 GIL workaround
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
echo "PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DECREF=1" >> $GITHUB_ENV
# Allow duplicate OpenMP libraries (MATLAB's libiomp5md.dll + numpy's libomp.dll)
echo "KMP_DUPLICATE_LIB_OK=TRUE" >> $GITHUB_ENV
# Generate run.m using Python to avoid shell encoding issues on Windows
- name: Generate run.m
shell: bash -l {0}
run: |
conda activate mhkit_conda_env
python -c "
import sys
import os
python_exe = sys.executable.replace('\\\\', '/')
python_dir = os.path.dirname(sys.executable).replace('\\\\', '/')
content = f'''getenv('path')
setenv('path', ['{python_dir};', getenv('path')])
getenv('path')
pyenv(Version='{python_exe}', ExecutionMode='OutOfProcess')
% Verify Python environment
pe = pyenv;
disp(pe);
% Warm up numpy - must call function to force resolution
py.importlib.import_module('numpy');
dummy = py.numpy.array([1,2,3]);
disp(class(dummy));
clear dummy;
disp('py.numpy.array: resolved');
% Warm up mhkit submodules - force resolution by calling functions
py.importlib.import_module('mhkit');
py.importlib.import_module('mhkit.wave.io.ndbc');
py.importlib.import_module('mhkit.wave.io.swan');
py.importlib.import_module('mhkit.river.resource');
disp('mhkit submodules: imported');
py.sys.path
version
pyenv
addpath(genpath('mhkit'))
import matlab.unittest.TestSuite
import matlab.unittest.TestRunner
testFolder = ['mhkit' filesep 'tests'];
suite = TestSuite.fromFolder(testFolder);
runner = TestRunner.withTextOutput;
results = runner.run(suite);
assertSuccess(results)
'''
with open('run.m', 'w', encoding='utf-8', newline='\\n') as f:
f.write(content)
"
- name: Output Run.m
shell: bash
run: cat run.m
- name: Run MHKiT-MATLAB Unit Tests
uses: matlab-actions/run-command@v2
with:
command: run
startup-options: -noFigureWindows