Skip to content

Commit 641d268

Browse files
ENH: Add JupyterLite sphinx integration and CI/CD infrastructure
Integrates jupyterlite-sphinx into the MNE-Python doc build so every sphinx-gallery example gets a 'Try in Browser' button backed by a Pyodide/WebAssembly kernel. - doc/conf.py: configure jupyterlite_sphinx; build a local MNE dev wheel with relaxed Pyodide constraints; copy required MNE sample-data subset into JupyterLite's virtual filesystem; inject a setup cell that installs MNE via micropip (keep_going=True bypasses version conflicts), mocks missing stdlib modules (lzma, multiprocessing), patches pooch to block large OSF downloads, and sets MNE_DATA paths - .circleci/config.yml: ensure MNE sample data is on disk before the doc build so conf.py can copy it into jupyterlite_contents/ - .github/workflows/jupyterlite.yml: standalone GH Actions workflow on the jupyterlite-gh-actions branch that builds and uploads the site - pyproject.toml: add jupyterlite-pyodide-kernel and jupyterlite-sphinx to the [doc] extras - .gitignore: exclude jupyterlite_contents build artifacts
1 parent 3b3f3af commit 641d268

7 files changed

Lines changed: 415 additions & 327 deletions

File tree

.circleci/config.yml

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ _check_skip: &check_skip
2121
circleci-agent step halt;
2222
fi
2323
24+
_machine_image: &machine_image
25+
image: ubuntu-2604:2026.05.1
26+
2427
jobs:
2528
build_docs:
2629
parameters:
2730
scheduled:
2831
type: string
2932
default: "false"
3033
machine:
31-
image: ubuntu-2404:current
34+
<<: *machine_image
3235
# large 4 vCPUs 15GB mem
3336
# https://discuss.circleci.com/t/changes-to-remote-docker-reporting-pricing/47759
3437
resource_class: large
@@ -62,6 +65,9 @@ jobs:
6265
if [[ $(cat merge.txt) != "" ]]; then
6366
echo "Merging $(cat merge.txt)";
6467
git pull --ff-only upstream "refs/pull/$(cat merge.txt)/merge";
68+
elif [[ "$CIRCLE_PROJECT_USERNAME" != "mne-tools" ]]; then
69+
echo "On CIRCLE_PROJECT_USERNAME=\"$CIRCLE_PROJECT_USERNAME\" repo rather than mne-tools, merging upstream/main."
70+
git merge upstream/main --no-edit || exit 1
6571
else
6672
if [[ "$CIRCLE_BRANCH" == "main" ]]; then
6773
KIND=dev
@@ -107,7 +113,7 @@ jobs:
107113
# Load pip cache
108114
- restore_cache:
109115
keys:
110-
- pip-cache-0
116+
- pip-cache-1
111117
- restore_cache:
112118
keys:
113119
- user-install-bin-cache-310
@@ -119,7 +125,7 @@ jobs:
119125
./tools/circleci_dependencies.sh
120126
121127
- save_cache:
122-
key: pip-cache-0
128+
key: pip-cache-1
123129
paths:
124130
- ~/.cache/pip
125131
- save_cache:
@@ -219,7 +225,7 @@ jobs:
219225
keys:
220226
- data-cache-ds004388
221227
- run:
222-
name: Get data
228+
name: Get data and triage examples to run
223229
# This limit could be increased, but this is helpful for finding slow ones
224230
# (even ~2GB datasets should be downloadable in this time from good
225231
# providers)
@@ -243,6 +249,16 @@ jobs:
243249
cp junit-results.xml doc/_build/test-results/test-doc/junit.xml;
244250
cp coverage.xml doc/_build/test-results/test-doc/coverage.xml;
245251
fi;
252+
# Ensure the MNE sample dataset is on disk so conf.py can copy the
253+
# required subset into jupyterlite_contents/ for the JupyterLite build.
254+
# circleci_download.sh only fetches sample data when the changed files
255+
# reference it, so a cache miss on a PR that touches only doc/conf.py
256+
# would leave ~/mne_data/MNE-sample-data absent and the notebooks would
257+
# fail at runtime with FileNotFoundError on /drive/mne_data.
258+
- run:
259+
name: Ensure MNE sample data for JupyterLite
260+
command: |
261+
python -c "import mne; mne.datasets.sample.data_path(update_path=True)"
246262
# Build docs
247263
- run:
248264
name: make html
@@ -416,7 +432,7 @@ jobs:
416432
type: string
417433
default: "false"
418434
machine:
419-
image: ubuntu-2404:current
435+
<<: *machine_image
420436
resource_class: large
421437
steps:
422438
- restore_cache:
@@ -436,7 +452,7 @@ jobs:
436452
command: ./tools/circleci_bash_env.sh
437453
- restore_cache:
438454
keys:
439-
- pip-cache-0
455+
- pip-cache-1
440456
- run:
441457
name: Get Python running
442458
command: |
@@ -457,7 +473,7 @@ jobs:
457473

458474
deploy:
459475
machine:
460-
image: ubuntu-2404:current
476+
<<: *machine_image
461477
steps:
462478
- attach_workspace:
463479
at: /tmp/build

.github/workflows/jupyterlite.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Build JupyterLite
2+
3+
on: # yamllint disable-line rule:truthy
4+
push:
5+
branches:
6+
- jupyterlite-gh-actions
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
build:
13+
name: Build JupyterLite Site
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
with:
19+
persist-credentials: false
20+
21+
- name: Setup Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.11'
25+
26+
- name: Install JupyterLite & Build Tools
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install jupyterlite-core jupyterlite-pyodide-kernel build jupyter-server
30+
31+
- name: Build MNE-Python Wheel
32+
run: |
33+
python -m build --wheel
34+
mkdir -p lite-wheels
35+
cp dist/*.whl lite-wheels/
36+
37+
- name: Build JupyterLite Site
38+
# We pass the local wheel to JupyterLite so the browser environment uses the exact code from this branch!
39+
run: |
40+
jupyter lite build --contents examples/ --output-dir dist_lite/ --piplite-wheel lite-wheels/*.whl
41+
42+
- name: Upload Artifact
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: jupyterlite-build
46+
path: dist_lite/

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ tags
7474
/doc/fil-result
7575
/doc/optipng.exe
7676
/doc/sphinxext/.joblib
77+
/doc/code_credit.inc
7778
sg_execution_times.rst
7879
sg_api_usage.rst
7980
sg_api_unused.dot
@@ -102,3 +103,5 @@ venv/
102103
.hypothesis/
103104
.ruff_cache/
104105
.ipynb_checkpoints/
106+
jupyterlite_contents/auto_tutorials
107+
jupyterlite_contents/mne_data
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added a JupyterLite GitHub Actions workflow to automatically build a Wasm-compatible interactive documentation site by Natneal Belete.

0 commit comments

Comments
 (0)