Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
34 changes: 34 additions & 0 deletions .github/workflows/create-tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Create tag from new version

on:
workflow_dispatch:
workflow_call:
push:
branches:
- main
paths:
- fieldtrip/_version.py

permissions:
contents: write

jobs:
setup-tag:
runs-on: "ubuntu-latest"
steps:
- name: Check out FieldTrip Python
uses: actions/checkout@v4

- name: Get package version
run: |
VERSION=$(sed -n 's/^__version__ = "\(.*\)"/\1/p' fieldtrip/_version.py)
echo "pyproject.toml version: $VERSION"
git config user.name github-actions
git config user.email [email protected]
MSG=$(git log $(git describe --tags --abbrev=0)..HEAD --oneline)
echo "Creating tag $VERSION with message:"
echo "$MSG"
git tag -a "$VERSION" -m "$MSG"

- name: Publish tags
run: git push --tags
153 changes: 153 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: Upload and Publish Python Package
on:
workflow_run:
workflows: ["run_unit_tests"]
types:
- completed
workflow_dispatch:

env:
PYTHON_VERSION: "3.13"

jobs:
check-tag:
name: Check if commit is a tag
if: >
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
outputs:
is_tagged: ${{ steps.check-tag.outputs.is_tagged }}
tag_name: ${{ steps.check-tag.outputs.tag_name }}
is_prerelease: ${{ steps.check-tag.outputs.is_prerelease }}
steps:
- name: Checkout full history
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Determine tagged commit and pre-release
id: check-tag
run: |
TAG=$(git tag --points-at HEAD | head -n 1)
echo "Found tag: $TAG"
if [[ "$TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
echo "is_tagged=true" >> $GITHUB_OUTPUT
echo "tag_name=$TAG" >> $GITHUB_OUTPUT

if [[ "$TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+[a-zA-Z].*$ ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
fi
else
echo "is_tagged=false" >> $GITHUB_OUTPUT
fi

build:
name: Build Package
needs: check-tag
if: needs.check-tag.outputs.is_tagged == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build

- name: Build sdist and wheel
run: python -m build

- name: Upload built packages
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

publish-to-testpypi:
name: Publish to TestPyPI
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

test-install:
name: Test Install from TestPyPI
needs: publish-to-testpypi
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Test install from TestPyPI
run: |
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple fieldtrip-python
python -c "import fieldtrip"

publish-to-pypi:
name: Publish to PyPI
needs: test-install
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/fieldtrip-python/
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

sign-and-release:
name: Sign and Create GitHub Release
needs: [check-tag, publish-to-pypi]
if: needs.check-tag.outputs.is_tagged == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Sign with Sigstore
uses: sigstore/[email protected]
with:
inputs: >-
dist/*.tar.gz
dist/*.whl

- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "${{ needs.check-tag.outputs.tag_name }}" \
--repo "$GITHUB_REPOSITORY" \
--generate-notes \
$([[ "${{ needs.check-tag.outputs.is_prerelease }}" == "true" ]] && echo "--prerelease") \
dist/*
128 changes: 128 additions & 0 deletions .github/workflows/run_unit_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Unit tests
on:
workflow_dispatch:
workflow_call:
push:
paths:
- tests/**
- fieldtrip/**
- setup.py
- pyproject.toml
pull_request:

env:
MLM_LICENSE_TOKEN: ${{ secrets.MATLAB_BATCH_TOKEN }}

jobs:
run-unit-tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: False
matrix:
matlab: ["R2025b"]
os: [ubuntu-latest, macos-13, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13"]
include:
- os: ubuntu-latest
os_name: Linux
platform: Linux
- os: macos-13
os_name: macOS_Intel
platform: Mac
- os: macos-latest
os_name: macOS_Apple_Silicon
platform: Mac
- os: windows-latest
os_name: Windows
platform: Windows

steps:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install FieldTrip Python from latest Release (to get CTF file)
run: |
python -m pip install https://github.com/johmedr/fieldtrip-python/releases/latest/download/fieldtrip_python-20241219b1-py3-none-any.whl

- name: Check out FieldTrip Python
uses: actions/checkout@v4

# Setup MATLAB and Runtime
- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v2
with:
release: ${{matrix.matlab}}
cache: True
products: |
MATLAB_Compiler
MATLAB_Compiler_SDK

- name: Extract MATLAB path to file
uses: matlab-actions/run-command@v2
with:
command: |
fileID = fopen('matlab_path.txt', 'w');
matlabpath = matlabroot;
matlabpath = strrep(matlabpath, filesep, '/');
matlabpath = strrep(matlabpath, '\', '\\');
matlabpath = strrep(matlabpath, 'C:', '/c/');
matlabpath = strrep(matlabpath, 'D:', '/d/');
fprintf(fileID, matlabpath);
fclose(fileID);
# sometimes this step hangs when closing matlab, automatically terminating after 2 minutes solves the issue
timeout-minutes: 2
continue-on-error: true

- name: Set environment variable with MATLAB path
shell: bash # Works on Windows as well because of shell: bash
run: |
matlab_path=$(cat matlab_path.txt)
echo "MATLAB_PATH=$matlab_path" >> $GITHUB_ENV

- name: Run tests (Mac Apple Silicon)
if: matrix.os_name == 'macOS_Apple_Silicon'
run: |
export DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH:+${DYLD_LIBRARY_PATH}:}\
${{ env.MATLAB_PATH }}/runtime/maca64:\
${{ env.MATLAB_PATH }}/bin/maca64:\
${{ env.MATLAB_PATH }}/sys/os/maca64:\
${{ env.MATLAB_PATH }}/extern/bin/maca64"
export PYTHONHOME=${{ env.pythonLocation }}
mwpython -m unittest discover tests -v

- name: Run tests (Mac Intel)
if: matrix.os_name == 'macOS_Intel'
run: |
export DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH:+${DYLD_LIBRARY_PATH}:}\
${{ env.MATLAB_PATH }}/runtime/maci64:\
${{ env.MATLAB_PATH }}/bin/maci64:\
${{ env.MATLAB_PATH }}/sys/os/maci64:\
${{ env.MATLAB_PATH }}/extern/bin/maci64"
export PYTHONHOME=${{ env.pythonLocation }}
mwpython -m unittest discover tests -v

- name: Run tests (Windows)
if: matrix.os_name == 'Windows'
shell: bash
run: |
export PATH="${{ env.MATLAB_PATH }}/runtime/win64:\
${{ env.MATLAB_PATH }}/bin/win64:\
${{ env.MATLAB_PATH }}/sys/os/win64:\
${{ env.MATLAB_PATH }}/extern/bin/win64\
${{ env.MATLAB_PATH }}/runtime/win32:\
${{ env.MATLAB_PATH }}/bin/win32:\
${{ env.MATLAB_PATH }}/sys/os/win32:\
${{ env.MATLAB_PATH }}/extern/bin/win32:${PATH}"
python -m unittest discover tests -v

- name: Run tests (Linux)
if: runner.os == 'Linux'
run: |
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}\
${{ env.MATLAB_PATH }}/runtime/glnxa64:\
${{ env.MATLAB_PATH }}/bin/glnxa64:\
${{ env.MATLAB_PATH }}/sys/os/glnxa64:\
${{ env.MATLAB_PATH }}/extern/bin/glnxa64"
python -m unittest discover tests -v
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Python cache files
**/__pycache__/

# Virtual environment
**/venv/
**/.env/
**/env/
**/.venv/

# Distribution files
**/dist/
**/build/
**/*.egg-info/

# Jupyter Notebook checkpoints
**/.ipynb_checkpoints/

# IDE and editor files
**/.vscode/
**/.idea/
**/*.swp

# Pytest cache
.cache/

# OS-specific files
**/.DS_Store
**/Thumbs.db

*.nii

# MPython Hashmaps
**/.mpython_hashmap.csv
.mpython/build
.mpython/external
**/*.asv
examples/data/

# CTF file
**/*.ctf
8 changes: 8 additions & 0 deletions .mpython/templates/class_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from mpython import MatlabClass
from fieldtrip._runtime import Runtime, RuntimeMixin


class <classname>(RuntimeMixin, MatlabClass):
def __init__(self, *args, **kwargs):
<docstring>
super().__init__()
28 changes: 28 additions & 0 deletions .mpython/templates/docstring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
<matlabhelp>

This file was automatically converted from Matlab to Python using
[MPython](https://github.com/MPython-Package-Factory/mpython), please
refer to the original matlab file for the most accurate documentation.

[Matlab code]( https://github.com/fieldtrip/fieldtrip/blob/master/<rfilepath> )

Copyright (C) 2011-2021, Robert Oostenveld
Copyright (C) 2022-, Jan-Mathijs Schoffelen and Robert Oostenveld

This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
for the documentation and details.

FieldTrip is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

FieldTrip is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
"""
Empty file.
Loading