ci: real-data fixture + matlab tests on github actions#30
Merged
Conversation
Adds a small (2.3 MB) BIDS-EEG fixture and a GitHub Actions workflow so the MATLAB test suite runs on every push/PR, not only locally on the maintainer's /Volumes mount. Implements issue #11 plus the practicum brief's Week-4 CI scope. Fixture (tests/fixtures/bids_mini/) - Real 60 s slice of sub-NDARAA948VFH ThePresent from the HBN R3 100 Hz local dataset. No synthesis, no resampling. - Built by scripts/build_test_fixture.m (deterministic, idempotent). - Includes both subject-level and root-level BIDS sidecars; the latter carries Manufacturer / ManufacturersModelName that EEGLAB needs to auto-look-up GSN HydroCel 129 channel locations. Without it, clean_rawdata falls into a location-free path that errors at srate < 110 Hz. - License CC-BY-SA 4.0 inherited from HBN-EEG. CI workflow (.github/workflows/matlab-tests.yml) - matlab-actions/setup-matlab @ R2024a. - EEGLAB pinned to tagged release 2026.0.0, cloned with --recurse-submodules so EEG-BIDS, clean_rawdata, ICLabel, dipfit, firfilt come along. Cache keyed on the tag. - Biosig auto-installed via EEGLAB plugin_askinstall on first run. - Runs tests/matlab/run_all_tests.m against the fixture. Test refactor - tests/matlab/test_bids_root.m: resolver helper. Tries HBN_BIDS_ROOT, then tests/fixtures/bids_mini, then /Volumes/... - test_phase1_no_subjects.m, test_phase1_smoke.m: use the resolver. Pre-commit: end-of-file-fixer, trailing-whitespace, mixed-line-ending, typos all skip tests/fixtures/. mixed-line-ending also skips binary EEG. Misc: lint.yml drops the develop branch trigger; logs/ added to .gitignore; local_ci.sh falls back to the fixture when BIDS_ROOT unset. All 4 tests pass locally against the fixture (clean_rawdata removes 11 channels on the 60 s slice vs 6 on the full 210 s recording for the same subject; different statistics, both correct). Closes #11. Refs #1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a small (2.3 MB) BIDS-EEG fixture and a GitHub Actions workflow so the MATLAB test suite runs on every push and PR, not only locally on the maintainer's
/Volumesmount. Implements issue #11 plus the practicum brief's Week-4 CI scope that we had been deferring.Why now: PR #29 just landed the Phase 1 derivatives without CI coverage. Before Phase 2 (AMICA), the test infrastructure should be in place so new code is covered from day one.
Fixture
tests/fixtures/bids_mini/— real 60 s slice ofsub-NDARAA948VFH'sThePresentrecording from the HBN R3 100 Hz local dataset. No synthesis, no resampling.scripts/build_test_fixture.m(deterministic, idempotent; re-runs from the same/Volumessource produce byte-identical output for the JSON/TSV sidecars).task-ThePresent_eeg.jsonis the key one: it hasManufacturer/ManufacturersModelNamethat EEGLAB uses to auto-look-up the GSN HydroCel 129 channel locations. Without it,clean_rawdatafalls into a location-free path that errors atsrate < 110 Hzon our 100 Hz data.dataset_description.json+README).CI workflow
.github/workflows/matlab-tests.yml:matlab-actions/setup-matlab@v2on R2024a (same release as the existingcheckcodejob).2026.0.0, cloned with--recurse-submodulessoEEG-BIDS,clean_rawdata,ICLabel,dipfit,firfiltcome along automatically. Cache keyed on the tag so a version bump invalidates cleanly.plugin_askinstallon first run (not a submodule; needed for BDF I/O).tests/matlab/run_all_tests.magainst the fixture viaHBN_BIDS_ROOT.Test refactor
tests/matlab/test_bids_root.m: new resolver helper. TriesHBN_BIDS_ROOT, thentests/fixtures/bids_mini, then/Volumes/.... Errors with a precise message if none resolve, so a CI failure surfaces "no fixture" rather than disguising itself as a phase1 error.test_phase1_no_subjects.m,test_phase1_smoke.m: drop the hardcoded/Volumespath; use the resolver.Local CI
scripts/local_ci.shfalls back to the fixture whenBIDS_ROOTis unset, so a clean checkout works without the maintainer's/Volumesmount.HBN_BIDS_ROOTso the shell and the in-MATLAB resolver agree.Pre-commit changes
The fixture mirrors upstream HBN sidecars byte-for-byte. Several hooks were rewriting them or flagging upstream artifacts:
mixed-line-ending: was treating the binary BDF as text and corrupting it. Now skipsBDF/EDF/SET/FDT/MAT.end-of-file-fixer,trailing-whitespace: now skiptests/fixtures/.typos: now skipstests/fixtures/so upstream spelling artifacts inparticipants.jsondon't fail CI.Misc
.github/workflows/lint.yml: drops the staledevelopbranch trigger (main-only now).logs/added to.gitignore(transient MATLAB batch logs from local runs).Local verification
All 4 tests pass against the fixture:
clean_rawdataon the 60 s slice removes 11 channels (vs 6 on the full 210 s recording for the same subject); different rejection statistics on different-length windows, both correct. The smoke test asserts that at least one channel is rejected and that the checkpoint round-trips with matchingnbchan/srate, so a no-op rejector cannot silently pass.Test plan
run_all_testsgreen againstHBN_BIDS_ROOT=tests/fixtures/bids_mini.run_all_testsgreen against the full/Volumesdataset (regression check).Closes #11.
Refs #1.