Skip to content

MAINT: Restore Python 3.11 support #100

MAINT: Restore Python 3.11 support

MAINT: Restore Python 3.11 support #100

Workflow file for this run

name: Tests
on: # yamllint disable-line rule:truthy
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "17 5 * * 1"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lint:
name: Lint
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --group lint
- name: Run repository checks
run: spin lint
base-install:
name: Base install / Python 3.11
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
- name: Validate base installation
run: |
base_python="$RUNNER_TEMP/mne-denoise-base/bin/python"
python -m venv "$RUNNER_TEMP/mne-denoise-base"
"$base_python" -m pip install --upgrade pip
"$base_python" -m pip install -e .
"$base_python" -m pip check
"$base_python" scripts/check_base_install.py
- name: Display environment information
run: |
base_python="$RUNNER_TEMP/mne-denoise-base/bin/python"
"$base_python" --version
"$base_python" - <<'PY'
from importlib.metadata import version
for package in ("mne-denoise", "numpy", "scipy", "scikit-learn", "joblib"):
print(package, version(package))
PY
lower-bound-base:
name: Lower bound / base dependencies
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
version: ">=0.9"
python-version: "3.11"
activate-environment: true
cache-dependency-glob: |
pyproject.toml
tools/pylock.ci-min-base.toml
- name: Install shared lockfile checker
run: >-
uv pip install
"mne-tools @ git+https://github.com/mne-tools/mne-tools.git@2e7c4b5469ef311a169e16c7f97cd0ce68508a61"
- name: Validate base lower-bound lockfile
run: |
python -m mne_tools.check_lockfile \
"$GITHUB_WORKSPACE" \
tools/pylock.ci-min-base.toml \
--groups lockfile_base
- name: Restore lower-bound Python environment
run: |
base_env="$RUNNER_TEMP/mne-denoise-lower-bound-base"
uv venv --python 3.11 "$base_env"
echo "MNE_DENOISE_BASE_ENV=$base_env" >> "$GITHUB_ENV"
- name: Install lower-bound environment
run: |
base_python="$MNE_DENOISE_BASE_ENV/bin/python"
uv pip sync --python "$base_python" tools/pylock.ci-min-base.toml
uv pip install --python "$base_python" pip \
"mne-tools @ git+https://github.com/mne-tools/mne-tools.git@2e7c4b5469ef311a169e16c7f97cd0ce68508a61"
uv pip install --python "$base_python" -e . --no-deps
- name: Check declared lower bounds
run: |
base_python="$MNE_DENOISE_BASE_ENV/bin/python"
"$base_python" -m mne_tools.check_environment \
"$GITHUB_WORKSPACE" \
--groups lockfile_base
- name: Check base installation boundary
run: >-
"$MNE_DENOISE_BASE_ENV/bin/python" scripts/check_base_install.py
- name: Display environment information
run: |
base_python="$MNE_DENOISE_BASE_ENV/bin/python"
"$base_python" --version
"$base_python" - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
):
print(package, version(package))
PY
- name: Check installed requirements
run: >-
"$MNE_DENOISE_BASE_ENV/bin/python" -m pip check
mne-minimum:
name: MNE-Python 1.13.0 minimum integration
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
cache: pip
- name: Install MNE-Python minimum test environment
run: |
python -m pip install --upgrade pip
python -m pip install -e . --group test "mne==1.13.0"
- name: Verify MNE-Python minimum version
run: |
python - <<'PY'
from importlib.metadata import version
installed = version("mne")
if installed != "1.13.0":
raise SystemExit(f"expected MNE-Python 1.13.0, found {installed}")
print("MNE-Python:", installed)
PY
- name: Display environment information
run: |
python --version
python - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
"mne",
"matplotlib",
"seaborn",
"tqdm",
):
print(package, version(package))
PY
- name: Check installed requirements
run: python -m pip check
- name: Run full test suite
run: pytest -q
lower-bound-extras:
name: Lower bound / standalone extras
if: github.event_name != 'schedule'
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
version: ">=0.9"
python-version: "3.11"
activate-environment: true
cache-dependency-glob: |
pyproject.toml
tools/pylock.ci-min-extras.toml
- name: Install shared lockfile checker
run: >-
uv pip install
"mne-tools @ git+https://github.com/mne-tools/mne-tools.git@2e7c4b5469ef311a169e16c7f97cd0ce68508a61"
- name: Validate standalone extras lower-bound lockfile
run: |
python -m mne_tools.check_lockfile \
"$GITHUB_WORKSPACE" \
tools/pylock.ci-min-extras.toml \
--groups lockfile_extras
- name: Restore lower-bound Python environment
run: |
extras_env="$RUNNER_TEMP/mne-denoise-lower-bound-extras"
uv venv --python 3.11 "$extras_env"
echo "MNE_DENOISE_EXTRAS_ENV=$extras_env" >> "$GITHUB_ENV"
- name: Install lower-bound environment
run: |
extras_python="$MNE_DENOISE_EXTRAS_ENV/bin/python"
uv pip sync --python "$extras_python" tools/pylock.ci-min-extras.toml
uv pip install --python "$extras_python" pip \
"mne-tools @ git+https://github.com/mne-tools/mne-tools.git@2e7c4b5469ef311a169e16c7f97cd0ce68508a61"
uv pip install --python "$extras_python" -e . --no-deps
- name: Check declared lower bounds
run: |
extras_python="$MNE_DENOISE_EXTRAS_ENV/bin/python"
"$extras_python" -m mne_tools.check_environment \
"$GITHUB_WORKSPACE" --groups lockfile_extras
- name: Verify MNE-Python remains optional
run: |
"$MNE_DENOISE_EXTRAS_ENV/bin/python" - <<'PY'
from importlib.util import find_spec
if find_spec("mne") is not None:
raise SystemExit(
"MNE-Python leaked into the standalone extras lower-bound environment"
)
PY
- name: Display environment information
run: |
extras_python="$MNE_DENOISE_EXTRAS_ENV/bin/python"
"$extras_python" --version
"$extras_python" - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
"matplotlib",
"seaborn",
"tqdm",
):
print(package, version(package))
PY
- name: Check installed requirements
run: >-
"$MNE_DENOISE_EXTRAS_ENV/bin/python" -m pip check
- name: Run standalone public API smoke
run: |
extras_python="$MNE_DENOISE_EXTRAS_ENV/bin/python"
MPLBACKEND=Agg "$extras_python" - <<'PY'
import matplotlib.pyplot as plt
from mne_denoise.progress import TqdmProgress
from mne_denoise.viz import plot_metric_violins
data = {
"subject": ["s1", "s1", "s2", "s2"],
"group": ["a", "a", "b", "b"],
"metric": [1.0, 2.0, 3.0, 4.0],
}
fig = plot_metric_violins(data, ["metric"], show=False)
plt.close(fig)
progress = TqdmProgress(disable=True)
progress.close()
PY
stable:
name: ${{ matrix.name }}
if: github.event_name != 'schedule'
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
python-version: "3.12"
name: Python 3.12
coverage: "false"
- os: ubuntu-latest
python-version: "3.13"
name: Python 3.13
coverage: "false"
- os: ubuntu-latest
python-version: "3.14"
name: Latest / Python 3.14
coverage: "true"
- os: windows-latest
python-version: "3.14"
name: Windows / Python 3.14
coverage: "false"
- os: macos-latest
python-version: "3.14"
name: macOS ARM / Python 3.14
coverage: "false"
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install stable test environment
run: |
python -m pip install --upgrade pip
python -m pip install -e . --group test
- name: Verify macOS ARM runner
if: matrix.name == 'macOS ARM / Python 3.14'
run: |
python - <<'PY'
import platform
print("machine:", platform.machine())
print("platform:", platform.platform())
if platform.machine() != "arm64":
raise SystemExit("macOS compatibility job is not running on arm64")
PY
- name: Display environment information
run: |
python --version
python - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
"mne",
"matplotlib",
"seaborn",
"tqdm",
):
print(package, version(package))
PY
- name: Check installed requirements
run: python -m pip check
- name: Run tests
if: matrix.coverage == 'false'
run: pytest -q
- name: Run tests with coverage
if: matrix.coverage == 'true'
run: pytest --cov=mne_denoise --cov-report=xml -q
- name: Upload coverage to Codecov
if: matrix.coverage == 'true'
uses: codecov/codecov-action@0b35c9ecc4f0529d0eb674914510c22f85b196b4 # v7.1.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
flags: unittests
fail_ci_if_error: false
mne-main:
name: MNE main
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install stable mne-denoise test environment
run: |
python -m pip install --upgrade pip
python -m pip install -e . --group test
python -c "import mne; print(mne.__version__)" > "$RUNNER_TEMP/mne-stable-version"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: mne-tools/mne-python
path: .ci/mne-python
fetch-depth: 0
persist-credentials: false
- name: Install MNE-Python main
run: python -m pip install --upgrade ./.ci/mne-python
- name: Verify MNE-Python main installation
run: |
git -C .ci/mne-python rev-parse HEAD
python - <<'PY'
import os
from importlib.metadata import version
import mne
stable_version = open(
os.path.join(os.environ["RUNNER_TEMP"], "mne-stable-version"),
encoding="utf-8",
).read().strip()
print("mne.__version__:", mne.__version__)
print("mne metadata:", version("mne"))
print("mne path:", mne.__file__)
if mne.__version__ == stable_version:
raise SystemExit("MNE main installation did not replace stable MNE")
PY
- name: Display environment information
run: |
python --version
echo "MNE git SHA: $(git -C .ci/mne-python rev-parse HEAD)"
python - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
"mne",
"matplotlib",
"seaborn",
"tqdm",
):
print(package, version(package))
PY
- name: Check installed requirements
run: python -m pip check
- name: Run tests
run: pytest -q
prerelease:
name: Prerelease dependencies
continue-on-error: true
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
- name: Install stable test environment
run: |
python -m pip install --upgrade pip
python -m pip install -e . --group test
- name: Upgrade scientific dependencies to prereleases
run: |
python -m pip install --upgrade --pre \
numpy scipy scikit-learn joblib matplotlib seaborn tqdm
- name: Display environment information
run: |
python --version
python - <<'PY'
from importlib.metadata import version
for package in (
"mne-denoise",
"numpy",
"scipy",
"scikit-learn",
"joblib",
"mne",
"matplotlib",
"seaborn",
"tqdm",
):
print(package, version(package))
PY
- name: Check installed requirements
run: python -m pip check
- name: Run tests
run: pytest -q