Skip to content

Port OME-Zarr and SmartSPIM readers from MATLAB to Python #51

Port OME-Zarr and SmartSPIM readers from MATLAB to Python

Port OME-Zarr and SmartSPIM readers from MATLAB to Python #51

Workflow file for this run

name: CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install black ruff
- name: Check formatting with black
run: black --check src/ tests/
- name: Lint with ruff
run: ruff check src/ tests/
bridge:
name: MATLAB/Python bridge completeness
runs-on: ubuntu-latest
steps:
# Two checkouts, laid out as siblings, because the check compares
# NDR-matlab's +ndr tree against this repo's bridge YAMLs.
# No MATLAB runtime is needed -- it only reads the source tree --
# so this stays a fast job rather than joining the format-heavy
# test matrix. Mirrors NDI-python's ``bridge`` job by design.
- uses: actions/checkout@v4
with:
path: NDR-python
- name: Check out NDR-matlab (matching branch, fall back to main)
uses: actions/checkout@v4
with:
repository: VH-Lab/NDR-matlab
# A bridge entry usually lands on the same feature branch as
# the MATLAB function it records, so check that branch first.
ref: ${{ github.head_ref || github.ref_name }}
# fetch-depth: 0 so the hash-currency test can walk history
# for every file: without it `git log -- <path>` sees only the
# last commit and every recorded hash looks stale.
fetch-depth: 0
path: NDR-matlab
continue-on-error: true
id: matlab_checkout_branch
- name: Check out NDR-matlab (main fallback)
if: steps.matlab_checkout_branch.outcome == 'failure'
uses: actions/checkout@v4
with:
repository: VH-Lab/NDR-matlab
ref: main
fetch-depth: 0
path: NDR-matlab
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pytest and PyYAML
run: |
python -m pip install --upgrade pip
pip install pytest pyyaml
- name: Check bridge completeness and hash currency
working-directory: NDR-python
env:
# Both repos are checked out above, so an absent MATLAB tree
# means the checkout step broke. Fail instead of skipping --
# a check that could not run must not report a pass.
NDR_BRIDGE_CHECK_STRICT: "1"
NDR_MATLAB_PATH: ${{ github.workspace }}/NDR-matlab
run: pytest tests/test_matlab_bridge_completeness.py -v --tb=short
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install package with dev and formats dependencies
# The formats extra carries neo, pyabf, tdt, tifffile and scipy.
# Without it the reader tests raise ImportError and pass as skips,
# so the readers they cover are never actually exercised.
run: pip install -e ".[dev,formats]"
- name: Run tests
run: pytest tests/ src/ndr/test/ -v --tb=short
ced-integration:
name: CED integration (real sonpipe)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# CED ships sonpy only for CPython 3.14 on Linux, so the real CLI
# cannot run on the main test matrix. This job is the one place the
# CED reader is exercised end-to-end against a real .smr file; the
# stand-in CLI in tests/test_ced_sonpipe.py covers the bridge itself
# on every supported version.
python-version: "3.14"
- name: Install package with dev and ced dependencies
# The [ced] extra pulls sonpipe from its git URL. Same install as
# `python -m ndr.setup.sonpipe`; downstream packages (NDI-python) use
# the module entry point in their own CI so they don't have to know
# the git URL themselves.
run: pip install -e ".[dev,ced]"
- name: Verify sonpipe and sonpy are usable
# Ask sonpipe where SonFile lives rather than hardcoding a layout. CED
# packages sonpy three different ways depending on wheel and version --
# sonpy.SonFile, sonpy.sonpy.SonFile, sonpy.lib.SonFile -- and
# sonpipe.sonfile.load_sonpy already resolves all three. Naming one
# directly here is how this step failed the first time.
run: |
sonpipe --version
python -c "from sonpipe.sonfile import load_sonpy; m = load_sonpy(); assert hasattr(m, 'SonFile'); print('sonpy OK via', m.__name__)"
- name: Run the CED format tests against the real CLI
# NDR_REQUIRE_SONPIPE turns the usual skip into a failure, so this job
# cannot pass by quietly reading nothing.
env:
NDR_REQUIRE_SONPIPE: "1"
run: pytest src/ndr/test/format/ced/ tests/test_ced_sonpipe.py -v --tb=short