From cb25a420181ab98c69fda54f0d13b8cb24d1ced0 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 15:48:26 -0400 Subject: [PATCH 01/35] MAINT: Switch to pip for macOS jobs --- .github/workflows/tests.yml | 34 ++++++++------------------ environment.yml | 4 +-- tools/github_actions_dependencies.sh | 3 ++- tools/github_actions_verify_python.sh | 26 ++++++++++++++++++++ tools/hooks/update_environment_file.py | 4 ++- 5 files changed, 43 insertions(+), 28 deletions(-) create mode 100755 tools/github_actions_verify_python.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f5afb0be73..995201d3fc6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - uses: actions/setup-python@v6 with: - python-version: '3.13' + python-version: '3.14' - uses: pre-commit/action@v3.0.1 - run: pip install mypy numpy scipy vulture - run: mypy @@ -77,11 +77,11 @@ jobs: python: '3.13' kind: conda - os: macos-latest # arm64 (Apple Silicon): Sequoia - python: '3.13' - kind: mamba + python: '3.14' + kind: pip - os: macos-15-intel # intel: Sequoia python: '3.13' - kind: mamba + kind: pip - os: windows-latest python: '3.11' kind: mamba @@ -123,31 +123,16 @@ jobs: with: python-version: ${{ matrix.python }} if: startswith(matrix.kind, 'pip') + id: setup-python + # Workaround macOS path behavior with login shells (which puts system Python first) + - run: echo "export PATH=\"$(dirname ${{ steps.setup-python.outputs.python-path }}):$PATH\"" | tee -a ~/.bash_profile # zizmor: ignore[template-injection] + if: startswith(matrix.kind, 'pip') && startswith(matrix.os, 'macos') # Python (if conda) - - name: Fixes for conda - run: | - # For some reason on Linux we get crashes - if [[ "$RUNNER_OS" == "Linux" ]]; then - sed -i "/numba/d" environment.yml - fi - # And on Windows and macOS PySide6.9.0 segfaults - if [[ "$RUNNER_OS" == "macOS" ]]; then - sed -i "" "s/ - PySide6 .*/ - PySide6 =6.9.2/g" environment.yml - sed -i "" "s/ - vtk .*/ - vtk =9.5.1/g" environment.yml - - else - sed -i "s/ - PySide6 .*/ - PySide6 =6.9.2/g" environment.yml - sed -i "s/ - vtk .*/ - vtk =9.5.1/g" environment.yml - if [[ "$RUNNER_OS" == "Windows" ]]; then - echo "MNE_IS_OSMESA=true" | tee -a $GITHUB_ENV - fi - fi - if: matrix.kind == 'conda' || matrix.kind == 'mamba' - uses: mamba-org/setup-micromamba@v3 with: environment-file: ${{ env.CONDA_ENV }} environment-name: mne - log-level: ${{ runner.debug == '1' && 'debug' || 'info' }} + log-level: 'info' create-args: >- python=${{ env.PYTHON_VERSION }} -v @@ -162,6 +147,7 @@ jobs: **/pylock.ci-old.toml python-version: ${{ matrix.python }} if: matrix.kind == 'old' + - run: bash ./tools/github_actions_verify_python.sh - run: bash ./tools/github_actions_dependencies.sh - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' diff --git a/environment.yml b/environment.yml index 4bc85279dc8..5e9800ef39a 100644 --- a/environment.yml +++ b/environment.yml @@ -43,7 +43,7 @@ dependencies: - pyarrow - pybv - pymatreader - - PySide6 !=6.9.1 + - PySide6 ==6.10.2 - python-neo - python-picard >=0.4 - pyvista >=0.43 @@ -61,7 +61,7 @@ dependencies: - trame - trame-vtk - trame-vuetify - - vtk >=9.2 + - vtk ==9.6.1 - xlrd - pip: - nest-asyncio2 diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 8621a7a9709..74956cd0aab 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -3,6 +3,7 @@ set -eo pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +ONLY_BINARY_ARG="--only-binary=numpy,scipy,matplotlib,numba,llvmlite,antio" STD_ARGS="--progress-bar off --upgrade" INSTALL_ARGS="-e" if [ ! -z "$CONDA_ENV" ]; then @@ -61,6 +62,6 @@ else echo "::group::Installing MNE in development mode using pip" fi set -x -python -m pip install $STD_ARGS $INSTALL_ARGS .$EXTRAS $GROUP_ARG +python -m pip install $STD_ARGS $ONLY_BINARY_ARG $INSTALL_ARGS .$EXTRAS $GROUP_ARG set +x echo "::endgroup::" diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh new file mode 100755 index 00000000000..d9dd77aa2b0 --- /dev/null +++ b/tools/github_actions_verify_python.sh @@ -0,0 +1,26 @@ +#!/bin/bash -ef + +set -eo pipefail + +GOT_PYTHON=$(which python) +echo "Checking Python at: +echo " which python=${GOT_PYTHON} +echo "for" +echo " MNE_CI_KIND=${MNE_CI_KIND}" +if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then + WANT="micromamba/envs/mne" +elif [[ "${MNE_CI_KIND}" == "old" ]]; then + WANT="mne-python/mne-python/.venv/bin" +elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]]; then + WANT="hostedtoolcache/Python" +else + echo "ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" + exit 1 +fi +if [[ "${GOT_PYTHON}" != *"${WANT}"* ]]; then + echo "ERROR: Did not find \"${WANT}\" from PATH:" + tr ':' '\n' <<< "$PATH" + exit 1 +else + echo "OK: Found expected \"${WANT}\"" +fi diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index da4b3e6eb46..1d7d3416d39 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -57,7 +57,9 @@ def split_dep(dep): # `environment.yaml` breaks the solver. 6.9.1 has a bug, and 6.9.2 needs newer # C deps that mean we need to upgrade VTK etc. if package_name == "PySide6": - version_spec = "!=6.9.1" + version_spec = "==6.10.2" + if package_name == "vtk": + version_spec = "==9.6.1" # rstrip output line in case `version_spec` == "" line = f" - {package_name} {version_spec}".rstrip() # use pip for packages needing e.g. `platform_system` or `python_version` triaging From 91bf0426ae4df02a530ca49cc1d118eda16baec4 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:18:22 -0400 Subject: [PATCH 02/35] FIX: More --- mne/tests/test_surface.py | 3 +++ tools/github_actions_env_vars.sh | 4 ++-- tools/github_actions_verify_python.sh | 12 ++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/mne/tests/test_surface.py b/mne/tests/test_surface.py index eeaedbb5e05..2ad97262f5d 100644 --- a/mne/tests/test_surface.py +++ b/mne/tests/test_surface.py @@ -2,6 +2,7 @@ # License: BSD-3-Clause # Copyright the MNE-Python contributors. +import os from pathlib import Path import numpy as np @@ -252,6 +253,8 @@ def test_normal_orth(): def test_marching_cubes(dtype, value, smooth, order): """Test creating surfaces via marching cubes.""" pytest.importorskip("pyvista") + if os.getenv("MNE_CI_KIND") in ("conda", "mamba"): + pytest.skip("VTK on conda CIs segfaults") data = np.zeros((50, 50, 50), dtype=dtype, order=order) data[20:30, 20:30, 20:30] = value level = [value] diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index c518e982276..eac7b1f6e5a 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -eo pipefail -x +set -eo pipefail # old and minimal use conda if [[ "$MNE_CI_KIND" == "pip"* ]]; then @@ -27,7 +27,7 @@ else # conda-like echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV # TODO: Also need "|unreliable on GitHub Actions conda" on macOS, but omit for now to make sure the failure actually shows up - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior).*" | tee -a $GITHUB_ENV + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV # Our cache_dir test has problems when the path is too long, so prevent it from getting too long if [[ "$RUNNER_OS" == "macOS" ]]; then echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index d9dd77aa2b0..3ff0316a6b2 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -3,10 +3,10 @@ set -eo pipefail GOT_PYTHON=$(which python) -echo "Checking Python at: -echo " which python=${GOT_PYTHON} +echo "Checking Python found at:" +echo " $(which python) == ${GOT_PYTHON}" echo "for" -echo " MNE_CI_KIND=${MNE_CI_KIND}" +echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then WANT="micromamba/envs/mne" elif [[ "${MNE_CI_KIND}" == "old" ]]; then @@ -14,13 +14,13 @@ elif [[ "${MNE_CI_KIND}" == "old" ]]; then elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]]; then WANT="hostedtoolcache/Python" else - echo "ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" + echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" exit 1 fi if [[ "${GOT_PYTHON}" != *"${WANT}"* ]]; then - echo "ERROR: Did not find \"${WANT}\" from PATH:" + echo "✕ ERROR: Did not find \"${WANT}\" from PATH:" tr ':' '\n' <<< "$PATH" exit 1 else - echo "OK: Found expected \"${WANT}\"" + echo "☑ Found expected \"${WANT}\"" fi From 22f6f7b777436769f154fd858fffff70b3a9b225 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:22:44 -0400 Subject: [PATCH 03/35] FIX: arm64 can run slow ones now --- tools/github_actions_test.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/github_actions_test.sh b/tools/github_actions_test.sh index 202b041bc79..7b1f7143c3b 100755 --- a/tools/github_actions_test.sh +++ b/tools/github_actions_test.sh @@ -4,8 +4,18 @@ set -eo pipefail if [[ "${CI_OS_NAME}" == "ubuntu"* ]]; then CONDITION="not (ultraslowtest or pgtest)" -else # macOS or Windows +elif [[ "${CI_OS_NAME}" == "macos"* ]]; then + # detect arch and run slowtest on arm64 only (pgtest is already ultraslow on macOS) + if [[ "$(uname -m)" == "arm64" ]]; then + CONDITION="not (ultraslowtest or pgtest)" + else + CONDITION="not (slowtest or pgtest)" + fi +elif [[ "${CI_OS_NAME}" == "windows"* ]]; then CONDITION="not (slowtest or pgtest)" +else: + echo "✕ ERROR: Unrecognized CI_OS_NAME=${CI_OS_NAME}" + exit 1 fi if [ "${MNE_CI_KIND}" == "notebook" ]; then USE_DIRS=mne/viz/ From 8fe639bd79cdca03b569bbb4fd7e7776f681f5bc Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:26:15 -0400 Subject: [PATCH 04/35] FIX: Bash --- tools/github_actions_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/github_actions_test.sh b/tools/github_actions_test.sh index 7b1f7143c3b..d55613e97cc 100755 --- a/tools/github_actions_test.sh +++ b/tools/github_actions_test.sh @@ -13,7 +13,7 @@ elif [[ "${CI_OS_NAME}" == "macos"* ]]; then fi elif [[ "${CI_OS_NAME}" == "windows"* ]]; then CONDITION="not (slowtest or pgtest)" -else: +else echo "✕ ERROR: Unrecognized CI_OS_NAME=${CI_OS_NAME}" exit 1 fi From 90a88f1060d88447c32afe9ead71577318dc465e Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:29:20 -0400 Subject: [PATCH 05/35] FIX: Escapes --- tools/github_actions_verify_python.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index 3ff0316a6b2..ab6322a2371 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -4,7 +4,7 @@ set -eo pipefail GOT_PYTHON=$(which python) echo "Checking Python found at:" -echo " $(which python) == ${GOT_PYTHON}" +echo " \$(which python) == ${GOT_PYTHON}" echo "for" echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then From f124275608b3c429cd5e533d75b3b1bdd9364265 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:34:51 -0400 Subject: [PATCH 06/35] FIX: Kind --- .github/workflows/tests.yml | 2 +- tools/github_actions_env_vars.sh | 29 ++++++++++++--------------- tools/github_actions_verify_python.sh | 2 +- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 995201d3fc6..1439d43be3f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,7 +122,7 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - if: startswith(matrix.kind, 'pip') + if: startswith(matrix.kind, 'pip') || matrix.kind == 'minimal' id: setup-python # Workaround macOS path behavior with login shells (which puts system Python first) - run: echo "export PATH=\"$(dirname ${{ steps.setup-python.outputs.python-path }}):$PATH\"" | tee -a ~/.bash_profile # zizmor: ignore[template-injection] diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index eac7b1f6e5a..50aafaabfcb 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -4,34 +4,31 @@ set -eo pipefail # old and minimal use conda if [[ "$MNE_CI_KIND" == "pip"* ]]; then echo "Setting pip env vars for $MNE_CI_KIND" + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV if [[ "$MNE_CI_KIND" == "pip-pre" ]]; then - echo "MNE_QT_BACKEND=PyQt6" | tee -a $GITHUB_ENV # We should test an eager import somewhere, might as well be here echo "EAGER_IMPORT=true" | tee -a $GITHUB_ENV # Make sure nothing unexpected is skipped echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|Numba not|PySide6 causes segfaults).*" | tee -a $GITHUB_ENV - else - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV fi elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_IGNORE_WARNINGS_IN_TESTS=true" | tee -a $GITHUB_ENV echo "MNE_SKIP_NETWORK_TESTS=1" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV +elif [[ "$MNE_CI_KIND" == "minimal" ]]; then + echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV else # conda-like echo "Setting conda env vars for $MNE_CI_KIND" - if [[ "$MNE_CI_KIND" == "minimal" ]]; then - echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV - else # conda, mamba (use warning level for completeness) - echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV - echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV - # TODO: Also need "|unreliable on GitHub Actions conda" on macOS, but omit for now to make sure the failure actually shows up - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV - # Our cache_dir test has problems when the path is too long, so prevent it from getting too long - if [[ "$RUNNER_OS" == "macOS" ]]; then - echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV - fi + # conda, mamba (use warning level for completeness) + echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV + echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV + # TODO: Also need "|unreliable on GitHub Actions conda" on macOS, but omit for now to make sure the failure actually shows up + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV + # Our cache_dir test has problems when the path is too long, so prevent it from getting too long + if [[ "$RUNNER_OS" == "macOS" ]]; then + echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV fi fi set +x diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index ab6322a2371..9107dce27db 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -11,7 +11,7 @@ if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then WANT="micromamba/envs/mne" elif [[ "${MNE_CI_KIND}" == "old" ]]; then WANT="mne-python/mne-python/.venv/bin" -elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]]; then +elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]] || [[ "${MNE_CI_KIND}" == "minimal" ]]; then WANT="hostedtoolcache/Python" else echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" From 58dc371af45c5925e06aac7cf1f46ad6462a80d6 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:38:51 -0400 Subject: [PATCH 07/35] FIX: Cleaner --- .github/workflows/tests.yml | 4 ++-- tools/environment_minimal.yml | 12 ++---------- tools/github_actions_dependencies.sh | 4 +--- tools/github_actions_env_vars.sh | 25 ++++++++++++------------- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1439d43be3f..cfa8eb00c2b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,7 +122,7 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - if: startswith(matrix.kind, 'pip') || matrix.kind == 'minimal' + if: startswith(matrix.kind, 'pip') id: setup-python # Workaround macOS path behavior with login shells (which puts system Python first) - run: echo "export PATH=\"$(dirname ${{ steps.setup-python.outputs.python-path }}):$PATH\"" | tee -a ~/.bash_profile # zizmor: ignore[template-injection] @@ -136,7 +136,7 @@ jobs: create-args: >- python=${{ env.PYTHON_VERSION }} -v - if: matrix.kind == 'conda' || matrix.kind == 'mamba' + if: matrix.kind == 'conda' || matrix.kind == 'mamba' || matrix.kind == 'minimal' timeout-minutes: 20 # Python (if old) - uses: astral-sh/setup-uv@v8.1.0 diff --git a/tools/environment_minimal.yml b/tools/environment_minimal.yml index f67decbe0d2..dd6e90b7030 100644 --- a/tools/environment_minimal.yml +++ b/tools/environment_minimal.yml @@ -2,14 +2,6 @@ name: mne channels: - conda-forge dependencies: - - python>=3.9 + - python >=3.9 - pip - - numpy - - scipy - - matplotlib - - tqdm - - pooch - - decorator - - packaging - - jinja2 - - lazy_loader + - mne-base diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 74956cd0aab..63a140ad527 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -8,10 +8,8 @@ STD_ARGS="--progress-bar off --upgrade" INSTALL_ARGS="-e" if [ ! -z "$CONDA_ENV" ]; then echo "Uninstalling MNE for CONDA_ENV=${CONDA_ENV}" - # This will fail if mne-base is not in the env (like in our minimal env, so ||true them): echo "::group::Uninstalling MNE" - conda remove -c conda-forge --force -yq mne-base || true - python -m pip uninstall -y mne || true + conda remove -c conda-forge --force -yq mne-base echo "::endgroup::" # If using bare environment.yml and not on windows, do a non-editable install if [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${CONDA_ENV}" != "environment_"* ]]; then diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 50aafaabfcb..8a6e31a00c1 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -4,31 +4,30 @@ set -eo pipefail # old and minimal use conda if [[ "$MNE_CI_KIND" == "pip"* ]]; then echo "Setting pip env vars for $MNE_CI_KIND" - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV if [[ "$MNE_CI_KIND" == "pip-pre" ]]; then # We should test an eager import somewhere, might as well be here echo "EAGER_IMPORT=true" | tee -a $GITHUB_ENV # Make sure nothing unexpected is skipped echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|Numba not|PySide6 causes segfaults).*" | tee -a $GITHUB_ENV fi + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_IGNORE_WARNINGS_IN_TESTS=true" | tee -a $GITHUB_ENV echo "MNE_SKIP_NETWORK_TESTS=1" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV -elif [[ "$MNE_CI_KIND" == "minimal" ]]; then - echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV else # conda-like echo "Setting conda env vars for $MNE_CI_KIND" - # conda, mamba (use warning level for completeness) - echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV - echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV - echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV - # TODO: Also need "|unreliable on GitHub Actions conda" on macOS, but omit for now to make sure the failure actually shows up - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV - # Our cache_dir test has problems when the path is too long, so prevent it from getting too long - if [[ "$RUNNER_OS" == "macOS" ]]; then - echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV + if [[ "$MNE_CI_KIND" == "minimal" ]]; then + echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV + else # conda, mamba (use warning level for completeness) + echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV + echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV + # Our cache_dir test has problems when the path is too long, so prevent it from getting too long + if [[ "$RUNNER_OS" == "macOS" ]]; then + echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV + fi fi + echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV fi set +x From 9bab071a105aa5e11284facfaaab36d1c619c55e Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:40:57 -0400 Subject: [PATCH 08/35] FIX: Simplify --- .github/workflows/tests.yml | 4 ++-- tools/environment_minimal.yml | 7 ------- tools/github_actions_dependencies.sh | 22 ++++++++++------------ 3 files changed, 12 insertions(+), 21 deletions(-) delete mode 100644 tools/environment_minimal.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cfa8eb00c2b..1439d43be3f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,7 +122,7 @@ jobs: - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - if: startswith(matrix.kind, 'pip') + if: startswith(matrix.kind, 'pip') || matrix.kind == 'minimal' id: setup-python # Workaround macOS path behavior with login shells (which puts system Python first) - run: echo "export PATH=\"$(dirname ${{ steps.setup-python.outputs.python-path }}):$PATH\"" | tee -a ~/.bash_profile # zizmor: ignore[template-injection] @@ -136,7 +136,7 @@ jobs: create-args: >- python=${{ env.PYTHON_VERSION }} -v - if: matrix.kind == 'conda' || matrix.kind == 'mamba' || matrix.kind == 'minimal' + if: matrix.kind == 'conda' || matrix.kind == 'mamba' timeout-minutes: 20 # Python (if old) - uses: astral-sh/setup-uv@v8.1.0 diff --git a/tools/environment_minimal.yml b/tools/environment_minimal.yml deleted file mode 100644 index dd6e90b7030..00000000000 --- a/tools/environment_minimal.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: mne -channels: - - conda-forge -dependencies: - - python >=3.9 - - pip - - mne-base diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 63a140ad527..d11b9b41a4c 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -9,24 +9,22 @@ INSTALL_ARGS="-e" if [ ! -z "$CONDA_ENV" ]; then echo "Uninstalling MNE for CONDA_ENV=${CONDA_ENV}" echo "::group::Uninstalling MNE" - conda remove -c conda-forge --force -yq mne-base + conda remove -c conda-forge --force -y mne-base echo "::endgroup::" # If using bare environment.yml and not on windows, do a non-editable install if [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${CONDA_ENV}" != "environment_"* ]]; then INSTALL_ARGS="" fi # If on minimal, just install testing deps - if [[ "${MNE_CI_KIND}" == "minimal" ]]; then - GROUP="test" - EXTRAS="" - STD_ARGS="--progress-bar off ${MNE_QT_BACKEND}" - echo "::group::Upgrading pip installation" - python -m pip install --upgrade pip # upgrade pip to support --group - echo "::endgroup::" - else - GROUP="test_extra" - EXTRAS="[hdf5]" - fi + GROUP="test_extra" + EXTRAS="[hdf5]" +elif [[ "${MNE_CI_KIND}" == "minimal" ]]; then + GROUP="test" + EXTRAS="" + STD_ARGS="--progress-bar off ${MNE_QT_BACKEND}" + echo "::group::Upgrading pip installation" + python -m pip install --upgrade pip # upgrade pip to support --group + echo "::endgroup::" elif [[ "${MNE_CI_KIND}" == "old" ]]; then GROUP="" # group "test" already included when pylock file generated EXTRAS="" From d8e276e9c8fbbfbd4ac196d4f886a757e6cac7a8 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:42:13 -0400 Subject: [PATCH 09/35] FIX: Better --- tools/github_actions_env_vars.sh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 8a6e31a00c1..4e699263d0e 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -2,7 +2,7 @@ set -eo pipefail # old and minimal use conda -if [[ "$MNE_CI_KIND" == "pip"* ]]; then +if [[ "$MNE_CI_KIND" == "pip"* ]] || [[ "$MNE_CI_KIND" == "minimal" ]]; then echo "Setting pip env vars for $MNE_CI_KIND" if [[ "$MNE_CI_KIND" == "pip-pre" ]]; then # We should test an eager import somewhere, might as well be here @@ -17,16 +17,12 @@ elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV else # conda-like echo "Setting conda env vars for $MNE_CI_KIND" - if [[ "$MNE_CI_KIND" == "minimal" ]]; then - echo "CONDA_ENV=tools/environment_minimal.yml" | tee -a $GITHUB_ENV - else # conda, mamba (use warning level for completeness) - echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV - echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV - # Our cache_dir test has problems when the path is too long, so prevent it from getting too long - if [[ "$RUNNER_OS" == "macOS" ]]; then - echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV - fi + echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV + echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV + # Our cache_dir test has problems when the path is too long, so prevent it from getting too long + if [[ "$RUNNER_OS" == "macOS" ]]; then + echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV fi echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV fi From a2a22b3c2a3ed3ca8dfde337dffdacc9180a2b08 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:43:31 -0400 Subject: [PATCH 10/35] FIX: Simplify --- tools/install_pre_requirements.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/install_pre_requirements.sh b/tools/install_pre_requirements.sh index 9977a01c9d4..093940e193a 100755 --- a/tools/install_pre_requirements.sh +++ b/tools/install_pre_requirements.sh @@ -7,7 +7,9 @@ PLATFORM=$(python -c 'import platform; print(platform.system())') echo "Installing pip-pre dependencies on ${PLATFORM}" STD_ARGS="--progress-bar off --upgrade --pre" -QT_BINDING="PySide6" +if [[ "$MNE_QT_BACKEND" == "" ]]; then + MNE_QT_BACKEND="PySide6" +fi # Dependencies of scientific-python-nightly-wheels are installed here so that # we can use strict --index-url (instead of --extra-index-url) below @@ -16,7 +18,7 @@ echo "::group::Prerequisites" python -m pip install $STD_ARGS pip setuptools packaging \ threadpoolctl cycler fonttools kiwisolver pyparsing pillow python-dateutil \ patsy pytz tzdata nibabel tqdm trx-python joblib numexpr \ - "$QT_BINDING!=6.9.1" \ + "$MNE_QT_BACKEND!=6.9.1" \ py-cpuinfo blosc2 hatchling "formulaic>=1.1.0" \ matplotlib python -m pip uninstall -yq numpy @@ -69,5 +71,5 @@ python -c "import numpy as np; assert np.__version__[0] == '2', np.__version__" echo "::endgroup::" echo "::group::Check Qt import" -${SCRIPT_DIR}/check_qt_import.sh "$QT_BINDING" +${SCRIPT_DIR}/check_qt_import.sh "$MNE_QT_BACKEND" echo "::endgroup::" From 01539a3c90ddc022eee95cd2fd3b24dc4f2a58b0 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:44:03 -0400 Subject: [PATCH 11/35] FIX: Verify --- tools/github_actions_env_vars.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 4e699263d0e..3e2dc356cf6 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -15,7 +15,7 @@ elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_IGNORE_WARNINGS_IN_TESTS=true" | tee -a $GITHUB_ENV echo "MNE_SKIP_NETWORK_TESTS=1" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV -else # conda-like +elif [[ "$MNE_CI_KIND" == "conda" ]] || [[ "$MNE_CI_KIND" == "mamba" ]]; then echo "Setting conda env vars for $MNE_CI_KIND" echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV @@ -25,5 +25,8 @@ else # conda-like echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV fi echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV +else + echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" + exit 1 fi set +x From d7d684754cd9bc32ba25c15440df4ed9d08418af Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:46:44 -0400 Subject: [PATCH 12/35] FIX: Cleanup --- tools/github_actions_dependencies.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index d11b9b41a4c..7b00214d9ea 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -11,11 +11,10 @@ if [ ! -z "$CONDA_ENV" ]; then echo "::group::Uninstalling MNE" conda remove -c conda-forge --force -y mne-base echo "::endgroup::" - # If using bare environment.yml and not on windows, do a non-editable install - if [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${CONDA_ENV}" != "environment_"* ]]; then + # If not on windows, do a non-editable install + if [[ "${RUNNER_OS}" != "Windows" ]]; then INSTALL_ARGS="" fi - # If on minimal, just install testing deps GROUP="test_extra" EXTRAS="[hdf5]" elif [[ "${MNE_CI_KIND}" == "minimal" ]]; then From ac1f9ef73026dbbb44cbc8f0104cca38293f5b45 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 17:51:07 -0400 Subject: [PATCH 13/35] FIX: Py ver --- .github/workflows/tests.yml | 2 +- tools/github_actions_verify_python.sh | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1439d43be3f..81727e5b031 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -147,7 +147,7 @@ jobs: **/pylock.ci-old.toml python-version: ${{ matrix.python }} if: matrix.kind == 'old' - - run: bash ./tools/github_actions_verify_python.sh + - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index 9107dce27db..25f46ebbfc2 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -2,11 +2,19 @@ set -eo pipefail +WANT_PYTHON_VERSION="$1" +if [[ -z "$WANT_PYTHON_VERSION" ]]; then + echo "✕ ERROR: Missing required argument: want Python version (e.g., 3.10)" + exit 1 +fi + GOT_PYTHON=$(which python) +GOT_PYTHON_VERSION=$(python --version) echo "Checking Python found at:" -echo " \$(which python) == ${GOT_PYTHON}" +echo " \$(which python) == ${GOT_PYTHON}" +echo " \$(python --version) == ${GOT_PYTHON_VERSION}" echo "for" -echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" +echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then WANT="micromamba/envs/mne" elif [[ "${MNE_CI_KIND}" == "old" ]]; then @@ -24,3 +32,9 @@ if [[ "${GOT_PYTHON}" != *"${WANT}"* ]]; then else echo "☑ Found expected \"${WANT}\"" fi +if [[ "${GOT_PYTHON_VERSION}" != *"${WANT_PYTHON_VERSION}"* ]]; then + echo "✕ ERROR: Did not find expected Python version \"${WANT_PYTHON_VERSION}\"" + exit 1 +else + echo "☑ Found expected Python version \"${WANT_PYTHON_VERSION}\"" +fi \ No newline at end of file From 6a2a48eb60aad7c63d433359d2b3132c1479ab12 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:00:17 -0400 Subject: [PATCH 14/35] FIX: Move --- environment.yml | 3 ++- tools/hooks/update_environment_file.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/environment.yml b/environment.yml index 5e9800ef39a..26872d36be5 100644 --- a/environment.yml +++ b/environment.yml @@ -5,6 +5,7 @@ channels: dependencies: - python >=3.10 - antio >=0.5.0 + - conda - curryreader >=0.1.2 - darkdetect - decorator >=5.1 @@ -29,6 +30,7 @@ dependencies: - matplotlib >=3.8 - mffpy >=0.5.7 - mne-qt-browser + - nest-asyncio2 - nibabel >=2.0 - nilearn - nomkl @@ -64,6 +66,5 @@ dependencies: - vtk ==9.6.1 - xlrd - pip: - - nest-asyncio2 - pymef - pyobjc-framework-Cocoa >=5.2.0;platform_system=='Darwin' diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 1d7d3416d39..d9add65f908 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -22,8 +22,9 @@ deps |= set(section_deps) recursive_deps = set(d for d in deps if d.startswith("mne[")) deps -= recursive_deps -deps |= {"pip", "mamba", "nomkl"} -deps -= {"nest-asyncio2", "pymef"} # not on conda-forge +deps |= {"pip", "mamba", "conda", "nomkl"} +deps -= {"pymef"} # not on conda-forge +pip_deps = {" - pymef"} def remove_spaces(version_spec): @@ -47,7 +48,6 @@ def split_dep(dep): # split package name from version spec translations = dict(neo="python-neo") -pip_deps = {" - nest-asyncio2", " - pymef"} conda_deps = set() for dep in deps: package_name, version_spec = split_dep(dep) From 11b31b948ef9a3b8e4435ef1e0e302d6e74968a1 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:02:10 -0400 Subject: [PATCH 15/35] FIX: Move --- tools/hooks/update_environment_file.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index d9add65f908..a42ce3640ba 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -24,7 +24,7 @@ deps -= recursive_deps deps |= {"pip", "mamba", "conda", "nomkl"} deps -= {"pymef"} # not on conda-forge -pip_deps = {" - pymef"} +pip_deps = {"pymef"} def remove_spaces(version_spec): @@ -64,7 +64,7 @@ def split_dep(dep): line = f" - {package_name} {version_spec}".rstrip() # use pip for packages needing e.g. `platform_system` or `python_version` triaging if ";" in version_spec: - pip_deps.add(f" {line}") + pip_deps.add(line[4:]) else: conda_deps.add(line) @@ -72,7 +72,7 @@ def split_dep(dep): newline = "\n" # python < 3.12 forbids backslash in {} part of f-string pip_section = f"""\ - pip: -{newline.join(sorted(pip_deps, key=str.casefold))} +{newline.join(sorted((f" - {dep}" for dep in pip_deps), key=str.casefold))} """ pip_section = pip_section if len(pip_deps) else "" # prepare the env file From bf7c8ae05bf19ac97f971730d5483e0801e469bc Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:05:51 -0400 Subject: [PATCH 16/35] FIX: Move --- tools/hooks/update_environment_file.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index a42ce3640ba..057f6c51e52 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -23,8 +23,9 @@ recursive_deps = set(d for d in deps if d.startswith("mne[")) deps -= recursive_deps deps |= {"pip", "mamba", "conda", "nomkl"} -deps -= {"pymef"} # not on conda-forge +# not on conda-forge pip_deps = {"pymef"} +deps -= pip_deps def remove_spaces(version_spec): From e53a4867696e92e4aad1ce94bec490e44977885e Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:06:32 -0400 Subject: [PATCH 17/35] FIX: noqt --- environment.yml | 1 + tools/hooks/update_environment_file.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 26872d36be5..4eacf8a5003 100644 --- a/environment.yml +++ b/environment.yml @@ -34,6 +34,7 @@ dependencies: - nibabel >=2.0 - nilearn - nomkl + - noqt5 - numba >=0.35 - numpy >=1.26,<3 - openmeeg >=2.5.7 diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 057f6c51e52..4eeff2b9844 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -22,7 +22,7 @@ deps |= set(section_deps) recursive_deps = set(d for d in deps if d.startswith("mne[")) deps -= recursive_deps -deps |= {"pip", "mamba", "conda", "nomkl"} +deps |= {"pip", "mamba", "conda", "nomkl", "noqt5"} # not on conda-forge pip_deps = {"pymef"} deps -= pip_deps From 39df8bff412badacea9dda41c05b4fd8ac460f9d Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:10:18 -0400 Subject: [PATCH 18/35] FIX: Clean --- environment.yml | 4 ++-- tools/hooks/update_environment_file.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/environment.yml b/environment.yml index 4eacf8a5003..ee25ce2cbf3 100644 --- a/environment.yml +++ b/environment.yml @@ -46,7 +46,7 @@ dependencies: - pyarrow - pybv - pymatreader - - PySide6 ==6.10.2 + - PySide6 !=6.7.0,!=6.8.0,!=6.8.0.1,!=6.9.1 - python-neo - python-picard >=0.4 - pyvista >=0.43 @@ -64,7 +64,7 @@ dependencies: - trame - trame-vtk - trame-vuetify - - vtk ==9.6.1 + - vtk >=9.2 - xlrd - pip: - pymef diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 4eeff2b9844..521f61cc077 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -50,17 +50,21 @@ def split_dep(dep): # split package name from version spec translations = dict(neo="python-neo") conda_deps = set() +version_spec_overrides = { + # Help the solver work faster by specifying these (should be updated periodically): + "PySide6": "==6.10.2", + "vtk": "==9.6.1", +} +for key in version_spec_overrides: + assert any(dep.startswith(key) for dep in deps), ( + f"Need to adjust code below if {key} is not a dependency: {deps}" + ) for dep in deps: package_name, version_spec = split_dep(dep) + version_spec = version_spec_overrides.get(dep, version_spec) # handle package name differences package_name = translations.get(package_name, package_name) - # PySide6==6.7.0 only exists on PyPI, not conda-forge, so excluding it in - # `environment.yaml` breaks the solver. 6.9.1 has a bug, and 6.9.2 needs newer # C deps that mean we need to upgrade VTK etc. - if package_name == "PySide6": - version_spec = "==6.10.2" - if package_name == "vtk": - version_spec = "==9.6.1" # rstrip output line in case `version_spec` == "" line = f" - {package_name} {version_spec}".rstrip() # use pip for packages needing e.g. `platform_system` or `python_version` triaging From 86cc1840ab1400a3f7d89d7552946effdcae50ca Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:10:31 -0400 Subject: [PATCH 19/35] FIX: Clean --- environment.yml | 4 ++-- tools/hooks/update_environment_file.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/environment.yml b/environment.yml index ee25ce2cbf3..4eacf8a5003 100644 --- a/environment.yml +++ b/environment.yml @@ -46,7 +46,7 @@ dependencies: - pyarrow - pybv - pymatreader - - PySide6 !=6.7.0,!=6.8.0,!=6.8.0.1,!=6.9.1 + - PySide6 ==6.10.2 - python-neo - python-picard >=0.4 - pyvista >=0.43 @@ -64,7 +64,7 @@ dependencies: - trame - trame-vtk - trame-vuetify - - vtk >=9.2 + - vtk ==9.6.1 - xlrd - pip: - pymef diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 521f61cc077..74a31ff52ac 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -61,7 +61,7 @@ def split_dep(dep): ) for dep in deps: package_name, version_spec = split_dep(dep) - version_spec = version_spec_overrides.get(dep, version_spec) + version_spec = version_spec_overrides.get(package_name, version_spec) # handle package name differences package_name = translations.get(package_name, package_name) # C deps that mean we need to upgrade VTK etc. From c7116c600feab21c06d66b436526566809e70a05 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 18:13:42 -0400 Subject: [PATCH 20/35] FIX: Names --- tools/hooks/update_environment_file.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 74a31ff52ac..62507b534ae 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -49,7 +49,7 @@ def split_dep(dep): # split package name from version spec translations = dict(neo="python-neo") -conda_deps = set() +conda_dep_lines = set() version_spec_overrides = { # Help the solver work faster by specifying these (should be updated periodically): "PySide6": "==6.10.2", @@ -71,7 +71,7 @@ def split_dep(dep): if ";" in version_spec: pip_deps.add(line[4:]) else: - conda_deps.add(line) + conda_dep_lines.add(line) # prepare the pip dependencies section newline = "\n" # python < 3.12 forbids backslash in {} part of f-string @@ -88,7 +88,7 @@ def split_dep(dep): - conda-forge dependencies: - python {req_python} -{newline.join(sorted(conda_deps, key=str.casefold))} +{newline.join(sorted(conda_dep_lines, key=str.casefold))} {pip_section}""" # noqa: E501 (repo_root / "environment.yml").write_text(env) From 04840546564875749f0d67ee0a2852cb82c794d8 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:25:19 -0400 Subject: [PATCH 21/35] FIX: Revert --- environment.yml | 2 +- mne/conftest.py | 1 + mne/tests/test_source_estimate.py | 2 +- mne/tests/test_surface.py | 3 --- tools/hooks/update_environment_file.py | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/environment.yml b/environment.yml index 4eacf8a5003..00982630e41 100644 --- a/environment.yml +++ b/environment.yml @@ -64,7 +64,7 @@ dependencies: - trame - trame-vtk - trame-vuetify - - vtk ==9.6.1 + - vtk ==9.6.0 - xlrd - pip: - pymef diff --git a/mne/conftest.py b/mne/conftest.py index 85a1e72e9f8..2c2ee028b79 100644 --- a/mne/conftest.py +++ b/mne/conftest.py @@ -213,6 +213,7 @@ def pytest_configure(config: pytest.Config): # VTK <-> NumPy 2.5 (https://gitlab.kitware.com/vtk/vtk/-/merge_requests/12796) # nitime <-> NumPy 2.5 (https://github.com/nipy/nitime/pull/236) ignore:Setting the shape on a NumPy array has been deprecated.*:DeprecationWarning + ignore:Implicitly cleaning up.*:ResourceWarning """ # noqa: E501 for warning_line in warning_lines.split("\n"): warning_line = warning_line.strip() diff --git a/mne/tests/test_source_estimate.py b/mne/tests/test_source_estimate.py index 41e33c52274..2dfd3bb04d4 100644 --- a/mne/tests/test_source_estimate.py +++ b/mne/tests/test_source_estimate.py @@ -1983,7 +1983,7 @@ def test_scale_morph_labels(kind, scale, monkeypatch, tmp_path): min_, max_ = 0.72, 0.76 else: # min_, max_ = 0.84, 0.855 # zooms='auto' values - min_, max_ = 0.46, 0.63 + min_, max_ = 0.44, 0.63 assert min_ < corr <= max_, scale else: assert_allclose(label_tc, label_tc_to_morph, atol=1e-12, rtol=1e-12) diff --git a/mne/tests/test_surface.py b/mne/tests/test_surface.py index 2ad97262f5d..eeaedbb5e05 100644 --- a/mne/tests/test_surface.py +++ b/mne/tests/test_surface.py @@ -2,7 +2,6 @@ # License: BSD-3-Clause # Copyright the MNE-Python contributors. -import os from pathlib import Path import numpy as np @@ -253,8 +252,6 @@ def test_normal_orth(): def test_marching_cubes(dtype, value, smooth, order): """Test creating surfaces via marching cubes.""" pytest.importorskip("pyvista") - if os.getenv("MNE_CI_KIND") in ("conda", "mamba"): - pytest.skip("VTK on conda CIs segfaults") data = np.zeros((50, 50, 50), dtype=dtype, order=order) data[20:30, 20:30, 20:30] = value level = [value] diff --git a/tools/hooks/update_environment_file.py b/tools/hooks/update_environment_file.py index 62507b534ae..ba822baa651 100755 --- a/tools/hooks/update_environment_file.py +++ b/tools/hooks/update_environment_file.py @@ -53,7 +53,7 @@ def split_dep(dep): version_spec_overrides = { # Help the solver work faster by specifying these (should be updated periodically): "PySide6": "==6.10.2", - "vtk": "==9.6.1", + "vtk": "==9.6.0", } for key in version_spec_overrides: assert any(dep.startswith(key) for dep in deps), ( From 02f70a4ad08ee4c2c03a7a2ac7400f08e5b69d8e Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:28:12 -0400 Subject: [PATCH 22/35] WIP: Try --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 81727e5b031..bff7d6ed153 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -149,6 +149,7 @@ jobs: if: matrix.kind == 'old' - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh + - run: pytest mne/tests/test_surface.py -k cubes - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' # Minimal commands on Linux (macOS stalls) From 2f1fd1104f406e6c22cd2d1d8a459c92f3ec9851 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:33:36 -0400 Subject: [PATCH 23/35] FIX: Both --- .github/workflows/tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bff7d6ed153..1db4726fca4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -149,7 +149,6 @@ jobs: if: matrix.kind == 'old' - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh - - run: pytest mne/tests/test_surface.py -k cubes - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' # Minimal commands on Linux (macOS stalls) @@ -168,6 +167,8 @@ jobs: key: ${{ env.TESTING_VERSION }} path: ~/mne_data - run: bash ./tools/github_actions_download.sh + - run: pytest mne/viz -k test_brain_gc + - run: pytest mne/tests/test_surface.py -k cubes - run: bash ./tools/github_actions_test.sh # for some reason on macOS we need to run "bash X" in order for a failed test run to show up - uses: codecov/codecov-action@v6 with: From a0ea25c5759e0431c5873078d14c5d0bfb982880 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:38:19 -0400 Subject: [PATCH 24/35] TST: Try From 257396f63a7f80481d89e830a0883843ead5a698 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:45:28 -0400 Subject: [PATCH 25/35] FIX: Which --- .github/workflows/tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1db4726fca4..81727e5b031 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -167,8 +167,6 @@ jobs: key: ${{ env.TESTING_VERSION }} path: ~/mne_data - run: bash ./tools/github_actions_download.sh - - run: pytest mne/viz -k test_brain_gc - - run: pytest mne/tests/test_surface.py -k cubes - run: bash ./tools/github_actions_test.sh # for some reason on macOS we need to run "bash X" in order for a failed test run to show up - uses: codecov/codecov-action@v6 with: From aa00244aab496d50226d0db939adaaa3ef7bcb75 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:47:44 -0400 Subject: [PATCH 26/35] FIX: No need --- tools/github_actions_env_vars.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 3e2dc356cf6..9b9168c3a26 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -19,7 +19,7 @@ elif [[ "$MNE_CI_KIND" == "conda" ]] || [[ "$MNE_CI_KIND" == "mamba" ]]; then echo "Setting conda env vars for $MNE_CI_KIND" echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV - echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior|VTK on conda).*" | tee -a $GITHUB_ENV + echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior).*" | tee -a $GITHUB_ENV # Our cache_dir test has problems when the path is too long, so prevent it from getting too long if [[ "$RUNNER_OS" == "macOS" ]]; then echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV From 8688367ed6ae93ced4f8c06e3d54037aa4bc4a88 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:50:42 -0400 Subject: [PATCH 27/35] FIX: Try again [skip circle] [skip azp] --- .github/workflows/tests.yml | 27 ++++----------------------- tools/github_actions_env_vars.sh | 2 +- tools/github_actions_verify_python.sh | 2 +- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 81727e5b031..7aee9f2ceaa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -67,30 +67,9 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - python: '3.13' - kind: pip - - os: ubuntu-latest - python: '3.14' - kind: pip-pre - - os: ubuntu-latest - python: '3.13' - kind: conda - - os: macos-latest # arm64 (Apple Silicon): Sequoia - python: '3.14' - kind: pip - - os: macos-15-intel # intel: Sequoia - python: '3.13' - kind: pip - os: windows-latest python: '3.11' - kind: mamba - - os: ubuntu-latest - python: '3.12' - kind: minimal - - os: ubuntu-22.04 - python: '3.10' - kind: old + kind: pip steps: - uses: actions/checkout@v6 with: @@ -136,7 +115,7 @@ jobs: create-args: >- python=${{ env.PYTHON_VERSION }} -v - if: matrix.kind == 'conda' || matrix.kind == 'mamba' + if: matrix.kind == 'conda' timeout-minutes: 20 # Python (if old) - uses: astral-sh/setup-uv@v8.1.0 @@ -167,6 +146,8 @@ jobs: key: ${{ env.TESTING_VERSION }} path: ~/mne_data - run: bash ./tools/github_actions_download.sh + - run: pytest mne/viz -k test_brain_gc + - run: pytest mne/tests/test_surface.py -k cubes - run: bash ./tools/github_actions_test.sh # for some reason on macOS we need to run "bash X" in order for a failed test run to show up - uses: codecov/codecov-action@v6 with: diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 9b9168c3a26..51aa0312a59 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -15,7 +15,7 @@ elif [[ "$MNE_CI_KIND" == "old" ]]; then echo "MNE_IGNORE_WARNINGS_IN_TESTS=true" | tee -a $GITHUB_ENV echo "MNE_SKIP_NETWORK_TESTS=1" | tee -a $GITHUB_ENV echo "MNE_QT_BACKEND=PyQt5" | tee -a $GITHUB_ENV -elif [[ "$MNE_CI_KIND" == "conda" ]] || [[ "$MNE_CI_KIND" == "mamba" ]]; then +elif [[ "$MNE_CI_KIND" == "conda" ]]; then echo "Setting conda env vars for $MNE_CI_KIND" echo "CONDA_ENV=environment.yml" | tee -a $GITHUB_ENV echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index 25f46ebbfc2..6247a4b0da9 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -15,7 +15,7 @@ echo " \$(which python) == ${GOT_PYTHON}" echo " \$(python --version) == ${GOT_PYTHON_VERSION}" echo "for" echo " \$MNE_CI_KIND == ${MNE_CI_KIND}" -if [[ "${MNE_CI_KIND}" == "conda" ]] || [[ "${MNE_CI_KIND}" == "mamba" ]]; then +if [[ "${MNE_CI_KIND}" == "conda" ]]; then WANT="micromamba/envs/mne" elif [[ "${MNE_CI_KIND}" == "old" ]]; then WANT="mne-python/mne-python/.venv/bin" From 77fde19910435a3da1988edbdacdc4aecde72087 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 21:53:33 -0400 Subject: [PATCH 28/35] FIX: Check --- tools/github_actions_verify_python.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/github_actions_verify_python.sh b/tools/github_actions_verify_python.sh index 6247a4b0da9..c33a5cdec93 100755 --- a/tools/github_actions_verify_python.sh +++ b/tools/github_actions_verify_python.sh @@ -20,7 +20,7 @@ if [[ "${MNE_CI_KIND}" == "conda" ]]; then elif [[ "${MNE_CI_KIND}" == "old" ]]; then WANT="mne-python/mne-python/.venv/bin" elif [[ "${MNE_CI_KIND}" == "pip" ]] || [[ "${MNE_CI_KIND}" == "pip-pre" ]] || [[ "${MNE_CI_KIND}" == "minimal" ]]; then - WANT="hostedtoolcache/Python" + WANT="/hostedtoolcache/" else echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" exit 1 From add35b720edf6f1c22b83f92104005915a9118b3 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 22:04:24 -0400 Subject: [PATCH 29/35] FIX: More --- .github/workflows/tests.yml | 1 + tools/get_minimal_commands.sh | 1 - tools/github_actions_dependencies.sh | 9 +++++---- tools/github_actions_env_vars.sh | 6 ++++-- tools/github_actions_test.sh | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7aee9f2ceaa..84f97836405 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -128,6 +128,7 @@ jobs: if: matrix.kind == 'old' - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh + timeout-minutes: 5 - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' # Minimal commands on Linux (macOS stalls) diff --git a/tools/get_minimal_commands.sh b/tools/get_minimal_commands.sh index ff8ada7741d..1145ae5822c 100755 --- a/tools/get_minimal_commands.sh +++ b/tools/get_minimal_commands.sh @@ -79,4 +79,3 @@ which mne_surf2bem mne_surf2bem --version which mri_average mri_average --version -set +x diff --git a/tools/github_actions_dependencies.sh b/tools/github_actions_dependencies.sh index 7b00214d9ea..3ee5986cfa9 100755 --- a/tools/github_actions_dependencies.sh +++ b/tools/github_actions_dependencies.sh @@ -12,7 +12,7 @@ if [ ! -z "$CONDA_ENV" ]; then conda remove -c conda-forge --force -y mne-base echo "::endgroup::" # If not on windows, do a non-editable install - if [[ "${RUNNER_OS}" != "Windows" ]]; then + if [[ "${CI_OS_NAME}" != "windows"* ]]; then INSTALL_ARGS="" fi GROUP="test_extra" @@ -22,7 +22,7 @@ elif [[ "${MNE_CI_KIND}" == "minimal" ]]; then EXTRAS="" STD_ARGS="--progress-bar off ${MNE_QT_BACKEND}" echo "::group::Upgrading pip installation" - python -m pip install --upgrade pip # upgrade pip to support --group + python -m pip install --upgrade pip setuptools echo "::endgroup::" elif [[ "${MNE_CI_KIND}" == "old" ]]; then GROUP="" # group "test" already included when pylock file generated @@ -35,10 +35,12 @@ elif [[ "${MNE_CI_KIND}" == "old" ]]; then elif [[ "${MNE_CI_KIND}" == "pip" ]]; then GROUP="test_extra" EXTRAS="[full-pyside6]" + python -m pip install --upgrade pip setuptools else test "${MNE_CI_KIND}" == "pip-pre" + python -m pip install $STD_ARGS pip setuptools STD_ARGS="$STD_ARGS --pre" - ${SCRIPT_DIR}/install_pre_requirements.sh || exit 1 + ${SCRIPT_DIR}/install_pre_requirements.sh GROUP="test_extra" EXTRAS="" fi @@ -58,5 +60,4 @@ else fi set -x python -m pip install $STD_ARGS $ONLY_BINARY_ARG $INSTALL_ARGS .$EXTRAS $GROUP_ARG -set +x echo "::endgroup::" diff --git a/tools/github_actions_env_vars.sh b/tools/github_actions_env_vars.sh index 51aa0312a59..cf4d6eaa3c0 100755 --- a/tools/github_actions_env_vars.sh +++ b/tools/github_actions_env_vars.sh @@ -21,7 +21,7 @@ elif [[ "$MNE_CI_KIND" == "conda" ]]; then echo "MNE_LOGGING_LEVEL=warning" | tee -a $GITHUB_ENV echo "MNE_TEST_ALLOW_SKIP=.*(Requires (spm|brainstorm) dataset|CUDA not|PySide6 causes segfaults|Accelerate|Flakey verbose behavior).*" | tee -a $GITHUB_ENV # Our cache_dir test has problems when the path is too long, so prevent it from getting too long - if [[ "$RUNNER_OS" == "macOS" ]]; then + if [[ "$CI_OS_NAME" == "macos"* ]]; then echo "PYTEST_DEBUG_TEMPROOT=/tmp" | tee -a $GITHUB_ENV fi echo "MNE_QT_BACKEND=PySide6" | tee -a $GITHUB_ENV @@ -29,4 +29,6 @@ else echo "✕ ERROR: Unrecognized MNE_CI_KIND=${MNE_CI_KIND}" exit 1 fi -set +x +if [[ "$CI_OS_NAME" == "windows"* ]]; then + echo "MNE_IS_OSMESA=true" | tee -a $GITHUB_ENV +fi diff --git a/tools/github_actions_test.sh b/tools/github_actions_test.sh index d55613e97cc..ea4d783acea 100755 --- a/tools/github_actions_test.sh +++ b/tools/github_actions_test.sh @@ -23,7 +23,7 @@ else USE_DIRS="mne/" fi JUNIT_PATH="junit-results.xml" -if [[ ! -z "$CONDA_ENV" ]] && [[ "${RUNNER_OS}" != "Windows" ]] && [[ "${MNE_CI_KIND}" != "minimal" ]] && [[ "${MNE_CI_KIND}" != "old" ]]; then +if [[ ! -z "$CONDA_ENV" ]] && [[ "${CI_OS_NAME}" != "windows"* ]] && [[ "${MNE_CI_KIND}" != "minimal" ]] && [[ "${MNE_CI_KIND}" != "old" ]]; then PROJ_PATH="$(pwd)" JUNIT_PATH="$PROJ_PATH/${JUNIT_PATH}" # Use the installed version after adding all (excluded) test files From 3498aaeb0e08bcdac8bb83c39734c3d34c2cea03 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 22:11:17 -0400 Subject: [PATCH 30/35] FIX: Restore --- .github/workflows/tests.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 84f97836405..ad1cd0fc3bc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -67,9 +67,30 @@ jobs: fail-fast: false matrix: include: + - os: ubuntu-latest + python: '3.13' + kind: pip + - os: ubuntu-latest + python: '3.14' + kind: pip-pre + - os: ubuntu-latest + python: '3.13' + kind: conda + - os: macos-latest # arm64 (Apple Silicon): Sequoia + python: '3.14' + kind: pip + - os: macos-15-intel # intel: Sequoia + python: '3.13' + kind: pip - os: windows-latest python: '3.11' kind: pip + - os: ubuntu-latest + python: '3.12' + kind: minimal + - os: ubuntu-22.04 + python: '3.10' + kind: old steps: - uses: actions/checkout@v6 with: @@ -128,7 +149,7 @@ jobs: if: matrix.kind == 'old' - run: bash ./tools/github_actions_verify_python.sh "${{ matrix.python }}" - run: bash ./tools/github_actions_dependencies.sh - timeout-minutes: 5 + timeout-minutes: 10 - run: python ./tools/github_actions_check_old_env.py if: matrix.kind == 'old' # Minimal commands on Linux (macOS stalls) @@ -147,8 +168,6 @@ jobs: key: ${{ env.TESTING_VERSION }} path: ~/mne_data - run: bash ./tools/github_actions_download.sh - - run: pytest mne/viz -k test_brain_gc - - run: pytest mne/tests/test_surface.py -k cubes - run: bash ./tools/github_actions_test.sh # for some reason on macOS we need to run "bash X" in order for a failed test run to show up - uses: codecov/codecov-action@v6 with: From c5befee200f62adc4ecba0ba14aefcdc3b4788a6 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 23:04:18 -0400 Subject: [PATCH 31/35] FIX: Simplify --- .github/workflows/tests.yml | 7 ++----- mne/viz/tests/test_evoked.py | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ad1cd0fc3bc..b5a8386ccd5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -76,15 +76,12 @@ jobs: - os: ubuntu-latest python: '3.13' kind: conda - - os: macos-latest # arm64 (Apple Silicon): Sequoia + - os: macos-latest # arm64 python: '3.14' kind: pip - - os: macos-15-intel # intel: Sequoia + - os: macos-15-intel # Intel python: '3.13' kind: pip - - os: windows-latest - python: '3.11' - kind: pip - os: ubuntu-latest python: '3.12' kind: minimal diff --git a/mne/viz/tests/test_evoked.py b/mne/viz/tests/test_evoked.py index 9071bb8971c..c1e88acc1ef 100644 --- a/mne/viz/tests/test_evoked.py +++ b/mne/viz/tests/test_evoked.py @@ -373,6 +373,7 @@ def test_plot_white_rank(): evoked.plot_white(cov, rank=rank) +@pytest.mark.slowtest def test_plot_white(): """Test plot_white.""" cov = read_cov(cov_fname) From 0f960a985a7d59f7b24ef1d3bb8c7d9487a2f514 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 23:10:38 -0400 Subject: [PATCH 32/35] FIX: Names --- azure-pipelines.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3413eb5c391..5644f63759d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -82,7 +82,7 @@ stages: variables: AZURE_CI: 'true' jobs: - - job: Ultraslow_PG + - job: Linux_Ultraslow_PG pool: vmImage: 'ubuntu-22.04' variables: @@ -151,9 +151,9 @@ stages: inputs: summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - - job: Qt + - job: Linux_Qt_Bindings pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-24.04' variables: DISPLAY: ':99' OPENBLAS_NUM_THREADS: '1' @@ -250,9 +250,9 @@ stages: strategy: maxParallel: 4 matrix: - 3.10 pip: + 3.11 pip: TEST_MODE: 'pip' - PYTHON_VERSION: '3.10' + PYTHON_VERSION: '3.11' 3.13 pip pre: TEST_MODE: 'pip-pre' PYTHON_VERSION: '3.13' From e5effb4769268849bfc15afb15dbb5fd1851606a Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 23:12:42 -0400 Subject: [PATCH 33/35] FIX: Clean --- azure-pipelines.yml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5644f63759d..f74d11e06c8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -141,15 +141,6 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - job: Linux_Qt_Bindings pool: @@ -223,15 +214,6 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' - job: Windows pool: @@ -292,12 +274,3 @@ stages: - bash: bash <(curl -s https://codecov.io/bash) displayName: 'Codecov' condition: succeededOrFailed() - - task: PublishTestResults@2 - inputs: - testResultsFiles: '**/junit-*.xml' - testRunTitle: 'Publish test results for $(Agent.JobName) $(TEST_MODE) $(PYTHON_VERSION)' - failTaskOnFailedTests: true - condition: succeededOrFailed() - - task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' From 629329cb7e97ac021d2fcb3ec503cf25ad547040 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 23:15:26 -0400 Subject: [PATCH 34/35] FIX: Ubuntu --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f74d11e06c8..709d526ed12 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -84,7 +84,7 @@ stages: jobs: - job: Linux_Ultraslow_PG pool: - vmImage: 'ubuntu-22.04' + vmImage: 'ubuntu-latest' variables: DISPLAY: ':99' OPENBLAS_NUM_THREADS: '1' @@ -144,7 +144,7 @@ stages: - job: Linux_Qt_Bindings pool: - vmImage: 'ubuntu-24.04' + vmImage: 'ubuntu-latest' variables: DISPLAY: ':99' OPENBLAS_NUM_THREADS: '1' From 22f29d7b783f8b336576126e8e2d7ba8cdfcab19 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Fri, 1 May 2026 23:16:56 -0400 Subject: [PATCH 35/35] Bash --- azure-pipelines.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 709d526ed12..3802be37719 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -93,7 +93,7 @@ stages: MNE_BROWSER_PRECOMPUTE: 'false' steps: - bash: | - set -e + set -eo pipefail ./tools/setup_xvfb.sh sudo apt install -yq tcsh displayName: 'Install Ubuntu dependencies' @@ -112,19 +112,19 @@ stages: addToPath: true displayName: 'Get Python' - bash: | - set -e + set -eo pipefail python -m pip install --progress-bar off --upgrade pip python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git" pyvista scikit-learn python-picard qtpy nibabel sphinx-gallery "PySide6!=6.8.0,!=6.8.0.1,!=6.8.1.1,!=6.9.1" pandas neo pymatreader antio defusedxml curryreader pymef python -m pip uninstall -yq mne python -m pip install --progress-bar off --upgrade -e . --group=test displayName: 'Install dependencies with pip' - bash: | - set -e + set -eo pipefail mne sys_info -pd mne sys_info -pd | grep "qtpy .*(PySide6=.*)$" displayName: Print config - bash: | - set -e + set -eo pipefail LD_DEBUG=libs python -c "from PySide6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()" - bash: source tools/get_testing_version.sh displayName: 'Get testing version' @@ -160,7 +160,7 @@ stages: addToPath: true displayName: 'Get Python' - bash: | - set -e + set -eo pipefail python -m pip install --progress-bar off --upgrade pip python -m pip install --progress-bar off --upgrade --pre --only-binary=\"numpy,scipy,matplotlib,vtk\" numpy scipy matplotlib vtk python -c "import vtk"