diff --git a/.github/workflows/_reusable-build.yml b/.github/workflows/_reusable-build.yml new file mode 100644 index 00000000000..63639ac56c3 --- /dev/null +++ b/.github/workflows/_reusable-build.yml @@ -0,0 +1,66 @@ +# --------------------------------------------------------------------------- +# Reusable workflow: Build MNE-CPP (no tests, min/max Qt versions) +# Called by main.yml, staging.yml, and pull-request.yml +# --------------------------------------------------------------------------- +name: Reusable Build + +on: + workflow_call: + inputs: + qt_version: + description: "Qt version to build with" + required: true + type: string + +jobs: + Build: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + max-parallel: 3 + matrix: + os: [ubuntu-24.04, macos-26, windows-2025] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} + + - name: Install Qt (Linux|MacOS) + if: matrix.os == 'ubuntu-24.04' || matrix.os == 'macos-26' + uses: jurplel/install-qt-action@v3 + with: + version: ${{ inputs.qt_version }} + modules: qtshadertools + + - name: Install Qt (Windows) + if: matrix.os == 'windows-2025' + uses: jurplel/install-qt-action@v3 + with: + version: ${{ inputs.qt_version }} + arch: win64_msvc2022_64 + modules: qtshadertools + + - name: Configure and compile MNE-CPP (Linux|MacOS) + if: matrix.os == 'ubuntu-24.04' || matrix.os == 'macos-26' + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + cmake --build build + + - name: Configure and compile MNE-CPP (Windows) + if: matrix.os == 'windows-2025' + run: | + cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" + Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + cmake --build build --config Release + + - name: Deploy binaries + run: | + ./tools/deploy.bat dynamic pack diff --git a/.github/workflows/_reusable-tests.yml b/.github/workflows/_reusable-tests.yml new file mode 100644 index 00000000000..47678d7303c --- /dev/null +++ b/.github/workflows/_reusable-tests.yml @@ -0,0 +1,246 @@ +# --------------------------------------------------------------------------- +# Reusable workflow: Build & Test MNE-CPP +# Called by main.yml, staging.yml, and pull-request.yml +# --------------------------------------------------------------------------- +name: Reusable Tests + +on: + workflow_call: + inputs: + with_code_coverage: + description: "Enable gcov code coverage instrumentation (Linux only)" + required: false + default: false + type: boolean + upload_codecov: + description: "Upload coverage to Codecov (requires CODECOV_TOKEN secret)" + required: false + default: false + type: boolean + coverage_threshold: + description: "Minimum coverage % — workflow fails if below this (0 = disabled)" + required: false + default: 0 + type: number + fail_on_coverage_regression: + description: "Fail if coverage drops compared to previous baseline" + required: false + default: false + type: boolean + secrets: + CODECOV_TOKEN: + required: false + +jobs: + Tests: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + max-parallel: 3 + matrix: + os: [ubuntu-24.04, macos-26, windows-2025] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Clone mne-cpp test data + run: git clone https://github.com/mne-tools/mne-cpp-test-data.git resources/data/mne-cpp-test-data + + - name: Install Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} + + - name: Install Qt (Linux|MacOS) + if: matrix.os == 'ubuntu-24.04' || matrix.os == 'macos-26' + uses: jurplel/install-qt-action@v3 + with: + version: 6.10.2 + modules: qtshadertools + + - name: Install Qt (Windows) + if: matrix.os == 'windows-2025' + uses: jurplel/install-qt-action@v3 + with: + version: 6.10.2 + arch: win64_msvc2022_64 + modules: qtshadertools + + - name: Install MNE-Python + run: | + pip install --upgrade pip + pip install mne numpy scipy + + - name: Cache MNE sample data + id: cache-mne-data + uses: actions/cache@v4 + with: + path: ~/mne_data/MNE-sample-data + key: mne-sample-data-v1 + + - name: Download MNE sample data + if: steps.cache-mne-data.outputs.cache-hit != 'true' + run: | + python -c "import mne; mne.datasets.sample.data_path()" + + # ── Build ────────────────────────────────────────────────────────────── + - name: Configure and compile MNE-CPP (Linux) + if: matrix.os == 'ubuntu-24.04' + run: | + COV_FLAG="" + if [ "${{ inputs.with_code_coverage }}" = "true" ]; then + COV_FLAG="-DWITH_CODE_COV=ON" + fi + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ${COV_FLAG} + cmake --build build + + - name: Configure and compile MNE-CPP (MacOS) + if: matrix.os == 'macos-26' + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON + cmake --build build + + - name: Configure and compile MNE-CPP (Windows) + if: matrix.os == 'windows-2025' + run: | + cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" + Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON + cmake --build build --config Release + + # ── Run tests ────────────────────────────────────────────────────────── + - name: Run tests (Linux) + if: matrix.os == 'ubuntu-24.04' + env: + QTEST_FUNCTION_TIMEOUT: 900000 + QT_QPA_PLATFORM: offscreen + MNE_DATA: ~/mne_data + run: | + if [ "${{ inputs.with_code_coverage }}" = "true" ]; then + ./tools/test_all.bat verbose withCoverage + else + ./tools/test_all.bat verbose + fi + + - name: Run tests (MacOS) + if: matrix.os == 'macos-26' + env: + QTEST_FUNCTION_TIMEOUT: 900000 + QT_QPA_PLATFORM: offscreen + MNE_DATA: ~/mne_data + run: | + ./tools/test_all.bat Release verbose + + - name: Run tests (Windows) + if: matrix.os == 'windows-2025' + env: + QTEST_FUNCTION_TIMEOUT: 900000 + MNE_DATA: ~/mne_data + run: | + ./tools/test_all.bat Release verbose + + # ── Coverage: Codecov upload (main branch) ───────────────────────────── + - name: Upload coverage to Codecov + if: matrix.os == 'ubuntu-24.04' && inputs.upload_codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + # ── Coverage: threshold & regression check (staging branch) ──────────── + - name: Install lcov + if: matrix.os == 'ubuntu-24.04' && inputs.with_code_coverage && !inputs.upload_codecov + run: sudo apt-get install -y -qq lcov + + - name: Generate lcov report + id: lcov + if: matrix.os == 'ubuntu-24.04' && inputs.with_code_coverage && !inputs.upload_codecov + run: | + lcov --capture --directory build \ + --output-file coverage.info \ + --ignore-errors mismatch 2>/dev/null || true + # Remove external/test code from the report + lcov --remove coverage.info \ + '*/src/external/*' '*/src/examples/*' '*/src/testframes/*' \ + '/usr/*' '*/Qt/*' \ + --output-file coverage_filtered.info \ + --ignore-errors unused 2>/dev/null || true + # Extract total line coverage percentage + COVERAGE=$(lcov --summary coverage_filtered.info 2>&1 \ + | grep -oP 'lines\.*:\s*\K[0-9]+(\.[0-9]+)?' || echo "0") + echo "Total line coverage: ${COVERAGE}%" + echo "coverage=${COVERAGE}" >> "$GITHUB_OUTPUT" + + - name: Restore previous coverage baseline + id: prev-coverage + if: matrix.os == 'ubuntu-24.04' && inputs.fail_on_coverage_regression + uses: actions/cache/restore@v4 + with: + path: .coverage-baseline + key: coverage-baseline-${{ github.ref_name }} + + - name: Check coverage threshold & regression + if: matrix.os == 'ubuntu-24.04' && inputs.with_code_coverage && !inputs.upload_codecov + env: + CURRENT: ${{ steps.lcov.outputs.coverage }} + THRESHOLD: ${{ inputs.coverage_threshold }} + CHECK_REGRESSION: ${{ inputs.fail_on_coverage_regression }} + run: | + echo "═══════════════════════════════════════════════════" + echo " Coverage Report" + echo "═══════════════════════════════════════════════════" + echo " Current coverage : ${CURRENT}%" + echo " Minimum threshold: ${THRESHOLD}%" + + FAILED=false + + # --- Threshold check --- + if [ "$THRESHOLD" != "0" ]; then + if (( $(echo "${CURRENT} < ${THRESHOLD}" | bc -l) )); then + echo " ❌ FAIL: Coverage ${CURRENT}% is below threshold ${THRESHOLD}%" + FAILED=true + else + echo " ✅ PASS: Coverage is above threshold" + fi + fi + + # --- Regression check --- + if [ "$CHECK_REGRESSION" = "true" ] && [ -f .coverage-baseline ]; then + PREVIOUS=$(cat .coverage-baseline) + echo " Previous coverage: ${PREVIOUS}%" + if (( $(echo "${CURRENT} < ${PREVIOUS}" | bc -l) )); then + DELTA=$(echo "${PREVIOUS} - ${CURRENT}" | bc -l) + echo " ❌ FAIL: Coverage dropped by ${DELTA}% (${PREVIOUS}% → ${CURRENT}%)" + FAILED=true + else + echo " ✅ PASS: Coverage did not regress" + fi + fi + + echo "═══════════════════════════════════════════════════" + + # Update baseline for next run + echo "${CURRENT}" > .coverage-baseline + + if [ "$FAILED" = "true" ]; then + exit 1 + fi + + - name: Save coverage baseline + if: matrix.os == 'ubuntu-24.04' && inputs.fail_on_coverage_regression && always() + uses: actions/cache/save@v4 + with: + path: .coverage-baseline + key: coverage-baseline-${{ github.ref_name }}-${{ github.run_id }} + + - name: Upload coverage report artifact + if: matrix.os == 'ubuntu-24.04' && inputs.with_code_coverage + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: | + coverage.info + coverage_filtered.info + retention-days: 30 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a7d489722e1..5e24fb2fb3c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,10 +2,9 @@ name: "CodeQL" on: push: - branches: [ "main", "v2.0-dev" ] + branches: [ "main", "staging" ] pull_request: - # The branches below must be a subset of the branches above - branches: [ "main" ] + branches: [ "main", "staging" ] schedule: - cron: '28 15 * * 1' diff --git a/.github/workflows/docutest.yml b/.github/workflows/docutest.yml deleted file mode 100644 index 377544e2e1f..00000000000 --- a/.github/workflows/docutest.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: DocuTest - -on: - push: - branches: - # Change this to the branch name you make changes to the documentation on - - docu - -jobs: - gh-pages: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Clone doc/gh-pages into gh-pages branch - run: | - git config --global user.email dev@dev.com - git config --global user.name dev - # Copy the changed docu files first - cp -RT ../mne-cpp/doc/gh-pages ../newDoc - # Checkout the gh-pages branch - git fetch origin gh-pages - git checkout --track origin/gh-pages - # Remove all files first - git rm * -r - git commit --amend -a -m 'Update docu' --allow-empty - # Add the changed doc files - cp -RT ../newDoc ../mne-cpp - git add --all - git commit --amend -a -m 'Update docu' - git push -f --all \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000000..1171f1b81fa --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,348 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# Main Branch Pipeline +# ═══════════════════════════════════════════════════════════════════════════ +# +# Triggered on pushes to `main` and version tags (v*). +# +# ┌────────────────────┬────────────────────────────────────────────────────┐ +# │ Trigger │ What runs │ +# ├────────────────────┼────────────────────────────────────────────────────┤ +# │ Push to main │ Tests + Codecov, build matrix (min/max Qt), │ +# │ │ deploy production website + Doxygen API docs │ +# ├────────────────────┼────────────────────────────────────────────────────┤ +# │ Tag v* on main │ Everything above, PLUS: │ +# │ │ GitHub Release, platform binaries (Linux/macOS/ │ +# │ │ Windows, dynamic+static), cross-platform │ +# │ │ installers, WebAssembly build │ +# └────────────────────┴────────────────────────────────────────────────────┘ +# +# To cut a release: +# git tag v2.0.1 -a -m "Release v2.0.1" +# git push origin v2.0.1 +# +# Branch model: Feature → Staging → Main +# ═══════════════════════════════════════════════════════════════════════════ +name: Main + +on: + push: + branches: + - main + tags: + - 'v*' + +# Cancel superseded runs on the same branch/tag +concurrency: + group: main-${{ github.ref }} + cancel-in-progress: true + +# ═══════════════════════════════════════════════════════════════════════════ +# Jobs that run on EVERY push to main (and also on tags) +# ═══════════════════════════════════════════════════════════════════════════ +jobs: + + # ── Build compatibility matrix (min + max Qt) ─────────────────────────── + BuildMinQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.0' + + BuildMaxQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.2' + + # ── Tests with Codecov coverage ────────────────────────────────────────── + Tests: + uses: ./.github/workflows/_reusable-tests.yml + with: + with_code_coverage: true + upload_codecov: true + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # ── Doxygen API documentation (production) ─────────────────────────────── + Doxygen: + runs-on: ubuntu-24.04 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install Doxygen 1.16.1 and Graphviz + run: | + sudo apt-get update -qq + sudo apt-get install -qq qttools5-dev-tools graphviz + wget -q https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-1.16.1.linux.bin.tar.gz + tar xzf doxygen-1.16.1.linux.bin.tar.gz + sudo install -m 755 doxygen-1.16.1/bin/doxygen /usr/local/bin/doxygen + + - name: Run Doxygen + run: | + cd doc/doxygen + doxygen mne-cpp_doxyfile + + - name: Deploy qch to GitHub Release + if: startsWith(github.ref, 'refs/tags/') + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + file: doc/doxygen/qt-creator_doc/mne-cpp.qch + asset_name: mne-cpp-${{ github.ref_name }}-doc-qtcreator.qch + tag: ${{ github.ref }} + overwrite: true + + - name: Deploy Doxygen to GitHub Pages (production) + env: + GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + run: | + cd doc/doxygen + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + # Deploy to the root (stable) of doxygen-api + git clone -b gh-pages "https://${GIT_CREDENTIALS}@github.com/mne-cpp/doxygen-api" gh-pages + cd gh-pages + # Preserve /dev directory if it exists (staging docs) + if [ -d "dev" ]; then + cp -r dev /tmp/doxygen-dev-backup + fi + git rm -rf --ignore-unmatch . + git commit --amend --reset-author -a -m 'Update stable API docs' --allow-empty + touch .nojekyll + cp -r ../html/* . + # Restore /dev directory + if [ -d "/tmp/doxygen-dev-backup" ]; then + cp -r /tmp/doxygen-dev-backup dev + fi + git add . + git add .nojekyll + git commit --amend --reset-author -a -m 'Update stable API docs' + git push -f --all + + # ── Website (production) ───────────────────────────────────────────────── + Website: + runs-on: ubuntu-24.04 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: doc/website/package-lock.json + + - name: Build Docusaurus site (production) + env: + MNECPP_SITE_ENV: stable + run: | + cd doc/website + npm ci + npm run build + + - name: Deploy to mne-cpp.github.io + env: + GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + run: | + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + git clone -b main --single-branch "https://${GIT_CREDENTIALS}@github.com/mne-cpp/mne-cpp.github.io.git" + cd mne-cpp.github.io + + # Preserve /dev directory (staging website) + if [ -d "dev" ]; then + cp -r dev /tmp/website-dev-backup + fi + + git rm -rf --ignore-unmatch . + git commit --amend --reset-author -a -m 'Update website' --allow-empty + cd .. + + # Copy the stable Docusaurus build + cp -RT doc/website/build mne-cpp.github.io + + # Restore /dev directory + if [ -d "/tmp/website-dev-backup" ]; then + cp -r /tmp/website-dev-backup mne-cpp.github.io/dev + fi + + cd mne-cpp.github.io + git add . + git commit --amend --reset-author -a -m 'Update website' + git push -f --all + + # ═══════════════════════════════════════════════════════════════════════════ + # Jobs that run ONLY on version tags (v*) — the actual release pipeline + # ═══════════════════════════════════════════════════════════════════════════ + + # ── Create GitHub Release ──────────────────────────────────────────────── + CreateRelease: + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-24.04 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Create version branch for new minor releases + run: | + currentVersionPatch=$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f3) + if [[ "$currentVersionPatch" == 0 ]]; then + echo "New minor version — branching off ${GITHUB_REF#refs/tags/}" + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + git checkout -b ${GITHUB_REF#refs/tags/} + git push origin refs/heads/${GITHUB_REF#refs/tags/} + fi + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + run: | + TAG="${GITHUB_REF#refs/tags/}" + gh release create "$TAG" \ + --title "MNE-CPP $TAG" \ + --generate-notes \ + --target ${{ github.sha }} + + # ── Platform release builds (parallel) ─────────────────────────────────── + Linux: + if: startsWith(github.ref, 'refs/tags/') + needs: CreateRelease + uses: ./.github/workflows/release-linux.yml + secrets: inherit + + MacOS: + if: startsWith(github.ref, 'refs/tags/') + needs: CreateRelease + uses: ./.github/workflows/release-macos.yml + secrets: inherit + + Windows: + if: startsWith(github.ref, 'refs/tags/') + needs: CreateRelease + uses: ./.github/workflows/release-windows.yml + secrets: inherit + + # ── Installers (after all platform builds) ─────────────────────────────── + Installer: + if: startsWith(github.ref, 'refs/tags/') + needs: [Linux, MacOS, Windows] + uses: ./.github/workflows/release-installer.yml + secrets: inherit + + # ── WebAssembly ────────────────────────────────────────────────────────── + WebAssembly: + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-24.04 + needs: CreateRelease + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update -qq + sudo apt-get install -qq build-essential libgl1-mesa-dev ninja-build + + - name: Setup Emscripten + run: | + cd .. + git clone https://github.com/emscripten-core/emsdk.git + cd emsdk + ./emsdk install 4.0.7 + ./emsdk activate 4.0.7 + + - name: Download pre-built WASM Qt binaries + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download qt_binaries -p 'qt6_6102_static_binaries_wasm.tar.gz' -D /tmp + mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread + tar xf /tmp/qt6_6102_static_binaries_wasm.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread + echo "Qt6_DIR=${{ runner.tool_cache }}/Qt/6.10.2" >> $GITHUB_ENV + + - name: Download host Qt binaries for cross-compilation + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download qt_binaries -p 'qt6_6102_static_binaries_linux.tar.gz' -D /tmp + mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 + tar xf /tmp/qt6_6102_static_binaries_linux.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 + + - name: Build WASM + run: | + source ../emsdk/emsdk_env.sh + ./tools/wasm.sh --emsdk 4.0.7 + + - name: Prepare WASM artifacts + run: | + rm -rf out/wasm/apps/mne_analyze_plugins + rm -rf resources/data + cp resources/design/logos/qtlogo.svg out/wasm/apps/qtlogo.svg + if [ -d "out/wasm/examples" ]; then + cp resources/design/logos/qtlogo.svg out/wasm/examples/qtlogo.svg + fi + + - name: Package WASM + run: | + tar cfz mne-cpp-wasm.tar.gz -C out/wasm . + + - name: Upload WASM to GitHub Release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + file: mne-cpp-wasm.tar.gz + asset_name: mne-cpp-${{ github.ref_name }}-wasm.tar.gz + tag: ${{ github.ref }} + overwrite: true + + - name: Deploy WASM to mne-cpp/wasm repository + env: + GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + run: | + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + git clone "https://${GIT_CREDENTIALS}@github.com/mne-cpp/wasm.git" wasm-repo + cd wasm-repo + + # --- gh-pages branch --- + if git rev-parse --verify origin/gh-pages > /dev/null 2>&1; then + git checkout gh-pages + else + git checkout --orphan gh-pages + fi + git rm -rf --ignore-unmatch . + git clean -f -d + git commit --allow-empty -m 'Update wasm builds' + cp -RT ../out/wasm/apps . + if [ -d "../out/wasm/examples" ]; then + mkdir -p examples + cp -RT ../out/wasm/examples examples + fi + git add . + git commit --amend --reset-author -m 'Update wasm builds' + git push -f origin gh-pages + + # --- main branch --- + if git rev-parse --verify origin/main > /dev/null 2>&1; then + git checkout main + else + git checkout --orphan main + fi + git rm -rf --ignore-unmatch . + git clean -f -d + git commit --allow-empty -m 'Update wasm builds' + cp -RT ../out/wasm/apps . + if [ -d "../out/wasm/examples" ]; then + mkdir -p examples + cp -RT ../out/wasm/examples examples + fi + git add . + git commit --amend --reset-author -m 'Update wasm builds' + git push -f origin main diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 00000000000..56977f4c19f --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,65 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# Pull Request Pipeline +# ═══════════════════════════════════════════════════════════════════════════ +# +# Triggered on pull requests targeting `staging` or `main`. +# +# This is the FEATURE BRANCH pipeline: +# • Verifies the project builds across all platforms +# • Tests min + max supported Qt versions +# • Runs the full test suite (without coverage — that's done on staging) +# • No deployments, no releases +# +# Branch model: Feature → Staging → Main +# ═══════════════════════════════════════════════════════════════════════════ +name: Pull Request + +on: + pull_request: + branches: + - staging + - main + +# Cancel superseded runs for the same PR +concurrency: + group: pr-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + + # ── Build compatibility: minimum supported Qt ──────────────────────────── + BuildMinQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.0' + + # ── Build compatibility: maximum supported Qt ──────────────────────────── + BuildMaxQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.2' + + # ── Tests (no coverage collection) ────────────────────────────────────── + Tests: + uses: ./.github/workflows/_reusable-tests.yml + with: + with_code_coverage: false + upload_codecov: false + + # ── Doxygen build check ───────────────────────────────────────────────── + Doxygen: + runs-on: ubuntu-24.04 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install Doxygen and Graphviz + run: | + sudo apt-get update -qq + sudo apt-get install -qq qttools5-dev-tools doxygen graphviz + + - name: Run Doxygen (build check only — no deploy) + run: | + cd doc/doxygen + doxygen mne-cpp_doxyfile diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml deleted file mode 100644 index fe9385630d9..00000000000 --- a/.github/workflows/pullrequest.yml +++ /dev/null @@ -1,251 +0,0 @@ -name: PullRequest - -on: - pull_request: - branches: - - v2.0-dev - -jobs: - MinQtDynamic: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - qt: [6.10.2] - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Configure and compile MNE-CPP - run: | - ./tools/build_project.bat all - - name: Deploy binaries - run: | - ./tools/deploy.bat dynamic pack - - MaxQtDynamic: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - qt: [6.10.2] - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Configure and compile MNE-CPP - run: | - ./tools/build_project.bat all - - name: Deploy binaries - run: | - ./tools/deploy.bat dynamic pack - -# QtStatic: -# runs-on: ${{ matrix.os }} -# -# strategy: -# fail-fast: false -# max-parallel: 3 -# matrix: -# os: [ubuntu-20.04, macos-11, windows-2019] -# -# steps: -# - name: Clone repository -# uses: actions/checkout@v3 -# - name: Install Python 3.7 version -# uses: actions/setup-python@v4 -# with: -# python-version: '3.7' -# architecture: 'x64' -# - name: Install OpenGL (Linux) -# if: matrix.os == 'ubuntu-20.04' -# run: | -# sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" -# sudo apt-get update -q -# sudo apt-get install build-essential libgl1-mesa-dev libicu55 -# - name: Install Qt (Linux) -# if: matrix.os == 'ubuntu-20.04' -# run: | -# # Download the pre-built static version of Qt, which was created with the generateBinaries.yml workflow -# wget -O qt5_5152_static_binaries_linux.tar.gz https://www.dropbox.com/s/tje7jp6tsn2dxdd/qt5_5152_static_binaries_linux.tar.gz?dl=0 -# mkdir ../Qt5_binaries -# tar xvzf qt5_5152_static_binaries_linux.tar.gz -C ../ -P -# - name: Install Qt (MacOS) -# if: matrix.os == 'macos-11' -# run: | -# # Download the pre-built static version of Qt, which was created with the generateBinaries.yml workflow -# wget -O qt5_5152_static_binaries_macos.tar.gz https://www.dropbox.com/s/ccigarxk40wlxq0/qt5_5152_static_binaries_macos.tar.gz?dl=1 -# tar xvzf qt5_5152_static_binaries_macos.tar.gz -P -# - name: Install Qt (Windows) -# if: matrix.os == 'windows-2019' -# run: | -# # Download the pre-built static version of Qt, which was created with the generateBinaries.yml workflow -# Invoke-WebRequest https://www.dropbox.com/s/47s49smjg499gnm/qt5_5152_static_binaries_win.zip?dl=1 -OutFile .\qt5_5152_static_binaries_win.zip -# expand-archive -path "qt5_5152_static_binaries_win.zip" -destinationpath "..\" -# - name: Configure and compile MNE-CPP (Linux|MacOS) -# if: (matrix.os == 'ubuntu-20.04') || (matrix.os == 'macos-11') -# run: | -# export QT_DIR="$(pwd)/../Qt5_binaries/lib/cmake/Qt5" -# export Qt5_DIR="$(pwd)/../Qt5_binaries/lib/cmake/Qt5" -# ./tools/build_project.bat static all -# - name: Configure and compile MNE-CPP (Windows) -# if: matrix.os == 'windows-2019' -# run: | -# cmd.exe /c "call `"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" -# Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } -# $env:QT_DIR += "$PWD\..\Qt5_binaries\lib\cmake\Qt5" -# $env:Qt5_DIR += "$PWD\..\Qt5_binaries\lib\cmake\Qt5" -# ./tools/build_project.bat static all -# - name: Deploy binaries -# run: | -# ./tools/deploy.bat static pack - - Tests: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Clone mne-cpp test data - run: git clone https://github.com/mne-tools/mne-cpp-test-data.git resources/data/mne-cpp-test-data - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: 6.10.2 - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: 6.10.2 - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Install MNE-Python - run: | - pip install --upgrade pip - pip install mne numpy scipy - - name: Cache MNE sample data - id: cache-mne-data - uses: actions/cache@v4 - with: - path: ~/mne_data/MNE-sample-data - key: mne-sample-data-v1 - - name: Download MNE sample data - if: steps.cache-mne-data.outputs.cache-hit != 'true' - run: | - python -c "import mne; mne.datasets.sample.data_path()" - - name: Configure and compile MNE-CPP (Linux) - if: matrix.os == 'ubuntu-24.04' - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON -DWITH_CODE_COV=ON - cmake --build build - - name: Configure and compile MNE-CPP (MacOS) - if: matrix.os == 'macos-26' - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON - cmake --build build - - name: Configure and compile MNE-CPP (Windows) - if: matrix.os == 'windows-2025' - run: | - # Setup VS compiler - cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" - Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON - cmake --build build --config Release - - name: Run tests (Linux) - if: matrix.os == 'ubuntu-24.04' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - QT_QPA_PLATFORM: offscreen - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat verbose withCoverage - - name: Upload coverage to Codecov - if: matrix.os == 'ubuntu-24.04' - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - name: Run tests (MacOS) - if: matrix.os == 'macos-26' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - QT_QPA_PLATFORM: offscreen - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat Release verbose - - name: Run tests (Windows) - if: matrix.os == 'windows-2025' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat Release verbose - - Doxygen: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Qt Dev Tools, Doxygen and Graphviz - run: | - sudo apt-get update -q - sudo apt-get install -q qttools5-dev-tools doxygen graphviz - - name: Run Doxygen and package result - run: | - cd doc/doxygen - doxygen mne-cpp_doxyfile diff --git a/.github/workflows/release-installer.yml b/.github/workflows/release-installer.yml index bff5a23581f..822d471811b 100644 --- a/.github/workflows/release-installer.yml +++ b/.github/workflows/release-installer.yml @@ -54,9 +54,12 @@ jobs: if [[ "$GITHUB_REF" == refs/tags/* ]]; then echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT echo "asset_prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-latest" >> $GITHUB_OUTPUT else echo "tag=dev_build" >> $GITHUB_OUTPUT - echo "asset_prefix=mne-cpp-v2.0-dev" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-dev" >> $GITHUB_OUTPUT fi - name: Download dynamic release from GitHub Releases @@ -201,26 +204,14 @@ jobs: ls -lh MNE-CPP-*.run - - name: Deploy installer (stable release) - if: startsWith(github.ref, 'refs/tags/') + - name: Upload installer uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: MNE-CPP-*-Linux.run file_glob: true - asset_name: mne-cpp-${{ github.ref_name }}-linux-installer-x86_64.run - tag: ${{ github.ref }} - overwrite: true - - - name: Deploy installer (dev release) - if: endsWith(github.ref, 'v2.0-dev') == true - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: MNE-CPP-*-Linux.run - file_glob: true - asset_name: mne-cpp-v2.0-dev-linux-installer-x86_64.run - tag: dev_build + asset_name: ${{ steps.tag.outputs.asset_prefix }}-linux-installer-x86_64.run + tag: ${{ steps.tag.outputs.tag }} overwrite: true # ========================================================================= @@ -251,9 +242,12 @@ jobs: if [[ "$GITHUB_REF" == refs/tags/* ]]; then echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT echo "asset_prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-latest" >> $GITHUB_OUTPUT else echo "tag=dev_build" >> $GITHUB_OUTPUT - echo "asset_prefix=mne-cpp-v2.0-dev" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-dev" >> $GITHUB_OUTPUT fi - name: Download dynamic release from GitHub Releases @@ -545,26 +539,14 @@ jobs: run: | security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true - - name: Deploy installer (stable release) - if: startsWith(github.ref, 'refs/tags/') + - name: Upload installer uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: MNE-CPP-*-Darwin.dmg file_glob: true - asset_name: mne-cpp-${{ github.ref_name }}-macos-installer-arm64.dmg - tag: ${{ github.ref }} - overwrite: true - - - name: Deploy installer (dev release) - if: endsWith(github.ref, 'v2.0-dev') == true - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: MNE-CPP-*-Darwin.dmg - file_glob: true - asset_name: mne-cpp-v2.0-dev-macos-installer-arm64.dmg - tag: dev_build + asset_name: ${{ steps.tag.outputs.asset_prefix }}-macos-installer-arm64.dmg + tag: ${{ steps.tag.outputs.tag }} overwrite: true # ========================================================================= @@ -596,9 +578,12 @@ jobs: if [[ "$GITHUB_REF" == refs/tags/* ]]; then echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT echo "asset_prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-latest" >> $GITHUB_OUTPUT else echo "tag=dev_build" >> $GITHUB_OUTPUT - echo "asset_prefix=mne-cpp-v2.0-dev" >> $GITHUB_OUTPUT + echo "asset_prefix=mne-cpp-dev" >> $GITHUB_OUTPUT fi - name: Download dynamic release from GitHub Releases @@ -748,24 +733,12 @@ jobs: Get-ChildItem MNE-CPP-*-win64.exe - - name: Deploy installer (stable release) - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: MNE-CPP-*-win64.exe - file_glob: true - asset_name: mne-cpp-${{ github.ref_name }}-windows-installer-x86_64.exe - tag: ${{ github.ref }} - overwrite: true - - - name: Deploy installer (dev release) - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload installer uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: MNE-CPP-*-win64.exe file_glob: true - asset_name: mne-cpp-v2.0-dev-windows-installer-x86_64.exe - tag: dev_build + asset_name: ${{ steps.tag.outputs.asset_prefix }}-windows-installer-x86_64.exe + tag: ${{ steps.tag.outputs.tag }} overwrite: true diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 96994e91065..ef06b0385a0 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -9,7 +9,28 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -35,23 +56,14 @@ jobs: fi ls "$QT_PREFIX/lib"/libQt6*.so* 2>/dev/null | head -5 || echo " No Qt .so files found at $QT_PREFIX/lib" ./tools/deploy.bat dynamic pack - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-linux-dynamic-x86_64.tar.gz - asset_name: mne-cpp-${{ github.ref_name }}-linux-dynamic-x86_64.tar.gz - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-linux-dynamic-x86_64.tar.gz - asset_name: mne-cpp-v2.0-dev-linux-dynamic-x86_64.tar.gz - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-linux-dynamic-x86_64.tar.gz + tag: ${{ steps.release-info.outputs.tag }} overwrite: true @@ -60,7 +72,28 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -106,21 +139,12 @@ jobs: - name: Deploy binaries run: | ./tools/deploy.bat static pack - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-linux-static-x86_64.tar.gz - asset_name: mne-cpp-${{ github.ref_name }}-linux-static-x86_64.tar.gz - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-linux-static-x86_64.tar.gz - asset_name: mne-cpp-v2.0-dev-linux-static-x86_64.tar.gz - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-linux-static-x86_64.tar.gz + tag: ${{ steps.release-info.outputs.tag }} overwrite: true diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 81eec73eab0..41c1312b6a3 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -9,7 +9,28 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -54,23 +75,14 @@ jobs: if [ "${QT_FW_COUNT}" -lt 10 ]; then echo "WARNING: Very few Qt framework entries found. Deployment may be incomplete." fi - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-macos-dynamic-arm64.tar.gz - asset_name: mne-cpp-${{ github.ref_name }}-macos-dynamic-arm64.tar.gz - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-macos-dynamic-arm64.tar.gz - asset_name: mne-cpp-v2.0-dev-macos-dynamic-arm64.tar.gz - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-macos-dynamic-arm64.tar.gz + tag: ${{ steps.release-info.outputs.tag }} overwrite: true @@ -79,7 +91,28 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -124,21 +157,12 @@ jobs: - name: Deploy binaries (MacOS) run: | ./tools/deploy.bat static pack - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-macos-static-arm64.tar.gz - asset_name: mne-cpp-${{ github.ref_name }}-macos-static-arm64.tar.gz - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-macos-static-arm64.tar.gz - asset_name: mne-cpp-v2.0-dev-macos-static-arm64.tar.gz - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-macos-static-arm64.tar.gz + tag: ${{ steps.release-info.outputs.tag }} overwrite: true diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index dc5c9112831..0460a82659c 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -9,7 +9,29 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + shell: bash + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -48,23 +70,14 @@ jobs: echo "ERROR: Archive file not found!" exit 1 } - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-windows-dynamic-x86_64.zip - asset_name: mne-cpp-${{ github.ref_name }}-windows-dynamic-x86_64.zip - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-windows-dynamic-x86_64.zip - asset_name: mne-cpp-v2.0-dev-windows-dynamic-x86_64.zip - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-windows-dynamic-x86_64.zip + tag: ${{ steps.release-info.outputs.tag }} overwrite: true @@ -73,7 +86,29 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Determine release info + id: release-info + shell: bash + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + echo "tag=latest" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-latest" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then + echo "tag=dev_build" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-dev" >> "$GITHUB_OUTPUT" + echo "should_upload=true" >> "$GITHUB_OUTPUT" + else + echo "tag=none" >> "$GITHUB_OUTPUT" + echo "prefix=mne-cpp-local" >> "$GITHUB_OUTPUT" + echo "should_upload=false" >> "$GITHUB_OUTPUT" + fi - name: Install Python 3.10 version uses: actions/setup-python@v5 with: @@ -119,21 +154,12 @@ jobs: - name: Deploy binaries (Windows) run: | ./tools/deploy.bat static pack - - name: Deploy binaries with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-windows-static-x86_64.zip - asset_name: mne-cpp-${{ github.ref_name }}-windows-static-x86_64.zip - tag: ${{ github.ref }} - overwrite: true - - name: Deploy binaries with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true + - name: Upload release binaries + if: steps.release-info.outputs.should_upload == 'true' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} file: mne-cpp-windows-static-x86_64.zip - asset_name: mne-cpp-v2.0-dev-windows-static-x86_64.zip - tag: dev_build + asset_name: ${{ steps.release-info.outputs.prefix }}-windows-static-x86_64.zip + tag: ${{ steps.release-info.outputs.tag }} overwrite: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 78ca5c7ec14..00000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,314 +0,0 @@ -name: Release - -on: - push: - tags: - - v0.* - branches: - - v2.0-dev - -jobs: - CreateRelease: - runs-on: ubuntu-24.04 - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Create new branch with the tag's name (stable release only) - if: endsWith(github.ref, 'v2.0-dev') == false - run: | - currentVersionPatch=`echo ${GITHUB_REF#refs/tags/} | cut -d. -f3` - # Only branch off if we have a new minor version bump, which will always result in the patch version to be 0 - if [[ "$currentVersionPatch" == 0 ]]; then - echo Branching off $currentVersionPatch - # Setup Git - git config --global user.email christoph.dinh@mne-cpp.org - git config --global user.name chdinh - # Create new branch named after the new version tag - git checkout -b ${GITHUB_REF#refs/tags/} - git push origin refs/heads/${GITHUB_REF#refs/tags/} - fi - - name: Update dev_build tag and release (dev release only) - if: endsWith(github.ref, 'v2.0-dev') == true - timeout-minutes: 5 - env: - GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - run: | - set -x # Enable debug output - - git config --global user.email christoph.dinh@mne-cpp.org - git config --global user.name chdinh - - # Configure git to use token - git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} - - # Delete current dev_build release remotely (if it exists) - echo "Attempting to delete existing dev_build release..." - if gh release view dev_build > /dev/null 2>&1; then - gh release delete dev_build --yes --cleanup-tag - echo "Existing release deleted." - else - echo "No existing dev_build release found, skipping deletion." - fi - - # Delete current tag remotely (if it exists) - echo "Attempting to delete existing dev_build tag..." - git push origin :refs/tags/dev_build 2>/dev/null || echo "Tag did not exist remotely, continuing." - - # Change dev_build tag to point to newest commit - git tag dev_build -f -a -m "Development Builds" - - # Send the new tag - git push origin dev_build -f - - # Create new dev_build release (use --target to avoid tag propagation race) - echo "Creating new dev_build release..." - gh release create dev_build --prerelease --title "Development Builds" --notes "Development Builds" --target ${{ github.sha }} - echo "Release created successfully." - - # Platform-specific build workflows (run in parallel) - Linux: - needs: CreateRelease - uses: ./.github/workflows/release-linux.yml - secrets: inherit - - MacOS: - needs: CreateRelease - uses: ./.github/workflows/release-macos.yml - secrets: inherit - - Windows: - needs: CreateRelease - uses: ./.github/workflows/release-windows.yml - secrets: inherit - - # Build installers AFTER all platform releases have been uploaded. - # Downloads the release archives from GitHub Releases and packages them - # with the Qt Installer Framework. - Installer: - needs: [Linux, MacOS, Windows] - uses: ./.github/workflows/release-installer.yml - secrets: inherit - - # Cross-platform jobs (Tests are handled by testci.yml) - Doxygen: - runs-on: ubuntu-24.04 - needs: CreateRelease - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Qt Dev Tools, Doxygen 1.16.1 and Graphviz - run: | - sudo apt-get update -qq - sudo apt-get install -qq qttools5-dev-tools graphviz - wget -q https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-1.16.1.linux.bin.tar.gz - tar xzf doxygen-1.16.1.linux.bin.tar.gz - sudo install -m 755 doxygen-1.16.1/bin/doxygen /usr/local/bin/doxygen - - name: Run Doxygen and package result - run: | - git fetch --all - git checkout origin/v2.0-dev - cd doc/doxygen - doxygen mne-cpp_doxyfile - - name: Setup Github credentials - uses: fusion-engineering/setup-git-credentials@v2 - with: - credentials: ${{secrets.GIT_CREDENTIALS}} - - name: Deploy qch docu data base with stable release on Github - if: startsWith(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: doc/doxygen/qt-creator_doc/mne-cpp.qch - asset_name: mne-cpp-${{ github.ref_name }}-doc-qtcreator.qch - tag: ${{ github.ref }} - overwrite: true - - name: Deploy qch docu data base with dev release on Github - if: endsWith(github.ref, 'v2.0-dev') == true - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: doc/doxygen/qt-creator_doc/mne-cpp.qch - asset_name: mne-cpp-v2.0-dev-doc-qtcreator.qch - tag: dev_build - overwrite: true - - name: Update documentation at Github pages - env: - GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} - run: | - cd doc/doxygen - git config --global user.email christoph.dinh@mne-cpp.org - git config --global user.name chdinh - git clone -b gh-pages "https://${GIT_CREDENTIALS}@github.com/mne-cpp/doxygen-api" gh-pages - cd gh-pages - # Remove all files first - git rm * -r - git commit --amend --reset-author -a -m 'Update docu' --allow-empty - touch .nojekyll - # Copy doxygen files - cp -r ../html/* . - # Add all new files, commit and push - git add * - git add .nojekyll - git commit --amend --reset-author -a -m 'Update docu' - git push -f --all - - gh-pages: - # Only run for dev releases - if: endsWith(github.ref, 'v2.0-dev') == true - runs-on: ubuntu-24.04 - needs: CreateRelease - - steps: - - name: Clone repository - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: doc/website/package-lock.json - - name: Build Docusaurus site - run: | - cd doc/website - npm ci - npm run build - - name: Setup Github credentials - uses: fusion-engineering/setup-git-credentials@v2 - with: - credentials: ${{secrets.GIT_CREDENTIALS}} - - name: Deploy to mne-cpp.github.io - env: - GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} - run: | - git config --global user.email christoph.dinh@mne-cpp.org - git config --global user.name chdinh - # Clone using credentials embedded in URL - git clone -b main --single-branch "https://${GIT_CREDENTIALS}@github.com/mne-cpp/mne-cpp.github.io.git" - cd mne-cpp.github.io - # Remove all files first - git rm * -r - git commit --amend --reset-author -a -m 'Update docu' --allow-empty - cd .. - # Copy the Docusaurus build output - cp -RT doc/website/build mne-cpp.github.io - cd mne-cpp.github.io - git add . - git commit --amend --reset-author -a -m 'Update docu' - git push -f --all - - WebAssembly: - # Only run for dev releases - if: endsWith(github.ref, 'v2.0-dev') == true - runs-on: ubuntu-24.04 - needs: CreateRelease - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install dependencies - run: | - sudo apt-get update -qq - sudo apt-get install -qq build-essential libgl1-mesa-dev ninja-build - - name: Setup Emscripten - run: | - cd .. - git clone https://github.com/emscripten-core/emsdk.git - cd emsdk - ./emsdk install 4.0.7 - ./emsdk activate 4.0.7 - - name: Download pre-built WASM Qt binaries - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download qt_binaries -p 'qt6_6102_static_binaries_wasm.tar.gz' -D /tmp - mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread - tar xf /tmp/qt6_6102_static_binaries_wasm.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread - echo "Qt6_DIR=${{ runner.tool_cache }}/Qt/6.10.2" >> $GITHUB_ENV - - name: Download host Qt binaries for cross-compilation - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download qt_binaries -p 'qt6_6102_static_binaries_linux.tar.gz' -D /tmp - mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 - tar xf /tmp/qt6_6102_static_binaries_linux.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 - - name: Build WASM - run: | - source ../emsdk/emsdk_env.sh - ./tools/wasm.sh --emsdk 4.0.7 - - name: Prepare WASM artifacts - run: | - # Delete folders which we do not want to ship - rm -rf out/wasm/apps/mne_analyze_plugins - rm -rf resources/data - # Replace logo - cp resources/design/logos/qtlogo.svg out/wasm/apps/qtlogo.svg - if [ -d "out/wasm/examples" ]; then - cp resources/design/logos/qtlogo.svg out/wasm/examples/qtlogo.svg - fi - - name: Package WASM build as tar.gz - run: | - tar cfz mne-cpp-wasm.tar.gz -C out/wasm . - - name: Deploy WASM tar.gz with dev release on Github - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} - file: mne-cpp-wasm.tar.gz - asset_name: mne-cpp-v2.0-dev-wasm.tar.gz - tag: dev_build - overwrite: true - - name: Setup Github credentials - uses: fusion-engineering/setup-git-credentials@v2 - with: - credentials: ${{secrets.GIT_CREDENTIALS}} - - name: Clone and update mne-cpp/wasm repository - env: - GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} - run: | - git config --global user.email christoph.dinh@mne-cpp.org - git config --global user.name chdinh - git clone "https://${GIT_CREDENTIALS}@github.com/mne-cpp/wasm.git" wasm-repo - cd wasm-repo - - # --- Update gh-pages branch --- - if git rev-parse --verify origin/gh-pages > /dev/null 2>&1; then - git checkout gh-pages - else - git checkout --orphan gh-pages - fi - git rm -rf --ignore-unmatch . - git clean -f -d - git commit --allow-empty -m 'Update wasm builds' - # Copy apps to root - cp -RT ../out/wasm/apps . - # Copy examples to examples/ subdirectory - if [ -d "../out/wasm/examples" ]; then - mkdir -p examples - cp -RT ../out/wasm/examples examples - fi - git add . - git commit --amend --reset-author -m 'Update wasm builds' - git push -f origin gh-pages - - # --- Update main branch --- - if git rev-parse --verify origin/main > /dev/null 2>&1; then - git checkout main - else - git checkout --orphan main - fi - git rm -rf --ignore-unmatch . - git clean -f -d - git commit --allow-empty -m 'Update wasm builds' - # Copy apps to root - cp -RT ../out/wasm/apps . - # Copy examples to examples/ subdirectory - if [ -d "../out/wasm/examples" ]; then - mkdir -p examples - cp -RT ../out/wasm/examples examples - fi - git add . - git commit --amend --reset-author -m 'Update wasm builds' - git push -f origin main diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml new file mode 100644 index 00000000000..5a4b6e51f5e --- /dev/null +++ b/.github/workflows/staging.yml @@ -0,0 +1,271 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# Staging Branch Pipeline +# ═══════════════════════════════════════════════════════════════════════════ +# +# Triggered on pushes to `staging`. +# +# This is the DEVELOPMENT pipeline: +# • Creates/updates a rolling "dev_build" pre-release on GitHub +# • Builds development binaries for Linux, macOS, Windows +# • Runs full test suite with coverage threshold & regression checks +# (fails if coverage < minimum threshold or drops from previous run) +# • Deploys dev website → mne-cpp.github.io/dev/ +# • Deploys dev Doxygen API → mne-cpp.github.io/doxygen-api/dev/ +# • Builds WebAssembly dev version +# +# Coverage is NOT uploaded to Codecov (that's reserved for main). +# Instead, coverage is checked via lcov with: +# 1) A minimum threshold (configurable via COVERAGE_THRESHOLD env var) +# 2) Regression detection (compares to previous run's baseline) +# +# Branch model: Feature → Staging → Main +# ═══════════════════════════════════════════════════════════════════════════ +name: Staging + +on: + push: + branches: + - staging + +# Cancel superseded runs +concurrency: + group: staging-${{ github.ref }} + cancel-in-progress: true + +env: + # Minimum acceptable line coverage percentage. + # The pipeline will FAIL if coverage drops below this. + COVERAGE_THRESHOLD: 50 + +jobs: + + # ── Create / update dev_build pre-release ──────────────────────────────── + CreateDevRelease: + runs-on: ubuntu-24.04 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Update dev_build tag and release + timeout-minutes: 5 + env: + GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + run: | + set -x + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} + + # Delete existing dev_build release (if any) + if gh release view dev_build > /dev/null 2>&1; then + gh release delete dev_build --yes --cleanup-tag + fi + git push origin :refs/tags/dev_build 2>/dev/null || true + + # Create new tag + pre-release + git tag dev_build -f -a -m "Development Builds" + git push origin dev_build -f + gh release create dev_build \ + --prerelease \ + --title "Development Builds" \ + --notes "Latest development builds from the staging branch. These are pre-release builds for testing." \ + --target ${{ github.sha }} + + # ── Platform release builds (parallel) ─────────────────────────────────── + Linux: + needs: CreateDevRelease + uses: ./.github/workflows/release-linux.yml + secrets: inherit + + MacOS: + needs: CreateDevRelease + uses: ./.github/workflows/release-macos.yml + secrets: inherit + + Windows: + needs: CreateDevRelease + uses: ./.github/workflows/release-windows.yml + secrets: inherit + + # ── Build compatibility matrix (min + max Qt) ─────────────────────────── + BuildMinQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.0' + + BuildMaxQt: + uses: ./.github/workflows/_reusable-build.yml + with: + qt_version: '6.10.2' + + # ── Tests with coverage threshold & regression checks ──────────────────── + Tests: + uses: ./.github/workflows/_reusable-tests.yml + with: + with_code_coverage: true + upload_codecov: false + coverage_threshold: 50 + fail_on_coverage_regression: true + + # ── Doxygen API documentation (dev) ────────────────────────────────────── + Doxygen: + runs-on: ubuntu-24.04 + needs: CreateDevRelease + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install Doxygen 1.16.1 and Graphviz + run: | + sudo apt-get update -qq + sudo apt-get install -qq qttools5-dev-tools graphviz + wget -q https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-1.16.1.linux.bin.tar.gz + tar xzf doxygen-1.16.1.linux.bin.tar.gz + sudo install -m 755 doxygen-1.16.1/bin/doxygen /usr/local/bin/doxygen + + - name: Run Doxygen + run: | + cd doc/doxygen + doxygen mne-cpp_doxyfile + + - name: Deploy qch to dev_build release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + file: doc/doxygen/qt-creator_doc/mne-cpp.qch + asset_name: mne-cpp-dev-doc-qtcreator.qch + tag: dev_build + overwrite: true + + - name: Deploy Doxygen to GitHub Pages (dev subdirectory) + env: + GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + run: | + cd doc/doxygen + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + # Clone doxygen-api repo + git clone -b gh-pages "https://${GIT_CREDENTIALS}@github.com/mne-cpp/doxygen-api" gh-pages + cd gh-pages + # Only update the /dev subdirectory — preserve stable root docs + rm -rf dev + mkdir -p dev + cp -r ../html/* dev/ + git add . + git commit -m 'Update dev API docs' --allow-empty + git push origin gh-pages + + # ── Website (dev version) ──────────────────────────────────────────────── + Website: + runs-on: ubuntu-24.04 + needs: CreateDevRelease + + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: doc/website/package-lock.json + + - name: Build Docusaurus site (dev) + env: + MNECPP_SITE_ENV: dev + DOCUSAURUS_BASE_URL: /dev/ + run: | + cd doc/website + npm ci + npm run build + + - name: Deploy to mne-cpp.github.io/dev/ + env: + GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} + run: | + git config --global user.email christoph.dinh@mne-cpp.org + git config --global user.name chdinh + git clone -b main --single-branch "https://${GIT_CREDENTIALS}@github.com/mne-cpp/mne-cpp.github.io.git" + cd mne-cpp.github.io + + # Only update the /dev subdirectory — preserve stable root docs + rm -rf dev + mkdir -p dev + cp -RT ../doc/website/build dev/ + + git add . + git commit -m 'Update dev website' --allow-empty + git push origin main + + # ── WebAssembly (dev) ──────────────────────────────────────────────────── + WebAssembly: + runs-on: ubuntu-24.04 + needs: CreateDevRelease + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update -qq + sudo apt-get install -qq build-essential libgl1-mesa-dev ninja-build + + - name: Setup Emscripten + run: | + cd .. + git clone https://github.com/emscripten-core/emsdk.git + cd emsdk + ./emsdk install 4.0.7 + ./emsdk activate 4.0.7 + + - name: Download pre-built WASM Qt binaries + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download qt_binaries -p 'qt6_6102_static_binaries_wasm.tar.gz' -D /tmp + mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread + tar xf /tmp/qt6_6102_static_binaries_wasm.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/wasm_multithread + echo "Qt6_DIR=${{ runner.tool_cache }}/Qt/6.10.2" >> $GITHUB_ENV + + - name: Download host Qt binaries for cross-compilation + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download qt_binaries -p 'qt6_6102_static_binaries_linux.tar.gz' -D /tmp + mkdir -p ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 + tar xf /tmp/qt6_6102_static_binaries_linux.tar.gz -C ${{ runner.tool_cache }}/Qt/6.10.2/gcc_64 + + - name: Build WASM + run: | + source ../emsdk/emsdk_env.sh + ./tools/wasm.sh --emsdk 4.0.7 + + - name: Prepare WASM artifacts + run: | + rm -rf out/wasm/apps/mne_analyze_plugins + rm -rf resources/data + cp resources/design/logos/qtlogo.svg out/wasm/apps/qtlogo.svg + if [ -d "out/wasm/examples" ]; then + cp resources/design/logos/qtlogo.svg out/wasm/examples/qtlogo.svg + fi + + - name: Package and upload WASM to dev_build release + env: + GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + run: | + tar cfz mne-cpp-wasm.tar.gz -C out/wasm . + + - name: Upload WASM to dev_build release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + file: mne-cpp-wasm.tar.gz + asset_name: mne-cpp-dev-wasm.tar.gz + tag: dev_build + overwrite: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 63dba0f962a..00000000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,211 +0,0 @@ -name: Tests - -on: - push: - branches: - - v2.0-dev - -jobs: - MinQtDynamic: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - qt: [6.10.0] - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Configure and compile MNE-CPP (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release - cmake --build build - - name: Configure and compile MNE-CPP (Windows) - if: matrix.os == 'windows-2025' - run: | - # Setup VS compiler - cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" - Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release - cmake --build build --config Release - - name: Deploy binaries - run: | - ./tools/deploy.bat dynamic pack - - MaxQtDynamic: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - qt: [6.10.2] - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: ${{ matrix.qt }} - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Configure and compile MNE-CPP (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release - cmake --build build - - name: Configure and compile MNE-CPP (Windows) - if: matrix.os == 'windows-2025' - run: | - # Setup VS compiler - cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" - Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release - cmake --build build --config Release - - name: Deploy binaries - run: | - ./tools/deploy.bat dynamic pack - - Tests: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - os: [ubuntu-24.04, macos-26, windows-2025] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Clone mne-cpp test data - run: git clone https://github.com/mne-tools/mne-cpp-test-data.git resources/data/mne-cpp-test-data - - name: Install Python 3.10 version - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: ${{ matrix.os == 'macos-26' && 'arm64' || 'x64' }} - - name: Install Qt (Linux|MacOS) - if: (matrix.os == 'ubuntu-24.04') || (matrix.os == 'macos-26') - uses: jurplel/install-qt-action@v3 - with: - version: 6.10.2 - modules: qtshadertools - - name: Install Qt (Windows) - if: matrix.os == 'windows-2025' - uses: jurplel/install-qt-action@v3 - with: - version: 6.10.2 - arch: win64_msvc2022_64 - modules: qtshadertools - - name: Install MNE-Python - run: | - pip install --upgrade pip - pip install mne numpy scipy - - name: Cache MNE sample data - id: cache-mne-data - uses: actions/cache@v4 - with: - path: ~/mne_data/MNE-sample-data - key: mne-sample-data-v1 - - name: Download MNE sample data - if: steps.cache-mne-data.outputs.cache-hit != 'true' - run: | - python -c "import mne; mne.datasets.sample.data_path()" - - name: Configure and compile MNE-CPP (Linux) - if: matrix.os == 'ubuntu-24.04' - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON -DWITH_CODE_COV=ON - cmake --build build - - name: Configure and compile MNE-CPP (MacOS) - if: matrix.os == 'macos-26' - run: | - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON - cmake --build build - - name: Configure and compile MNE-CPP (Windows) - if: matrix.os == 'windows-2025' - run: | - # Setup VS compiler - cmd.exe /c "call `"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt" - Get-Content "$env:temp\vcvars.txt" | Foreach-Object { if ($_ -match "^(.*?)=(.*)$") { Set-Content "env:\$($matches[1])" $matches[2] } } - cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON - cmake --build build --config Release - - name: Run tests (Linux) - if: matrix.os == 'ubuntu-24.04' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - QT_QPA_PLATFORM: offscreen - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat verbose withCoverage - - name: Upload coverage to Codecov - if: matrix.os == 'ubuntu-24.04' - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - name: Run tests (MacOS) - if: matrix.os == 'macos-26' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - QT_QPA_PLATFORM: offscreen - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat Release verbose - - name: Run tests (Windows) - if: matrix.os == 'windows-2025' - env: - QTEST_FUNCTION_TIMEOUT: 900000 - MNE_DATA: ~/mne_data - run: | - ./tools/test_all.bat Release verbose - - Doxygen: - runs-on: ubuntu-24.04 - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - name: Install Qt Dev Tools, Doxygen and Graphviz - run: | - sudo apt-get update -q - sudo apt-get install -q qttools5-dev-tools doxygen graphviz - - name: Run Doxygen and package result - run: | - cd doc/doxygen - doxygen mne-cpp_doxyfile diff --git a/codecov.yml b/codecov.yml index 218bc8e311f..f288100145a 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,6 +1,6 @@ codecov: require_ci_to_pass: yes - branch: v2.0-dev + branch: main coverage: precision: 2 diff --git a/doc/website/docs/development/ci-deployment.mdx b/doc/website/docs/development/ci-deployment.mdx index 7515539f4e1..e86a1bc9f02 100644 --- a/doc/website/docs/development/ci-deployment.mdx +++ b/doc/website/docs/development/ci-deployment.mdx @@ -16,7 +16,7 @@ MNE-CPP depends on [Qt](https://www.qt.io/) and [Eigen](http://eigen.tuxfamily.o ### Windows -The `WinDynamic` workflow in [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) excludes examples and tests. MNE-CPP libraries are copied to both `mne-cpp/lib` and `mne-cpp/out/Release`. +The `WinDynamic` workflow in [release-windows.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/release-windows.yml) excludes examples and tests. MNE-CPP libraries are copied to both `mne-cpp/lib` and `mne-cpp/out/Release`. Dependency resolution uses `windeployqt` (maintained by Qt), called from [deploy.bat](https://github.com/mne-tools/mne-cpp/blob/main/tools/deploy.bat) with `dynamic` as the first argument. It runs against: - The MNE Scan `.exe` (covers all application-level Qt modules) @@ -26,7 +26,7 @@ Afterward, Qt and system libraries reside in `mne-cpp/out/Release`. The test dat ### Linux -The `LinuxDynamic` workflow in [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) excludes examples and tests. CMake configures the `RPATH` to link against libraries in `mne-cpp/lib`. +The `LinuxDynamic` workflow in [release-linux.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/release-linux.yml) excludes examples and tests. CMake configures the `RPATH` to link against libraries in `mne-cpp/lib`. Dependency resolution uses [linuxdeployqt](https://github.com/probonopd/linuxdeployqt), called from the deployment script under `tools/deployment`. @@ -34,7 +34,7 @@ The test data folder is deleted, and the folders `out/Release/apps`, `out/Releas ### macOS -The `MacOSDynamic` workflow in [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) excludes examples and tests. All applications are built as `.app` bundles. +The `MacOSDynamic` workflow in [release-macos.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/release-macos.yml) excludes examples and tests. All applications are built as `.app` bundles. Dependency resolution uses `macdeployqt` (maintained by Qt). MNE-CPP libraries are manually copied to each app's `Contents/Frameworks` folder, and resources and plugin folders are copied to the corresponding `.app` directories. diff --git a/doc/website/docs/development/ci-ghactions.mdx b/doc/website/docs/development/ci-ghactions.mdx index d651e75285d..27c629ac9ae 100644 --- a/doc/website/docs/development/ci-ghactions.mdx +++ b/doc/website/docs/development/ci-ghactions.mdx @@ -9,49 +9,72 @@ MNE-CPP uses [GitHub Actions](https://docs.github.com/en/actions) for all contin ## Workflow Overview -The following table summarizes every CI workflow in MNE-CPP: +MNE-CPP's CI is organized around the [Main – Staging – Feature branch model](ci-releasecycle.mdx). The following table summarizes every CI workflow: | Event type | Workflow Name | Workflow Script | Effect | | ---------- | ------------- | --------------- | ------ | -| Pull Requests | `PullRequest` | [pullrequest.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/pullrequest.yml) | Triggers checks to run on the PR code.| -| Pushes/Merges to `main` | `Linux|MacOS|Win|WASM` | [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) | Triggers the Development Release binaries to be updated with the most recently pushed changes. This workflow basically follows the idea of nightly builds. | -| Publishing a new release with tag syntax `v0.x.y` | `Linux|MacOS|Win|WASM` | [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) | Triggers stable release processing steps described in more detail [here](ci-releasecycle.mdx). | -| Pushes to the `docu` branch | `DocuTest` | [docutest.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/docutest.yml) | Creates a new version of the documentation website and makes them accessible via the repository's `gh-pages` branch. | +| Pull Requests → `staging` or `main` | `PullRequest` | [pull-request.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/pull-request.yml) | Build matrix (Qt min + max) and tests on all platforms. PR cannot be merged until all jobs pass. | +| Pushes to `staging` | `Staging` | [staging.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/staging.yml) | Dev release binaries, code coverage with threshold/regression checks, dev website + Doxygen deployment, CodeQL analysis. | +| Pushes to `main` | `Main` | [main.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/main.yml) | Builds, tests, stable website + Doxygen deployment. | +| Tag `v*` on `main` | `Main` (release jobs) | [main.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/main.yml) | Full stable release: platform binaries (Linux, macOS, Windows), installers, WebAssembly, Codecov upload. | | Pushes to the `wasm` branch | `WasmTest` | [wasmtest.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/wasmtest.yml) | Creates new versions of the WebAssembly capable MNE-CPP applications and makes them accessible via the repository's `gh-pages` branch. | -| Pushes to the `testci` branch | `TestCI` | [testci.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/testci.yml) | Triggers checks to run cross-platform build setups and tests without the need to create a Github PR. | | Timer runs out | `Coverity` | [coverity.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/coverity.yml) | Triggers every two days to run [Coverity](https://scan.coverity.com/projects/mne-tools-mne-cpp) static code analysis tools. | -| Pushes to the `generateqt` branch | `BuildQtBinaries` | [buildqtbinaries.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/buildqtbinaries.yml) | Triggers builds of all needed Qt versions and makes them accesible as [artifacts via the Github Actions interface](https://help.github.com/en/actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts). | +| Pushes to the `generateqt` branch | `BuildQtBinaries` | [buildqtbinaries.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/buildqtbinaries.yml) | Triggers builds of all needed Qt versions and makes them accessible as [artifacts via the Github Actions interface](https://help.github.com/en/actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts). | + +### Reusable Workflows + +Common build and test logic is extracted into reusable workflows to avoid duplication: + +| Workflow | Script | Purpose | +|----------|--------|---------| +| Reusable Build | [_reusable-build.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/_reusable-build.yml) | Cross-platform build parameterized by Qt version | +| Reusable Tests | [_reusable-tests.yml](https://github.com/mne-tools/mne-cpp/blob/staging/.github/workflows/_reusable-tests.yml) | Test execution with configurable code coverage (Codecov upload, threshold check, or plain) | + +These are called by the main pipeline workflows using `workflow_call`. ## How the Pull Request Workflow Works -When a contributor opens or updates a pull request, `pullrequest.yml` runs a build-and-test matrix across all supported platforms. The workflow typically: +When a contributor opens or updates a pull request targeting `staging` (or `main`), `pull-request.yml` runs a build-and-test matrix: 1. **Checks out** the PR branch. -2. **Installs Qt** using a cached Qt installation or the `aqtinstall` action. -3. **Configures CMake** with `BUILD_TESTS=ON` so that unit tests are included. -4. **Builds** the entire project in Release mode. -5. **Runs CTest** to execute all unit tests and reports pass/fail status back to the pull request. +2. **Builds** twice — once with the **minimum** supported Qt version and once with the **maximum** — to ensure compatibility across the supported Qt range. +3. **Runs tests** via the reusable test workflow (without coverage uploads). +4. **Builds Doxygen** documentation to verify it compiles without errors. -The PR cannot be merged until all matrix jobs pass. This ensures that every change is validated on Windows, Linux, and macOS before it reaches the `main` branch. +The PR cannot be merged until all matrix jobs pass. This ensures that every change is validated on Linux, macOS, and Windows before it reaches the `staging` branch. -## How the Release Workflow Works +## How the Staging Workflow Works -`release.yml` is the most complex workflow. It is triggered by two different events: +`staging.yml` is the active development pipeline, triggered on every push to `staging`. It: -- **Pushes to `main`** — produces a *development release* (nightly build). Dynamically linked binaries are built for all three desktop platforms and uploaded to the `DevBuilds` release on GitHub. -- **Publishing a tagged release (`v0.x.y`)** — produces a *stable release*. Both dynamically and statically linked binaries are built, deployment scripts bundle Qt dependencies, and the resulting archives are uploaded as release assets. +- Creates or updates the **`dev_build`** pre-release on GitHub with the latest development binaries +- Builds with both minimum and maximum Qt versions +- Runs tests with **code coverage** — enforcing a minimum threshold (50%) and detecting coverage regressions +- Invokes the platform-specific release workflows (`release-linux.yml`, `release-macos.yml`, `release-windows.yml`, `release-installer.yml`) to produce development binaries tagged as `dev_build` +- Deploys the **dev** version of the documentation website to `/dev/` and Doxygen API docs to `/dev/` +- Runs **CodeQL** security analysis -Each platform job follows the same high-level pattern: install Qt, configure CMake, build, deploy (bundle Qt libraries), package into an archive, and upload. +## How the Main / Release Workflow Works -## Testing CI Without a Pull Request +`main.yml` handles two scenarios: -The `testci` branch provides a convenient way to run the full CI matrix without opening a pull request. Push your changes to the `testci` branch on your fork: +### Pushes to `main` (no tag) -```bash -git push origin :testci -f -``` +On every push to `main`, the workflow: +- Builds with minimum and maximum Qt versions +- Runs tests (with Codecov upload) +- Deploys the **stable** website and Doxygen API documentation (preserving the dev subdirectory) + +### Tagged releases (`v*`) + +When a version tag is pushed (e.g., `v2.0.0`), the workflow additionally: +- Creates a GitHub Release from the tag +- Invokes platform-specific release workflows to build and upload binaries for Linux, macOS, and Windows +- Builds and uploads platform installers (`.run`, `.dmg`, `.exe`) +- Builds and deploys WebAssembly applications +- Uploads the Doxygen `.qch` file as a release asset -Then check the **Actions** tab in your fork's GitHub page. This is especially useful for debugging platform-specific build failures before submitting a PR. +Each platform job follows the same high-level pattern: install Qt, configure CMake, build, deploy (bundle Qt libraries), package into an archive, and upload to the GitHub release. ## Workflow File Structure @@ -62,16 +85,16 @@ name: WorkflowName on: push: - branches: [main] + branches: [staging] pull_request: - branches: [main] + branches: [staging, main] jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-24.04, macos-26, windows-2025] steps: - uses: actions/checkout@v4 - name: Install Qt @@ -93,6 +116,9 @@ Some workflows require GitHub repository secrets (configured in **Settings → S | Secret | Used by | Purpose | |--------|---------|---------| | `GITHUB_TOKEN` | All release workflows | Automatically provided; used to upload release assets | +| `GH_PAT` | Release workflows | Personal access token for cross-repo operations (optional fallback) | +| `GIT_CREDENTIALS` | Website + Doxygen deploy | Authentication for pushing to `gh-pages` branches | +| `CODECOV_TOKEN` | Main workflow | Token for uploading coverage to Codecov | | `COVERITY_TOKEN` | `coverity.yml` | Authentication token for Coverity Scan | ## Adding or Modifying a Workflow @@ -102,6 +128,6 @@ To add a new workflow: 1. Create a new `.yml` file in `.github/workflows/`. 2. Define the trigger event (`on:`) — push, pull_request, schedule, or workflow_dispatch. 3. Define one or more jobs with the appropriate runner (`runs-on:`) and steps. -4. Test the workflow by pushing to a feature branch or using `workflow_dispatch`. +4. Test the workflow by pushing to a feature branch and opening a PR against `staging`. To modify an existing workflow, edit the corresponding `.yml` file and push the change. If the modification affects the PR workflow, open a PR to see the results immediately. diff --git a/doc/website/docs/development/ci-releasecycle.mdx b/doc/website/docs/development/ci-releasecycle.mdx index fff7c061053..3514743ae5c 100644 --- a/doc/website/docs/development/ci-releasecycle.mdx +++ b/doc/website/docs/development/ci-releasecycle.mdx @@ -5,7 +5,7 @@ sidebar_label: Release Guide # Release Guide -This page describes the complete process for creating a new MNE-CPP release, from preparation through publication. +This page describes MNE-CPP's branch model, the development workflow, and the complete process for creating a new release. ## Versioning Scheme @@ -17,41 +17,107 @@ MNE-CPP follows [Semantic Versioning](https://semver.org/) with the tag syntax ` | **Minor** | New features, new plugins, significant enhancements | `v0.1.0` → `v0.2.0` | | **Patch** | Bug fixes, documentation corrections, small improvements | `v0.1.0` → `v0.1.1` | -## Branch Strategy +## Branch Model -New development takes place on the `main` branch. When a new **minor** release is created (e.g., going from `v0.1.x` to `v0.2.0`), a release branch named `v0.x.y` is automatically created from `main`. This branch receives only critical bug-fix back-ports and serves as the stable base for patch releases. +MNE-CPP uses a **Main – Staging – Feature** branch model with three tiers: ``` -main ──────●──────●──────●──────●──────●───► (ongoing development) - \ \ - v0.1.0 v0.2.0 (release branches) - \ \ - v0.1.1 ··· (patch releases) +feature/my-fix ──●──●──●──┐ + ▼ (PR → staging) +staging ───●───●───●───●───●───●───●───●───► (integration & dev builds) + \ + ──► main (merge when stable) + │ + ├─ v2.0.0 (tag → stable release) + └─ v2.1.0 (tag → stable release) ``` +### `main` — Stable / Release Branch + +The `main` branch always reflects a **production-ready** state. It is updated only by merging from `staging` once the code is considered stable. + +- **Pushes to `main`** trigger builds, tests, and deploy the **stable** version of the website and Doxygen API documentation. +- **Tagged releases** (`v*`) on `main` trigger the full release pipeline: platform binaries (Linux, macOS, Windows), installers, WebAssembly builds, and documentation uploads. +- Direct commits to `main` are not allowed; all changes flow through `staging` first. + +### `staging` — Integration / Development Branch + +The `staging` branch is the active development integration branch. Feature branches are merged here via pull requests. + +- Every push to `staging` triggers: + - Cross-platform builds (minimum and maximum supported Qt versions) + - Unit tests with **code coverage** — threshold checks (≥ 50%) and regression detection + - A rolling **dev pre-release** (`dev_build`) with binaries for all platforms + - Deployment of the **dev** version of the website (at `/dev/`) and Doxygen API docs (at `/dev/`) + - CodeQL security analysis + +### Feature Branches + +All development work happens on short-lived feature branches created from `staging`: + +```bash +git checkout -b feature/my-change staging +``` + +- Feature branches are merged into `staging` via pull requests. +- The [pull-request pipeline](ci-ghactions.mdx) builds and tests every PR across all platforms before it can be merged. +- Branch names should be descriptive, e.g., `fix/fiff-reader-crash`, `feature/lsl-plugin`, `doc/update-api`. + +### Flow Summary + +| From | To | How | When | +|------|----|-----|------| +| `staging` | feature branch | `git checkout -b feature/x staging` | Starting new work | +| feature branch | `staging` | Pull request (reviewed + CI passes) | Feature is complete | +| `staging` | `main` | Merge (maintainers only) | Code is release-ready | +| `main` | GitHub Release | Tag `v*` on `main` | Cutting a release | + +## Dual-Version Documentation + +The website and Doxygen API docs are deployed in two versions simultaneously: + +| Version | URL | Updated by | +|---------|-----|-----------| +| **Stable** | `mne-cpp.github.io` / `mne-cpp.github.io/doxygen-api` | Pushes to `main` | +| **Dev** | `mne-cpp.github.io/dev/` / `mne-cpp.github.io/doxygen-api/dev/` | Pushes to `staging` | + +Both versions are served from the same repository and branch (`gh-pages`), using subdirectory isolation — stable at the root, dev under `/dev/`. A version dropdown in the website header lets users switch between stable and dev documentation. + ## Release Steps -Once the developers have rough consensus that `main` is ready for a new release, the following steps are performed: +Once `staging` is considered stable and ready for release, the maintainers perform the following steps: + +### 1. Merge Staging into Main + +Create a pull request from `staging` → `main`, or merge directly: + +```bash +git checkout main +git merge staging +git push origin main +``` + +This triggers the `main` pipeline, which runs builds, tests, and deploys the **stable** website and Doxygen docs. -### 1. Increment Version Numbers (Manual) +### 2. Increment Version Numbers (Manual) Update the version string in these files: -- **[CMakeLists.txt](https://github.com/mne-tools/mne-cpp/blob/main/CMakeLists.txt)** — the top-level project version (`project(mne_cpp VERSION 0.x.y)`) +- **[CMakeLists.txt](https://github.com/mne-tools/mne-cpp/blob/main/CMakeLists.txt)** — the top-level project version (`project(mne_cpp VERSION x.y.z)`) - **[mne-cpp_doxyfile](https://github.com/mne-tools/mne-cpp/blob/main/doc/doxygen/mne-cpp_doxyfile)** — the Doxygen `PROJECT_NUMBER` field -### 2. Update Application Version Info (Manual) +### 3. Update Application Version Info (Manual) Bump the version constants in each application's `info.h`: - [MNE Scan info.h](https://github.com/mne-tools/mne-cpp/blob/main/applications/mne_scan/mne_scan/info.h) - [MNE Analyze info.h](https://github.com/mne-tools/mne-cpp/blob/main/applications/mne_analyze/mne_analyze/info.h) -### 3. Update the Release Table on the Website (Manual) +### 4. Update the Release Table on the Website (Manual) Add the new version to the documentation website's download / release page so users can find it. -### 4. Prepare the Changelog (Manual) +### 5. Prepare the Changelog (Manual) The changelog for the release being prepared is maintained on the [GitHub Wiki (Changelog-WIP)](https://github.com/mne-tools/mne-cpp/wiki/Changelog-WIP). To generate contributor statistics since the last release: @@ -61,42 +127,37 @@ git shortlog -s -n main --no-merges --since="" Move the work-in-progress changelog entries into the release notes. -### 5. Create the GitHub Release (Manual) +### 6. Tag and Create the GitHub Release (Manual) -Go to the [GitHub Releases page](https://github.com/mne-tools/mne-cpp/releases) and create a new release: +Tag the release on `main` and push the tag: -- **Tag**: `v0.x.y` (create the tag on `main`) -- **Title**: `v0.x.y` -- **Description**: Paste the changelog prepared in step 4 - -### 6. CI Creates a Release Branch (Automated) +```bash +git tag -a v0.x.y -m "Release v0.x.y" +git push origin v0.x.y +``` -The [release.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/release.yml) workflow detects the new tag and: +Then go to the [GitHub Releases page](https://github.com/mne-tools/mne-cpp/releases) and create a new release: -- Creates a branch named `v0.x.y` from `main` (only for **minor** or **major** version bumps, e.g., `v0.1.0` → `v0.2.0`) -- Skips branch creation for patch releases, since the branch already exists +- **Tag**: `v0.x.y` (the tag you just pushed) +- **Title**: `v0.x.y` +- **Description**: Paste the changelog prepared in step 5 ### 7. CI Builds and Uploads Binaries (Automated) -The same `release.yml` workflow: +The tag triggers the release jobs in [main.yml](https://github.com/mne-tools/mne-cpp/blob/main/.github/workflows/main.yml), which: -- Builds **dynamically linked** binaries for Windows, Linux, and macOS +- Builds **dynamically linked** binaries for Linux, macOS, and Windows via the platform-specific release workflows - Builds **statically linked** binaries for all platforms - Runs the deployment scripts (`tools/deploy.bat` / `tools/deploy.sh`) to bundle Qt dependencies -- Packages the output into `.zip` (Windows) or `.tar.gz` (Linux/macOS) archives -- Uploads the archives as release assets to the GitHub release created in step 5 - -### 8. Protect the New Branch (Manual) - -For minor or major version bumps, add branch protection rules for the newly created `v0.x.y` branch via the GitHub web interface (**Settings → Branches → Add rule**): - -- Require pull request reviews before merging -- Require status checks to pass +- Packages the output into `.zip` (Windows) or `.tar.gz` (Linux/macOS) archives and uploads them as release assets +- Builds platform installers (`.run`, `.dmg`, `.exe`) via the installer workflow +- Builds and deploys WebAssembly applications -## Post-Release +### 8. Post-Release After the release is published: -- Verify that the release assets (binaries) are downloadable and functional +- Verify that the release assets (binaries, installers) are downloadable and functional - Announce the release on relevant channels (mailing lists, website news, etc.) - Clear the work-in-progress changelog on the [GitHub Wiki](https://github.com/mne-tools/mne-cpp/wiki/Changelog-WIP) for the next development cycle +- Merge the version bump commit back into `staging` so development continues from the released state diff --git a/doc/website/docs/development/ci.mdx b/doc/website/docs/development/ci.mdx index cf5634dea28..d4f0b22cd51 100644 --- a/doc/website/docs/development/ci.mdx +++ b/doc/website/docs/development/ci.mdx @@ -5,26 +5,26 @@ sidebar_label: Continuous Integration # Continuous Integration -Every change to MNE-CPP is automatically built, tested, and — for releases — packaged across **Windows, Linux, and macOS** before it reaches users. The CI system runs on [GitHub Actions](https://docs.github.com/en/actions) and is triggered by pull requests, pushes to `main`, tagged releases, and dedicated test branches. +Every change to MNE-CPP is automatically built, tested, and — for releases — packaged across **Windows, Linux, and macOS** before it reaches users. The CI system runs on [GitHub Actions](https://docs.github.com/en/actions) and is organized around the [Main – Staging – Feature branch model](ci-releasecycle.mdx). -Pull requests cannot be merged until all platform jobs pass. Development builds (nightly) are published on every push to `main`; stable release binaries are created when a version tag (`v0.x.y`) is published. +Pull requests cannot be merged until all platform jobs pass. Development builds are published on every push to `staging`; stable release binaries are created when a version tag (`v*`) is pushed on `main`. ## Guides -- **[GitHub Actions](ci-ghactions.mdx)** — Workflow overview, the pull-request and release pipelines, secrets, and how to add or modify workflows. +- **[GitHub Actions](ci-ghactions.mdx)** — Workflow overview, the pull-request, staging, and release pipelines, secrets, and how to add or modify workflows. - **[Unit Testing](writingtest.mdx)** — How to write and run unit tests using Qt Test, including test structure, reference data, and naming conventions. - **[Deployment](ci-deployment.mdx)** — How Qt dependencies are bundled on each platform using `windeployqt`, `linuxdeployqt`, and `macdeployqt`. -- **[Release Guide](ci-releasecycle.mdx)** — The step-by-step process for creating a new stable release, from version bumps to automated binary uploads. +- **[Release Guide](ci-releasecycle.mdx)** — Branch model, versioning, and the step-by-step process for creating a new stable release. ## At a Glance | Branch / Event | Workflow | What Happens | |----------------|----------|--------------| -| Pull request | `pullrequest.yml` | Build + test on all platforms | -| Push to `main` | `release.yml` | Development release (nightly binaries) | -| Tag `v0.x.y` | `release.yml` | Stable release with static + dynamic binaries | -| Push to `testci` | `testci.yml` | Full CI matrix without opening a PR | +| Pull request → `staging` or `main` | `pull-request.yml` | Build matrix (Qt min + max) + tests on all platforms | +| Push to `staging` | `staging.yml` | Dev release binaries, coverage checks, dev website + Doxygen, CodeQL | +| Push to `main` | `main.yml` | Tests, stable website + Doxygen deployment | +| Tag `v*` on `main` | `main.yml` | Full stable release: platform binaries, installers, WebAssembly | | Push to `wasm` | `wasmtest.yml` | WebAssembly build deployed to GitHub Pages | -| Push to `docu` | `docutest.yml` | Documentation website rebuilt and published | +| Timer (every 2 days) | `coverity.yml` | Coverity static code analysis | Contributors should follow the [contribution workflow](contr-guide.mdx) to ensure their changes pass all CI checks before requesting a review. diff --git a/doc/website/docs/development/contr-git.mdx b/doc/website/docs/development/contr-git.mdx index 3866a82f055..94a2c079035 100644 --- a/doc/website/docs/development/contr-git.mdx +++ b/doc/website/docs/development/contr-git.mdx @@ -7,6 +7,18 @@ sidebar_label: Git Workflow This page gives a concise overview of the Git commands used in the MNE-CPP development workflow. For a deeper introduction, see this [Git tutorial video](https://www.youtube.com/watch?v=DtLrWCFaG0A&feature=youtu.be). For the full contribution process — from forking to pull request — see the [Contribution Guide](contr-guide.mdx). +## Branch Model + +MNE-CPP uses a **Main – Staging – Feature** branch model: + +| Branch | Purpose | +|--------|---------| +| `main` | Stable / release-ready code. Updated only from `staging`. | +| `staging` | Active development integration branch. Feature branches merge here. | +| `feature/*` | Short-lived branches for individual changes (bug fixes, features, docs). | + +See the [Release Guide](ci-releasecycle.mdx) for a detailed description of the branch model and release process. + ## Initial Setup As described in the [Build from Source](buildguide-cmake.mdx) guide, start by cloning your fork and adding the upstream remote: @@ -15,24 +27,24 @@ As described in the [Build from Source](buildguide-cmake.mdx) guide, start by cl git clone https://github.com//mne-cpp.git git remote add upstream https://github.com/mne-tools/mne-cpp.git git fetch --all -git rebase upstream/main +git rebase upstream/staging ``` ## Daily Workflow The general workflow is covered by the following steps: -- Create a new branch from `main`: +- Create a new feature branch from `staging`: ```bash -git checkout -b main +git checkout -b my-feature upstream/staging ``` - Get the latest changes and [rebase](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase): ```bash git fetch upstream -git rebase upstream/main +git rebase upstream/staging ``` - Solve [merge conflicts](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line), if they occur. @@ -68,11 +80,13 @@ git commit -m "FIX: meaningful commit message" --amend - Push your changes to origin (your fork on GitHub). Note that a force push (`-f`) may be necessary after a rebase: ```bash -git push origin +git push origin my-feature # or force push after rebase: -git push origin -f +git push origin my-feature -f ``` +- Open a pull request targeting the **`staging`** branch on the upstream repository. + ## Useful Commands | Command | Purpose | diff --git a/doc/website/docs/development/contr-guide.mdx b/doc/website/docs/development/contr-guide.mdx index 6269b454034..e943c457e2d 100644 --- a/doc/website/docs/development/contr-guide.mdx +++ b/doc/website/docs/development/contr-guide.mdx @@ -30,14 +30,14 @@ git remote add upstream https://github.com/mne-tools/mne-cpp.git ### 2. Create a Feature Branch -Always work on a dedicated branch — never commit directly to `main`: +Always work on a dedicated branch — never commit directly to `staging` or `main`. Feature branches are created from `staging`, which is the active development branch: ```bash git fetch upstream -git checkout -b my-feature upstream/main +git checkout -b my-feature upstream/staging ``` -Choose a descriptive branch name, e.g., `fix-fiff-reader-crash` or `add-lsl-plugin`. +Choose a descriptive branch name, e.g., `fix/fiff-reader-crash` or `feature/lsl-plugin`. ### 3. Make Your Changes @@ -66,16 +66,15 @@ ctest --output-on-failure If you added new functionality, write unit tests for it. See [Writing Tests](writingtest.mdx) for guidance. -### 5. Test on CI Without a Pull Request +### 5. Keep Your Branch Up to Date -Before opening a formal PR, you can validate your changes across all platforms by pushing to the `testci` branch on your fork: +Regularly rebase your feature branch on the latest `staging` to avoid large merge conflicts: ```bash -git push origin my-feature:testci -f +git fetch upstream +git rebase upstream/staging ``` -Check the **Actions** tab on your forked repository's GitHub page. Fix any platform-specific failures before proceeding. - ### 6. Push to Your Fork Once local tests pass, push your feature branch: @@ -89,11 +88,15 @@ git push origin my-feature Go to your fork on GitHub and create a pull request: 1. Click **New pull request** next to the branch selector. -2. Set the **base repository** to `mne-tools/mne-cpp` and the **base branch** to `main`. +2. Set the **base repository** to `mne-tools/mne-cpp` and the **base branch** to **`staging`**. 3. Set the **compare branch** to your feature branch. 4. Give the PR a descriptive title using the commit prefix convention (e.g., `ENH: Add LSL acquisition plugin`). 5. In the description, explain what your changes do, why they are needed, and how to test them. +:::important +Pull requests should target the **`staging`** branch, not `main`. The `main` branch is reserved for release-ready code and is updated only by maintainers merging from `staging`. +::: + For a detailed overview of how to make a pull request, see the [guide on the official GitHub website](https://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project). ### 8. Code Review and Iteration @@ -103,24 +106,24 @@ After you create the pull request: - The [CI pipeline](ci.mdx) will automatically run builds and tests on all platforms. - MNE-CPP maintainers will review your code and may request changes. - Address review comments by making additional commits on your feature branch and pushing them — they are automatically added to the existing PR. There is no need to create a new pull request. -- Once all CI checks pass and the reviewers approve, your code will be merged. +- Once all CI checks pass and the reviewers approve, your code will be merged into `staging`. ### 9. Clean Up After your PR is merged, you can delete the feature branch: ```bash -git checkout main +git checkout staging git branch -d my-feature git push origin --delete my-feature ``` -Keep your fork's `main` branch up to date: +Keep your fork's `staging` branch up to date: ```bash git fetch upstream -git rebase upstream/main -git push origin main +git rebase upstream/staging +git push origin staging ``` ## Tips for a Smooth Review diff --git a/doc/website/docs/development/contribute.mdx b/doc/website/docs/development/contribute.mdx index ea64e06d15d..ebd4f7fcc3b 100644 --- a/doc/website/docs/development/contribute.mdx +++ b/doc/website/docs/development/contribute.mdx @@ -24,13 +24,13 @@ All code contributions are reviewed by maintainers and validated by the [CI pipe git clone https://github.com//mne-cpp.git && cd mne-cpp git remote add upstream https://github.com/mne-tools/mne-cpp.git -# 2. Create a feature branch -git checkout -b my-feature upstream/main +# 2. Create a feature branch from staging +git checkout -b my-feature upstream/staging # 3. Build, make changes, run tests cmake -B build -S . -DBUILD_TESTS=ON && cmake --build build --parallel cd build && ctest --output-on-failure -# 4. Push and open a pull request +# 4. Push and open a pull request targeting staging git push origin my-feature ``` diff --git a/doc/website/docusaurus.config.ts b/doc/website/docusaurus.config.ts index 260160257c8..7a811d4d7b7 100644 --- a/doc/website/docusaurus.config.ts +++ b/doc/website/docusaurus.config.ts @@ -4,13 +4,19 @@ import type * as Preset from '@docusaurus/preset-classic'; import remarkMath from 'remark-math'; import rehypeKatex from 'rehype-katex'; +// Determine if this is a dev or stable build (set via CI env var) +const siteEnv = process.env.MNECPP_SITE_ENV || 'stable'; +const isDev = siteEnv === 'dev'; +const versionLabel = isDev ? 'dev (latest)' : 'v2.0.0'; + const config: Config = { title: 'MNE-CPP', tagline: 'The C++ framework for real-time functional brain imaging.', favicon: 'img/favicon.ico', url: 'https://mne-cpp.github.io', - baseUrl: '/', + // Allow CI to override baseUrl for dev builds (deployed under /dev/) + baseUrl: process.env.DOCUSAURUS_BASE_URL || '/', organizationName: 'mne-cpp', projectName: 'mne-cpp.github.io', @@ -96,7 +102,9 @@ const config: Config = { label: 'Development', }, { - href: 'https://mne-cpp.github.io/doxygen-api/', + href: isDev + ? 'https://mne-cpp.github.io/doxygen-api/dev/' + : 'https://mne-cpp.github.io/doxygen-api/', label: 'API Reference', position: 'left', }, @@ -106,10 +114,20 @@ const config: Config = { position: 'left', }, { - type: 'html', + type: 'dropdown', + label: versionLabel, position: 'right', - className: 'navbar-version-item', - value: 'v2.0.0', + className: 'navbar-version-dropdown', + items: [ + { + label: 'v2.0.0 (Stable)', + href: 'https://mne-cpp.github.io/', + }, + { + label: 'dev (Latest Development)', + href: 'https://mne-cpp.github.io/dev/', + }, + ], }, { href: 'https://github.com/mne-tools/mne-cpp', diff --git a/src/applications/mne_compute_mne/main.cpp b/src/applications/mne_compute_mne/main.cpp index a1471b3684a..3ba9ae7c9f4 100644 --- a/src/applications/mne_compute_mne/main.cpp +++ b/src/applications/mne_compute_mne/main.cpp @@ -54,8 +54,8 @@ #include #include #include -#include -#include +#include +#include #include @@ -366,7 +366,7 @@ static bool writeLabelOutput(const Label &label, */ static bool writeDipFile(const QString &fileName, const MatrixXd &stcData, - const MNESourceSpace &src, + const MNESourceSpaces &src, const QList &vertno, int timeIdx, double time_ms) @@ -386,7 +386,7 @@ static bool writeDipFile(const QString &fileName, int row = 0; for (int h = 0; h < vertno.size() && h < src.size(); ++h) { - const MNEHemisphere &hemi = src[h]; + const auto &hemi = src[h]; for (int v = 0; v < vertno[h].size(); ++v, ++row) { int vno = vertno[h](v); double amp = stcData(row, timeIdx); diff --git a/src/applications/mne_compute_raw_inverse/main.cpp b/src/applications/mne_compute_raw_inverse/main.cpp index c4e8a5f9c17..026657bd00c 100644 --- a/src/applications/mne_compute_raw_inverse/main.cpp +++ b/src/applications/mne_compute_raw_inverse/main.cpp @@ -51,8 +51,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/applications/mne_flash_bem/flashbem.cpp b/src/applications/mne_flash_bem/flashbem.cpp index 5f4650e9f17..1263849fad0 100644 --- a/src/applications/mne_flash_bem/flashbem.cpp +++ b/src/applications/mne_flash_bem/flashbem.cpp @@ -84,7 +84,7 @@ using namespace Eigen; // DEFINE MEMBER METHODS //============================================================================================================= -FlashBem::FlashBem(const MneFlashBemSettings& settings) +FlashBem::FlashBem(const MNEFlashBemSettings& settings) : m_settings(settings) , m_step(0) { diff --git a/src/applications/mne_flash_bem/flashbem.h b/src/applications/mne_flash_bem/flashbem.h index a540c5ac110..a6121060068 100644 --- a/src/applications/mne_flash_bem/flashbem.h +++ b/src/applications/mne_flash_bem/flashbem.h @@ -68,7 +68,7 @@ namespace MNEFLASHBEM { // FORWARD DECLARATIONS //============================================================================================================= -class MneFlashBemSettings; +class MNEFlashBemSettings; //============================================================================================================= /** @@ -96,7 +96,7 @@ class FlashBem * * @param[in] settings The parsed command-line settings. */ - FlashBem(const MneFlashBemSettings& settings); + FlashBem(const MNEFlashBemSettings& settings); //========================================================================================================= /** @@ -237,7 +237,7 @@ class FlashBem //========================================================================================================= - const MneFlashBemSettings& m_settings; /**< Command-line settings. */ + const MNEFlashBemSettings& m_settings; /**< Command-line settings. */ int m_step; /**< Current processing step number. */ }; diff --git a/src/applications/mne_flash_bem/main.cpp b/src/applications/mne_flash_bem/main.cpp index 34ea0349c33..c6c2689bf8d 100644 --- a/src/applications/mne_flash_bem/main.cpp +++ b/src/applications/mne_flash_bem/main.cpp @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("mne_flash_bem"); QCoreApplication::setApplicationVersion("1.0"); - MneFlashBemSettings settings(&argc, argv); + MNEFlashBemSettings settings(&argc, argv); FlashBem flashBem(settings); return flashBem.run(); diff --git a/src/applications/mne_flash_bem/mne_flash_bem_settings.cpp b/src/applications/mne_flash_bem/mne_flash_bem_settings.cpp index 56a875fb109..2f0a12c8671 100644 --- a/src/applications/mne_flash_bem/mne_flash_bem_settings.cpp +++ b/src/applications/mne_flash_bem/mne_flash_bem_settings.cpp @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneFlashBemSettings class definition. + * @brief MNEFlashBemSettings class definition. * */ @@ -56,7 +56,7 @@ using namespace MNEFLASHBEM; // DEFINE MEMBER METHODS //============================================================================================================= -MneFlashBemSettings::MneFlashBemSettings(int *argc, char **argv) +MNEFlashBemSettings::MNEFlashBemSettings(int *argc, char **argv) : m_bNoConvert(false) , m_bNoFlash30(false) { @@ -160,49 +160,49 @@ MneFlashBemSettings::MneFlashBemSettings(int *argc, char **argv) //============================================================================================================= -QString MneFlashBemSettings::subject() const +QString MNEFlashBemSettings::subject() const { return m_sSubject; } //============================================================================================================= -QString MneFlashBemSettings::subjectsDir() const +QString MNEFlashBemSettings::subjectsDir() const { return m_sSubjectsDir; } //============================================================================================================= -QString MneFlashBemSettings::freeSurferHome() const +QString MNEFlashBemSettings::freeSurferHome() const { return m_sFreeSurferHome; } //============================================================================================================= -bool MneFlashBemSettings::noConvert() const +bool MNEFlashBemSettings::noConvert() const { return m_bNoConvert; } //============================================================================================================= -bool MneFlashBemSettings::noFlash30() const +bool MNEFlashBemSettings::noFlash30() const { return m_bNoFlash30; } //============================================================================================================= -QString MneFlashBemSettings::unwarp() const +QString MNEFlashBemSettings::unwarp() const { return m_sUnwarp; } //============================================================================================================= -QString MneFlashBemSettings::flashDir() const +QString MNEFlashBemSettings::flashDir() const { return m_sFlashDir; } diff --git a/src/applications/mne_flash_bem/mne_flash_bem_settings.h b/src/applications/mne_flash_bem/mne_flash_bem_settings.h index b96cc6d06f8..c48262f2e69 100644 --- a/src/applications/mne_flash_bem/mne_flash_bem_settings.h +++ b/src/applications/mne_flash_bem/mne_flash_bem_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneFlashBemSettings class declaration. + * @brief MNEFlashBemSettings class declaration. * */ @@ -64,7 +64,7 @@ namespace MNEFLASHBEM { * * @brief Command-line settings for mne_flash_bem. */ -class MneFlashBemSettings +class MNEFlashBemSettings { public: //========================================================================================================= @@ -74,7 +74,7 @@ class MneFlashBemSettings * @param[in] argc Number of arguments. * @param[in] argv Argument array. */ - MneFlashBemSettings(int *argc, char **argv); + MNEFlashBemSettings(int *argc, char **argv); //========================================================================================================= /** diff --git a/src/applications/mne_make_source_space/main.cpp b/src/applications/mne_make_source_space/main.cpp index eb8ae2369e1..696d10d7a94 100644 --- a/src/applications/mne_make_source_space/main.cpp +++ b/src/applications/mne_make_source_space/main.cpp @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include @@ -307,7 +307,7 @@ static MNEHemisphere buildHemisphere(const Surface &surf, // Copy vertex positions and normals hemi.rr = surf.rr(); hemi.nn = surf.nn(); - hemi.tris = surf.tris(); + hemi.itris = surf.tris(); // Selection info hemi.nuse = vertno.size(); @@ -317,16 +317,16 @@ static MNEHemisphere buildHemisphere(const Surface &surf, // Build use_tris (triangles that use only selected vertices) QVector useTrisIdx; for (int t = 0; t < hemi.ntri; ++t) { - if (inuse(hemi.tris(t, 0)) && - inuse(hemi.tris(t, 1)) && - inuse(hemi.tris(t, 2))) { + if (inuse(hemi.itris(t, 0)) && + inuse(hemi.itris(t, 1)) && + inuse(hemi.itris(t, 2))) { useTrisIdx.append(t); } } hemi.nuse_tri = useTrisIdx.size(); - hemi.use_tris.resize(hemi.nuse_tri, 3); + hemi.use_itris.resize(hemi.nuse_tri, 3); for (int i = 0; i < hemi.nuse_tri; ++i) { - hemi.use_tris.row(i) = hemi.tris.row(useTrisIdx[i]); + hemi.use_itris.row(i) = hemi.itris.row(useTrisIdx[i]); } // Add geometry information (normals, triangle centers, etc.) diff --git a/src/applications/mne_rt_server/mne_rt_server/main.cpp b/src/applications/mne_rt_server/mne_rt_server/main.cpp index f7c8f8ec206..f2eed6b6d33 100644 --- a/src/applications/mne_rt_server/mne_rt_server/main.cpp +++ b/src/applications/mne_rt_server/mne_rt_server/main.cpp @@ -107,19 +107,19 @@ int main(int argc, char *argv[]) stream << QString("simFile = %1").arg(parser.value(inFileOpt));; file.close(); - qInfo() << QString("[MneRtServer::main] Streaming file %1").arg(parser.value(inFileOpt)); + qInfo() << QString("[MNERtServer::main] Streaming file %1").arg(parser.value(inFileOpt)); } else { - qWarning() << QString("[MneRtServer::main] Could not open %1").arg(QCoreApplication::applicationDirPath() + "/../resources/mne_rt_server/plugins/fiffsimulator/FiffSimulation.cfg"); + qWarning() << QString("[MNERtServer::main] Could not open %1").arg(QCoreApplication::applicationDirPath() + "/../resources/mne_rt_server/plugins/fiffsimulator/FiffSimulation.cfg"); } } else { - qWarning("[MneRtServer::main] Provided file does not exist. Falling back to default one."); + qWarning("[MNERtServer::main] Provided file does not exist. Falling back to default one."); if (file.open(QIODevice::Truncate | QIODevice::Text | QIODevice::WriteOnly)) { QTextStream stream(&file); stream << QString("simFile = /../resources/data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif"); file.close(); } else { - qWarning() << QString("[MneRtServer::main] Could not open %1").arg(QCoreApplication::applicationDirPath() + "/../resources/mne_rt_server/plugins/fiffsimulator/FiffSimulation.cfg"); + qWarning() << QString("[MNERtServer::main] Could not open %1").arg(QCoreApplication::applicationDirPath() + "/../resources/mne_rt_server/plugins/fiffsimulator/FiffSimulation.cfg"); } } } diff --git a/src/applications/mne_scan/libs/scDisp/realtime3dwidget.cpp b/src/applications/mne_scan/libs/scDisp/realtime3dwidget.cpp index 7a2cd87f191..0d704b11c77 100644 --- a/src/applications/mne_scan/libs/scDisp/realtime3dwidget.cpp +++ b/src/applications/mne_scan/libs/scDisp/realtime3dwidget.cpp @@ -60,6 +60,7 @@ #include #include +#include #include #include @@ -267,26 +268,25 @@ void RealTime3DWidget::alignFiducials(const QString& sFilePath) void RealTime3DWidget::alignFiducials(QSharedPointer pDigData) { - std::unique_ptr pMneMshDisplaySurfaceSet = std::make_unique(); + std::unique_ptr pMneMshDisplaySurfaceSet = std::make_unique(); pMneMshDisplaySurfaceSet->add_bem_surface(QCoreApplication::applicationDirPath() + "/../resources/general/hpiAlignment/fsaverage-head.fif", FIFFV_BEM_SURF_ID_HEAD, "head", 1, 1); - MneMshDisplaySurface* surface = pMneMshDisplaySurfaceSet->surfs[0].get(); + MNEMshDisplaySurface* surface = pMneMshDisplaySurfaceSet->surfs[0].get(); QFile t_fileDigDataReference(QCoreApplication::applicationDirPath() + "/../resources/general/hpiAlignment/fsaverage-fiducials.fif"); Eigen::Vector3f scales; QScopedPointer t_digDataReference(new FiffDigitizerData(t_fileDigDataReference)); - MneSurfaceOrVolume::align_fiducials(*pDigData, - *t_digDataReference, - surface, - 10, - 1, - 0, - scales); + surface->align_fiducials(*pDigData, + *t_digDataReference, + 10, + 1, + 0, + scales); QMatrix4x4 invMat = calculateInverseMatrix(pDigData, scales[0]); diff --git a/src/applications/mne_scan/libs/scMeas/realtimesourceestimate.h b/src/applications/mne_scan/libs/scMeas/realtimesourceestimate.h index 69c493efb62..a87321176e9 100644 --- a/src/applications/mne_scan/libs/scMeas/realtimesourceestimate.h +++ b/src/applications/mne_scan/libs/scMeas/realtimesourceestimate.h @@ -50,8 +50,8 @@ #include #include -#include -#include +#include +#include #include //============================================================================================================= diff --git a/src/applications/mne_scan/plugins/fiffsimulator/FormFiles/fiffsimulatorsetupwidget.h b/src/applications/mne_scan/plugins/fiffsimulator/FormFiles/fiffsimulatorsetupwidget.h index b5e7bb30043..d9a2c3512c7 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/FormFiles/fiffsimulatorsetupwidget.h +++ b/src/applications/mne_scan/plugins/fiffsimulator/FormFiles/fiffsimulatorsetupwidget.h @@ -121,7 +121,7 @@ class FiffSimulatorSetupWidget : public QWidget FiffSimulator* m_pFiffSimulator; /**< a pointer to corresponding mne rt client.*/ - Ui::FiffSimulatorSetupWidgetClass ui; /**< the user interface for the MneRtClientSetupWidget.*/ + Ui::FiffSimulatorSetupWidgetClass ui; /**< the user interface for the MNERtClientSetupWidget.*/ bool m_bIsInit; /**< false when gui is not initialized jet. Prevents gui from already interacting when not initialized. */ }; diff --git a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.h b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.h index dfe7cecd89d..828fd567330 100644 --- a/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.h +++ b/src/applications/mne_scan/plugins/fiffsimulator/fiffsimulatorproducer.h @@ -83,7 +83,7 @@ class FiffSimulatorProducer : public QThread /** * Constructs a FiffSimulatorProducer. * - * @param[in] p_pMneRtClient a pointer to the corresponding MneRtClient. + * @param[in] p_pMneRtClient a pointer to the corresponding MNERtClient. */ FiffSimulatorProducer(FiffSimulator* p_pFiffSimulator); @@ -109,7 +109,7 @@ class FiffSimulatorProducer : public QThread //========================================================================================================= /** - * Stops the MneRtClientProducer by stopping the producer's thread. + * Stops the MNERtClientProducer by stopping the producer's thread. */ void stop(); @@ -136,7 +136,7 @@ class FiffSimulatorProducer : public QThread QSharedPointer m_pRtDataClient; /**< The data client.*/ - FiffSimulator* m_pFiffSimulator; /**< Holds a pointer to corresponding MneRtClient.*/ + FiffSimulator* m_pFiffSimulator; /**< Holds a pointer to corresponding MNERtClient.*/ bool m_bDataClientIsConnected; /**< If the data client is connected.*/ bool m_bFlagInfoRequest; /**< Read Fiff Info flag. */ diff --git a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp index 6c8a43e16de..3801d465f82 100644 --- a/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp +++ b/src/applications/mne_scan/plugins/rtcmne/rtcmne.cpp @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include diff --git a/src/applications/mne_setup_forward_model/main.cpp b/src/applications/mne_setup_forward_model/main.cpp index 88625f9b5fa..4c8163d8e24 100644 --- a/src/applications/mne_setup_forward_model/main.cpp +++ b/src/applications/mne_setup_forward_model/main.cpp @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("mne_setup_forward_model"); QCoreApplication::setApplicationVersion("1.0"); - MneSetupForwardModelSettings settings(&argc, argv); + MNESetupForwardModelSettings settings(&argc, argv); SetupForwardModel setupFwdModel(settings); return setupFwdModel.run(); diff --git a/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.cpp b/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.cpp index f78fe76ff5a..946a105b350 100644 --- a/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.cpp +++ b/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.cpp @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSetupForwardModelSettings class definition. + * @brief MNESetupForwardModelSettings class definition. * */ @@ -57,7 +57,7 @@ using namespace MNESETUPFORWARDMODEL; // DEFINE MEMBER METHODS //============================================================================================================= -MneSetupForwardModelSettings::MneSetupForwardModelSettings(int *argc, char **argv) +MNESetupForwardModelSettings::MNESetupForwardModelSettings(int *argc, char **argv) : m_fScalpConductivity(0.3f) , m_fSkullConductivity(0.006f) , m_fBrainConductivity(0.3f) @@ -224,112 +224,112 @@ MneSetupForwardModelSettings::MneSetupForwardModelSettings(int *argc, char **arg //============================================================================================================= -QString MneSetupForwardModelSettings::subject() const +QString MNESetupForwardModelSettings::subject() const { return m_sSubject; } //============================================================================================================= -QString MneSetupForwardModelSettings::subjectsDir() const +QString MNESetupForwardModelSettings::subjectsDir() const { return m_sSubjectsDir; } //============================================================================================================= -float MneSetupForwardModelSettings::scalpConductivity() const +float MNESetupForwardModelSettings::scalpConductivity() const { return m_fScalpConductivity; } //============================================================================================================= -float MneSetupForwardModelSettings::skullConductivity() const +float MNESetupForwardModelSettings::skullConductivity() const { return m_fSkullConductivity; } //============================================================================================================= -float MneSetupForwardModelSettings::brainConductivity() const +float MNESetupForwardModelSettings::brainConductivity() const { return m_fBrainConductivity; } //============================================================================================================= -QString MneSetupForwardModelSettings::modelName() const +QString MNESetupForwardModelSettings::modelName() const { return m_sModelName; } //============================================================================================================= -bool MneSetupForwardModelSettings::homogeneous() const +bool MNESetupForwardModelSettings::homogeneous() const { return m_bHomogeneous; } //============================================================================================================= -bool MneSetupForwardModelSettings::useSurfFormat() const +bool MNESetupForwardModelSettings::useSurfFormat() const { return m_bUseSurfFormat; } //============================================================================================================= -int MneSetupForwardModelSettings::icoLevel() const +int MNESetupForwardModelSettings::icoLevel() const { return m_iIcoLevel; } //============================================================================================================= -bool MneSetupForwardModelSettings::noSolution() const +bool MNESetupForwardModelSettings::noSolution() const { return m_bNoSolution; } //============================================================================================================= -bool MneSetupForwardModelSettings::swap() const +bool MNESetupForwardModelSettings::swap() const { return m_bSwap; } //============================================================================================================= -bool MneSetupForwardModelSettings::meters() const +bool MNESetupForwardModelSettings::meters() const { return m_bMeters; } //============================================================================================================= -float MneSetupForwardModelSettings::innerShift() const +float MNESetupForwardModelSettings::innerShift() const { return m_fInnerShift; } //============================================================================================================= -float MneSetupForwardModelSettings::outerShift() const +float MNESetupForwardModelSettings::outerShift() const { return m_fOuterShift; } //============================================================================================================= -float MneSetupForwardModelSettings::scalpShift() const +float MNESetupForwardModelSettings::scalpShift() const { return m_fScalpShift; } //============================================================================================================= -bool MneSetupForwardModelSettings::overwrite() const +bool MNESetupForwardModelSettings::overwrite() const { return m_bOverwrite; } diff --git a/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.h b/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.h index 7849ea64554..4800315b095 100644 --- a/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.h +++ b/src/applications/mne_setup_forward_model/mne_setup_forward_model_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSetupForwardModelSettings class declaration. + * @brief MNESetupForwardModelSettings class declaration. * * Parses command-line settings for mne_setup_forward_model. * @@ -64,7 +64,7 @@ namespace MNESETUPFORWARDMODEL { * * @brief Command-line settings for mne_setup_forward_model. */ -class MneSetupForwardModelSettings +class MNESetupForwardModelSettings { public: //========================================================================================================= @@ -74,7 +74,7 @@ class MneSetupForwardModelSettings * @param[in] argc Number of arguments. * @param[in] argv Argument array. */ - MneSetupForwardModelSettings(int *argc, char **argv); + MNESetupForwardModelSettings(int *argc, char **argv); //========================================================================================================= /** diff --git a/src/applications/mne_setup_forward_model/setupforwardmodel.cpp b/src/applications/mne_setup_forward_model/setupforwardmodel.cpp index 73b4d09094f..3e24180e13e 100644 --- a/src/applications/mne_setup_forward_model/setupforwardmodel.cpp +++ b/src/applications/mne_setup_forward_model/setupforwardmodel.cpp @@ -65,7 +65,7 @@ #include -#include +#include #include #include @@ -96,7 +96,7 @@ using namespace Eigen; // DEFINE MEMBER METHODS //============================================================================================================= -SetupForwardModel::SetupForwardModel(const MneSetupForwardModelSettings& settings) +SetupForwardModel::SetupForwardModel(const MNESetupForwardModelSettings& settings) : m_settings(settings) { } @@ -462,12 +462,12 @@ bool SetupForwardModel::readAsciiTriFile(const QString& fileName, int id, float surf.ntri = ntri; surf.coord_frame = FIFFV_COORD_MRI; surf.rr = rr; - surf.tris = tris; + surf.itris = tris; surf.id = id; surf.sigma = sigma; // Compute vertex normals - surf.nn = Surface::compute_normals(surf.rr, surf.tris); + surf.nn = Surface::compute_normals(Eigen::MatrixX3f(surf.rr), Eigen::MatrixX3i(surf.itris)); // Shift vertices if requested if (shift != 0.0f) { @@ -539,12 +539,12 @@ bool SetupForwardModel::readFreeSurferSurf(const QString& fileName, int id, floa surf.ntri = nface; surf.coord_frame = FIFFV_COORD_MRI; surf.rr = verts.block(0, 0, nvert, 3); - surf.tris = faces; + surf.itris = faces; surf.id = id; surf.sigma = sigma; // Compute vertex normals - surf.nn = Surface::compute_normals(surf.rr, surf.tris); + surf.nn = Surface::compute_normals(Eigen::MatrixX3f(surf.rr), Eigen::MatrixX3i(surf.itris)); // Shift vertices if requested if (shift != 0.0f) { @@ -565,7 +565,7 @@ void SetupForwardModel::shiftVertices(MNEBemSurface& surf, float shift) const } // Recompute normals after shifting - surf.nn = Surface::compute_normals(surf.rr, surf.tris); + surf.nn = Surface::compute_normals(Eigen::MatrixX3f(surf.rr), Eigen::MatrixX3i(surf.itris)); printf("Surface vertices shifted by %6.1f mm.\n", 1000.0f * shift); } @@ -638,9 +638,9 @@ bool SetupForwardModel::exportSurfFile(const MNEBemSurface& surf, // Triangle vertex indices (as int32, 0-based) for (int k = 0; k < surf.ntri; ++k) { - ds << qint32(surf.tris(k, 0)) - << qint32(surf.tris(k, 1)) - << qint32(surf.tris(k, 2)); + ds << qint32(surf.itris(k, 0)) + << qint32(surf.itris(k, 1)) + << qint32(surf.itris(k, 2)); } file.close(); @@ -711,7 +711,7 @@ bool SetupForwardModel::prepareBemSolution(const QString& bemFile, for (int k = 0; k < bemModel->nsurf; ++k) { stream->start_block(FIFFB_BEM_SURF); - MneSurfaceOld* s = bemModel->surfs[k]; + MNESurface* s = bemModel->surfs[k]; // Surface ID int surfId = s->id; diff --git a/src/applications/mne_setup_forward_model/setupforwardmodel.h b/src/applications/mne_setup_forward_model/setupforwardmodel.h index c9c954fcfce..a93ab4ae59e 100644 --- a/src/applications/mne_setup_forward_model/setupforwardmodel.h +++ b/src/applications/mne_setup_forward_model/setupforwardmodel.h @@ -68,7 +68,7 @@ namespace MNESETUPFORWARDMODEL { // FORWARD DECLARATIONS //============================================================================================================= -class MneSetupForwardModelSettings; +class MNESetupForwardModelSettings; //============================================================================================================= /** @@ -93,7 +93,7 @@ class SetupForwardModel * * @param[in] settings The parsed command-line settings. */ - SetupForwardModel(const MneSetupForwardModelSettings& settings); + SetupForwardModel(const MNESetupForwardModelSettings& settings); //========================================================================================================= /** @@ -206,7 +206,7 @@ class SetupForwardModel //========================================================================================================= - const MneSetupForwardModelSettings& m_settings; /**< Command-line settings. */ + const MNESetupForwardModelSettings& m_settings; /**< Command-line settings. */ }; } // namespace MNESETUPFORWARDMODEL diff --git a/src/applications/mne_setup_mri/main.cpp b/src/applications/mne_setup_mri/main.cpp index fb0abb5770a..3b9784a2769 100644 --- a/src/applications/mne_setup_mri/main.cpp +++ b/src/applications/mne_setup_mri/main.cpp @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("mne_setup_mri"); QCoreApplication::setApplicationVersion("1.0"); - MneSetupMriSettings settings(&argc, argv); + MNESetupMriSettings settings(&argc, argv); SetupMri setupMri(settings); return setupMri.run(); diff --git a/src/applications/mne_setup_mri/mne_setup_mri_settings.cpp b/src/applications/mne_setup_mri/mne_setup_mri_settings.cpp index 87c5bf5f5ec..04770837bad 100644 --- a/src/applications/mne_setup_mri/mne_setup_mri_settings.cpp +++ b/src/applications/mne_setup_mri/mne_setup_mri_settings.cpp @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSetupMriSettings class definition. + * @brief MNESetupMriSettings class definition. * */ @@ -55,7 +55,7 @@ using namespace MNESETUPMRI; // DEFINE MEMBER METHODS //============================================================================================================= -MneSetupMriSettings::MneSetupMriSettings(int *argc, char **argv) +MNESetupMriSettings::MNESetupMriSettings(int *argc, char **argv) : m_bOverwrite(false) , m_bVerbose(false) { @@ -136,35 +136,35 @@ MneSetupMriSettings::MneSetupMriSettings(int *argc, char **argv) //============================================================================================================= -QString MneSetupMriSettings::subject() const +QString MNESetupMriSettings::subject() const { return m_sSubject; } //============================================================================================================= -QString MneSetupMriSettings::subjectsDir() const +QString MNESetupMriSettings::subjectsDir() const { return m_sSubjectsDir; } //============================================================================================================= -QStringList MneSetupMriSettings::mriSets() const +QStringList MNESetupMriSettings::mriSets() const { return m_slMriSets; } //============================================================================================================= -bool MneSetupMriSettings::overwrite() const +bool MNESetupMriSettings::overwrite() const { return m_bOverwrite; } //============================================================================================================= -bool MneSetupMriSettings::verbose() const +bool MNESetupMriSettings::verbose() const { return m_bVerbose; } diff --git a/src/applications/mne_setup_mri/mne_setup_mri_settings.h b/src/applications/mne_setup_mri/mne_setup_mri_settings.h index b06919a9251..e14adc3501b 100644 --- a/src/applications/mne_setup_mri/mne_setup_mri_settings.h +++ b/src/applications/mne_setup_mri/mne_setup_mri_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSetupMriSettings class declaration. + * @brief MNESetupMriSettings class declaration. * */ @@ -58,7 +58,7 @@ namespace MNESETUPMRI { * * @brief Command-line settings for mne_setup_mri. */ -class MneSetupMriSettings +class MNESetupMriSettings { public: //========================================================================================================= @@ -68,7 +68,7 @@ class MneSetupMriSettings * @param[in] argc Number of arguments. * @param[in] argv Argument array. */ - MneSetupMriSettings(int *argc, char **argv); + MNESetupMriSettings(int *argc, char **argv); //========================================================================================================= /** diff --git a/src/applications/mne_setup_mri/setupmri.cpp b/src/applications/mne_setup_mri/setupmri.cpp index a14d9991339..ec8eca5bf12 100644 --- a/src/applications/mne_setup_mri/setupmri.cpp +++ b/src/applications/mne_setup_mri/setupmri.cpp @@ -76,7 +76,7 @@ using namespace FIFFLIB; // DEFINE MEMBER METHODS //============================================================================================================= -SetupMri::SetupMri(const MneSetupMriSettings& settings) +SetupMri::SetupMri(const MNESetupMriSettings& settings) : m_settings(settings) { } diff --git a/src/applications/mne_setup_mri/setupmri.h b/src/applications/mne_setup_mri/setupmri.h index 643888af1b3..0e6857f9981 100644 --- a/src/applications/mne_setup_mri/setupmri.h +++ b/src/applications/mne_setup_mri/setupmri.h @@ -70,7 +70,7 @@ namespace MNESETUPMRI { // FORWARD DECLARATIONS //============================================================================================================= -class MneSetupMriSettings; +class MNESetupMriSettings; //============================================================================================================= /** @@ -97,7 +97,7 @@ class SetupMri * * @param[in] settings The parsed command-line settings. */ - SetupMri(const MneSetupMriSettings& settings); + SetupMri(const MNESetupMriSettings& settings); //========================================================================================================= /** @@ -120,7 +120,7 @@ class SetupMri //========================================================================================================= - const MneSetupMriSettings& m_settings; /**< Command-line settings. */ + const MNESetupMriSettings& m_settings; /**< Command-line settings. */ }; } // namespace MNESETUPMRI diff --git a/src/applications/mne_show_fiff/main.cpp b/src/applications/mne_show_fiff/main.cpp index bdd95d48ee9..faf1e42959a 100644 --- a/src/applications/mne_show_fiff/main.cpp +++ b/src/applications/mne_show_fiff/main.cpp @@ -78,8 +78,8 @@ int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); - MneShowFiffSettings settings(&argc,argv); - MneFiffExpSet expSet = MneFiffExpSet::read_fiff_explanations(QCoreApplication::applicationDirPath()+"/resources/general/explanations/fiff_explanations.txt"); + MNEShowFiffSettings settings(&argc,argv); + MNEFiffExpSet expSet = MNEFiffExpSet::read_fiff_explanations(QCoreApplication::applicationDirPath()+"/resources/general/explanations/fiff_explanations.txt"); expSet.show_fiff_contents(stdout, settings); return 0; diff --git a/src/applications/mne_show_fiff/mne_fiff_exp.cpp b/src/applications/mne_show_fiff/mne_fiff_exp.cpp index d6289ebcfd4..f8e6e55d745 100644 --- a/src/applications/mne_show_fiff/mne_fiff_exp.cpp +++ b/src/applications/mne_show_fiff/mne_fiff_exp.cpp @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief Definition of the MneFiffExp Class. + * @brief Definition of the MNEFiffExp Class. * */ @@ -54,14 +54,14 @@ using namespace SHOWFIFF; // DEFINE MEMBER METHODS //============================================================================================================= -MneFiffExp::MneFiffExp() +MNEFiffExp::MNEFiffExp() { } //************************************************************************************************************* -MneFiffExp::MneFiffExp(const MneFiffExp& p_MneFiffExp) +MNEFiffExp::MNEFiffExp(const MNEFiffExp& p_MneFiffExp) : exclass(p_MneFiffExp.exclass) , kind(p_MneFiffExp.kind) , text(p_MneFiffExp.text) @@ -71,7 +71,7 @@ MneFiffExp::MneFiffExp(const MneFiffExp& p_MneFiffExp) //************************************************************************************************************* -MneFiffExp::~MneFiffExp() +MNEFiffExp::~MNEFiffExp() { } @@ -79,7 +79,7 @@ MneFiffExp::~MneFiffExp() //************************************************************************************************************* -bool MneFiffExp::comp_exp(const MneFiffExp &ex1, const MneFiffExp &ex2) +bool MNEFiffExp::comp_exp(const MNEFiffExp &ex1, const MNEFiffExp &ex2) { if (ex1.exclass == ex2.exclass) { if (ex1.kind > ex2.kind) diff --git a/src/applications/mne_show_fiff/mne_fiff_exp.h b/src/applications/mne_show_fiff/mne_fiff_exp.h index 11542f58cfd..387e153fa60 100644 --- a/src/applications/mne_show_fiff/mne_fiff_exp.h +++ b/src/applications/mne_show_fiff/mne_fiff_exp.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneFiffExp class declaration. + * @brief MNEFiffExp class declaration. * */ @@ -73,17 +73,17 @@ namespace SHOWFIFF * * @brief Mne Fiff Explanation description */ -class MneFiffExp +class MNEFiffExp { public: - typedef QSharedPointer SPtr; /**< Shared pointer type for MneFiffExp. */ - typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MneFiffExp. */ + typedef QSharedPointer SPtr; /**< Shared pointer type for MNEFiffExp. */ + typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MNEFiffExp. */ //========================================================================================================= /** * Constructs the Mne Fiff Explanation */ - MneFiffExp(); + MNEFiffExp(); //========================================================================================================= /** @@ -91,22 +91,22 @@ class MneFiffExp * * @param[in] p_MneFiffExp Mne Fiff Explanation which should be copied */ - MneFiffExp(const MneFiffExp& p_MneFiffExp); + MNEFiffExp(const MNEFiffExp& p_MneFiffExp); //========================================================================================================= /** * Destroys the Mne Fiff Explanation */ - ~MneFiffExp(); + ~MNEFiffExp(); //========================================================================================================= /** * Compares if Explanation ex1 is lesser than ex2 * - * @param[in] ex1 MneFiffExp which should be checked wheter it is lesser than ex2. - * @param[in] ex2 MneFiffExp which should be checked wheter it is larger than ex1. + * @param[in] ex1 MNEFiffExp which should be checked wheter it is lesser than ex2. + * @param[in] ex2 MNEFiffExp which should be checked wheter it is larger than ex1. */ - static bool comp_exp(const MneFiffExp& ex1, const MneFiffExp& ex2); + static bool comp_exp(const MNEFiffExp& ex1, const MNEFiffExp& ex2); public: int exclass; /**< Class of this explanation */ diff --git a/src/applications/mne_show_fiff/mne_fiff_exp_set.cpp b/src/applications/mne_show_fiff/mne_fiff_exp_set.cpp index f0837a4cee2..ddbec6028af 100644 --- a/src/applications/mne_show_fiff/mne_fiff_exp_set.cpp +++ b/src/applications/mne_show_fiff/mne_fiff_exp_set.cpp @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief Definition of the MneFiffExpSet class. + * @brief Definition of the MNEFiffExpSet class. * */ @@ -89,14 +89,14 @@ using namespace FIFFLIB; // DEFINE MEMBER METHODS //============================================================================================================= -MneFiffExpSet::MneFiffExpSet() +MNEFiffExpSet::MNEFiffExpSet() { } //************************************************************************************************************* -MneFiffExpSet::MneFiffExpSet(const MneFiffExpSet &p_MneFiffExpSet) +MNEFiffExpSet::MNEFiffExpSet(const MNEFiffExpSet &p_MneFiffExpSet) : m_qListExp(p_MneFiffExpSet.m_qListExp) { @@ -105,7 +105,7 @@ MneFiffExpSet::MneFiffExpSet(const MneFiffExpSet &p_MneFiffExpSet) //************************************************************************************************************* -MneFiffExpSet::~MneFiffExpSet() +MNEFiffExpSet::~MNEFiffExpSet() { } @@ -113,11 +113,11 @@ MneFiffExpSet::~MneFiffExpSet() //************************************************************************************************************* -const MneFiffExp& MneFiffExpSet::operator[] (int idx) const +const MNEFiffExp& MNEFiffExpSet::operator[] (int idx) const { if (idx >= m_qListExp.length()) { - qWarning("Warning: Required MneFiffExp doesn't exist! Returning MneFiffExp '0'."); + qWarning("Warning: Required MNEFiffExp doesn't exist! Returning MNEFiffExp '0'."); idx=0; } return m_qListExp[idx]; @@ -126,11 +126,11 @@ const MneFiffExp& MneFiffExpSet::operator[] (int idx) const //************************************************************************************************************* -MneFiffExp& MneFiffExpSet::operator[] (int idx) +MNEFiffExp& MNEFiffExpSet::operator[] (int idx) { if (idx >= m_qListExp.length()) { - qWarning("Warning: Required MneFiffExp doesn't exist! Returning MneFiffExp '0'."); + qWarning("Warning: Required MNEFiffExp doesn't exist! Returning MNEFiffExp '0'."); idx = 0; } return m_qListExp[idx]; @@ -139,7 +139,7 @@ MneFiffExp& MneFiffExpSet::operator[] (int idx) //************************************************************************************************************* -MneFiffExpSet &MneFiffExpSet::operator<<(const MneFiffExp &p_MneFiffExp) +MNEFiffExpSet &MNEFiffExpSet::operator<<(const MNEFiffExp &p_MneFiffExp) { this->m_qListExp.append(p_MneFiffExp); return *this; @@ -148,11 +148,11 @@ MneFiffExpSet &MneFiffExpSet::operator<<(const MneFiffExp &p_MneFiffExp) //************************************************************************************************************* -MneFiffExpSet MneFiffExpSet::read_fiff_explanations(const QString &name) +MNEFiffExpSet MNEFiffExpSet::read_fiff_explanations(const QString &name) { QFile file(name); - MneFiffExpSet res; + MNEFiffExpSet res; int exclass,kind; QString text; @@ -188,7 +188,7 @@ MneFiffExpSet MneFiffExpSet::read_fiff_explanations(const QString &name) text.remove("\""); - MneFiffExp exp; + MNEFiffExp exp; exp.exclass = exclass; exp.kind = kind; exp.text = text; @@ -210,7 +210,7 @@ MneFiffExpSet MneFiffExpSet::read_fiff_explanations(const QString &name) //************************************************************************************************************* -void MneFiffExpSet::list_fiff_explanations(FILE *out) +void MNEFiffExpSet::list_fiff_explanations(FILE *out) { for (int k = 0; k < this->size(); k++) fprintf(out,"%d %d \"%s\"\n",this->m_qListExp[k].exclass,this->m_qListExp[k].kind,this->m_qListExp[k].text.toUtf8().constData()); @@ -219,14 +219,14 @@ void MneFiffExpSet::list_fiff_explanations(FILE *out) //************************************************************************************************************* -QList::const_iterator MneFiffExpSet::find_fiff_explanation(int exclass, int kind) const +QList::const_iterator MNEFiffExpSet::find_fiff_explanation(int exclass, int kind) const { - MneFiffExp one; + MNEFiffExp one; one.exclass = exclass; one.kind = kind; - auto it = std::lower_bound(this->m_qListExp.begin(), this->m_qListExp.end(), one, MneFiffExp::comp_exp); - if (it != this->m_qListExp.end() && !MneFiffExp::comp_exp(one, *it)) { + auto it = std::lower_bound(this->m_qListExp.begin(), this->m_qListExp.end(), one, MNEFiffExp::comp_exp); + if (it != this->m_qListExp.end() && !MNEFiffExp::comp_exp(one, *it)) { return it; } return this->m_qListExp.end(); @@ -235,7 +235,7 @@ QList::const_iterator MneFiffExpSet::find_fiff_explanation(int excla //************************************************************************************************************* -QList::const_iterator MneFiffExpSet::constEnd() const +QList::const_iterator MNEFiffExpSet::constEnd() const { return m_qListExp.constEnd(); } @@ -245,7 +245,7 @@ QList::const_iterator MneFiffExpSet::constEnd() const //************************************************************************************************************* -void MneFiffExpSet::print_file_id (FILE *out, FiffTag::SPtr tag) +void MNEFiffExpSet::print_file_id (FILE *out, FiffTag::SPtr tag) { FiffId id = tag->toFiffID(); struct tm *ltime; @@ -265,10 +265,10 @@ void MneFiffExpSet::print_file_id (FILE *out, FiffTag::SPtr tag) //************************************************************************************************************* -void MneFiffExpSet::print_ch_info (FILE *out, FiffTag::SPtr tag) +void MNEFiffExpSet::print_ch_info (FILE *out, FiffTag::SPtr tag) { FiffChInfo info = tag->toChInfo(); - QList::const_iterator exp; + QList::const_iterator exp; QString text1, text2, text3; exp = this->find_fiff_explanation(CLASS_UNIT, info.unit); @@ -287,7 +287,7 @@ void MneFiffExpSet::print_ch_info (FILE *out, FiffTag::SPtr tag) //************************************************************************************************************* -void MneFiffExpSet::print_transform(FILE *out, FiffTag::SPtr tag) +void MNEFiffExpSet::print_transform(FILE *out, FiffTag::SPtr tag) { FiffCoordTrans t = tag->toCoordTrans(); int k, p; @@ -311,7 +311,7 @@ void MneFiffExpSet::print_transform(FILE *out, FiffTag::SPtr tag) //************************************************************************************************************* -void MneFiffExpSet::print_dig_point(FILE *out, FiffTag::SPtr tag) +void MNEFiffExpSet::print_dig_point(FILE *out, FiffTag::SPtr tag) { FiffDigPoint point = tag->toDigPoint(); switch (point.kind) { @@ -334,7 +334,7 @@ void MneFiffExpSet::print_dig_point(FILE *out, FiffTag::SPtr tag) //************************************************************************************************************* -void MneFiffExpSet::print_matrix(FILE *out, FiffStream::SPtr stream, FiffDirEntry::SPtr this_ent) +void MNEFiffExpSet::print_matrix(FILE *out, FiffStream::SPtr stream, FiffDirEntry::SPtr this_ent) { // Simplified matrix info since we don't want to read the whole tag yet if it's large, // but FiffStream has some matrix reading logic. @@ -344,7 +344,7 @@ void MneFiffExpSet::print_matrix(FILE *out, FiffStream::SPtr stream, FiffDirEntr //************************************************************************************************************* -bool MneFiffExpSet::show_fiff_contents(FILE *out, const MneShowFiffSettings &settings) +bool MNEFiffExpSet::show_fiff_contents(FILE *out, const MNEShowFiffSettings &settings) { return show_fiff_contents(out,settings.inname, settings.verbose,settings.tags,settings.indent,settings.long_strings,settings.blocks_only); } @@ -352,7 +352,7 @@ bool MneFiffExpSet::show_fiff_contents(FILE *out, const MneShowFiffSettings &set //************************************************************************************************************* -bool MneFiffExpSet::show_fiff_contents(FILE *out, const QString &name, bool verbose, const QList &tags, int indent_step, bool long_strings, bool blocks_only) +bool MNEFiffExpSet::show_fiff_contents(FILE *out, const QString &name, bool verbose, const QList &tags, int indent_step, bool long_strings, bool blocks_only) { QFile file(name); FiffStream::SPtr stream(new FiffStream(&file)); @@ -367,7 +367,7 @@ bool MneFiffExpSet::show_fiff_contents(FILE *out, const QString &name, bool verb bool show_it = false; QString s; bool output_taginfo = false; - QList::const_iterator exp; + QList::const_iterator exp; if (!stream->open()) return false; @@ -623,12 +623,12 @@ bool MneFiffExpSet::show_fiff_contents(FILE *out, const QString &name, bool verb //************************************************************************************************************* -void MneFiffExpSet::sort_fiff_explanations() +void MNEFiffExpSet::sort_fiff_explanations() { if (this->size() == 0) return; - std::sort(this->m_qListExp.begin(), this->m_qListExp.end(), MneFiffExp::comp_exp); + std::sort(this->m_qListExp.begin(), this->m_qListExp.end(), MNEFiffExp::comp_exp); return; } diff --git a/src/applications/mne_show_fiff/mne_fiff_exp_set.h b/src/applications/mne_show_fiff/mne_fiff_exp_set.h index 4a312b66090..a30653930f6 100644 --- a/src/applications/mne_show_fiff/mne_fiff_exp_set.h +++ b/src/applications/mne_show_fiff/mne_fiff_exp_set.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneFiffExpSet class declaration. + * @brief MNEFiffExpSet class declaration. * */ @@ -81,7 +81,7 @@ namespace SHOWFIFF // FORWARD DECLARATIONS //============================================================================================================= -class MneShowFiffSettings; +class MNEShowFiffSettings; //============================================================================================================= @@ -91,18 +91,18 @@ class MneShowFiffSettings; * @brief Holds a set of Electric Current Dipoles. */ -class MneFiffExpSet +class MNEFiffExpSet { public: - typedef QSharedPointer SPtr; /**< Shared pointer type for MneFiffExpSet. */ - typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MneFiffExpSet. */ + typedef QSharedPointer SPtr; /**< Shared pointer type for MNEFiffExpSet. */ + typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MNEFiffExpSet. */ //========================================================================================================= /** * Constructs an MNE Fiff Explanation Set object. */ - MneFiffExpSet(); + MNEFiffExpSet(); //========================================================================================================= /** @@ -110,51 +110,51 @@ class MneFiffExpSet * * @param[in] p_MneFiffExpSet MNE Fiff Explanation Set which should be copied */ - MneFiffExpSet(const MneFiffExpSet &p_MneFiffExpSet); + MNEFiffExpSet(const MNEFiffExpSet &p_MneFiffExpSet); //========================================================================================================= /** * Destroys the Electric Current Dipole description */ - ~MneFiffExpSet(); + ~MNEFiffExpSet(); //========================================================================================================= /** - * Returns the number of stored MneFiffExps + * Returns the number of stored MNEFiffExps * - * @return number of stored MneFiffExps + * @return number of stored MNEFiffExps */ inline qint32 size() const; //========================================================================================================= /** - * Subscript operator [] to access MneFiffExp by index + * Subscript operator [] to access MNEFiffExp by index * - * @param[in] idx the MneFiffExp index. + * @param[in] idx the MNEFiffExp index. * - * @return MneFiffExp related to the parameter index. + * @return MNEFiffExp related to the parameter index. */ - const MneFiffExp& operator[] (int idx) const; + const MNEFiffExp& operator[] (int idx) const; //========================================================================================================= /** - * Subscript operator [] to access MneFiffExp by index + * Subscript operator [] to access MNEFiffExp by index * - * @param[in] idx the MneFiffExp index. + * @param[in] idx the MNEFiffExp index. * - * @return MneFiffExp related to the parameter index. + * @return MNEFiffExp related to the parameter index. */ - MneFiffExp& operator[] (int idx); + MNEFiffExp& operator[] (int idx); //========================================================================================================= /** - * Subscript operator << to add a new MneFiffExp + * Subscript operator << to add a new MNEFiffExp * - * @param[in] p_MneFiffExp MneFiffExp to be added + * @param[in] p_MneFiffExp MNEFiffExp to be added * - * @return MneFiffExpSet + * @return MNEFiffExpSet */ - MneFiffExpSet& operator<< (const MneFiffExp& p_MneFiffExp); + MNEFiffExpSet& operator<< (const MNEFiffExp& p_MneFiffExp); //========================================================================================================= /** @@ -163,7 +163,7 @@ class MneFiffExpSet * * @param[in] name File to read */ - static MneFiffExpSet read_fiff_explanations(const QString& name); + static MNEFiffExpSet read_fiff_explanations(const QString& name); //========================================================================================================= /** @@ -182,7 +182,7 @@ class MneFiffExpSet * @param[in] exclass explanation class to find * @param[in] kind kind to find */ - QList::const_iterator find_fiff_explanation(int exclass, int kind) const; + QList::const_iterator find_fiff_explanation(int exclass, int kind) const; //========================================================================================================= /** @@ -190,7 +190,7 @@ class MneFiffExpSet * * @return const STL-style iterator pointing to the item after the last item */ - QList::const_iterator constEnd() const; + QList::const_iterator constEnd() const; //========================================================================================================= /** @@ -201,7 +201,7 @@ class MneFiffExpSet * * @return true if succeeded */ - bool show_fiff_contents (FILE *out, const MneShowFiffSettings& settings); + bool show_fiff_contents (FILE *out, const MNEShowFiffSettings& settings); //========================================================================================================= /** @@ -239,7 +239,7 @@ class MneFiffExpSet void print_matrix(FILE *out, FIFFLIB::FiffStream::SPtr stream, FIFFLIB::FiffDirEntry::SPtr this_ent); private: - QList m_qListExp; /**< List of Explanations. */ + QList m_qListExp; /**< List of Explanations. */ // ### OLD STRUCT ### // typedef struct { @@ -254,7 +254,7 @@ class MneFiffExpSet // INLINE DEFINITIONS //============================================================================================================= -qint32 MneFiffExpSet::size() const +qint32 MNEFiffExpSet::size() const { return m_qListExp.size(); } diff --git a/src/applications/mne_show_fiff/mne_show_fiff_settings.cpp b/src/applications/mne_show_fiff/mne_show_fiff_settings.cpp index 7ed85c0d051..97194f7a1fc 100644 --- a/src/applications/mne_show_fiff/mne_show_fiff_settings.cpp +++ b/src/applications/mne_show_fiff/mne_show_fiff_settings.cpp @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief Definition of the MneShowFiffSettings class. + * @brief Definition of the MNEShowFiffSettings class. * */ @@ -67,7 +67,7 @@ using namespace SHOWFIFF; // DEFINE MEMBER METHODS //============================================================================================================= -MneShowFiffSettings::MneShowFiffSettings() +MNEShowFiffSettings::MNEShowFiffSettings() : indent(-1) , verbose(false) , long_strings(false) @@ -79,7 +79,7 @@ MneShowFiffSettings::MneShowFiffSettings() //************************************************************************************************************* -MneShowFiffSettings::MneShowFiffSettings(int *argc,char **argv) +MNEShowFiffSettings::MNEShowFiffSettings(int *argc,char **argv) : indent(-1) , verbose(false) , long_strings(false) @@ -96,7 +96,7 @@ MneShowFiffSettings::MneShowFiffSettings(int *argc,char **argv) //************************************************************************************************************* -MneShowFiffSettings::~MneShowFiffSettings() +MNEShowFiffSettings::~MNEShowFiffSettings() { //ToDo Garbage collection } @@ -104,7 +104,7 @@ MneShowFiffSettings::~MneShowFiffSettings() //************************************************************************************************************* -void MneShowFiffSettings::checkIntegrity() +void MNEShowFiffSettings::checkIntegrity() { if (this->indent < 0) this->indent = this->verbose ? 0 : DEFAULT_INDENT; @@ -113,7 +113,7 @@ void MneShowFiffSettings::checkIntegrity() //************************************************************************************************************* -void MneShowFiffSettings::usage(char *name) +void MNEShowFiffSettings::usage(char *name) { fprintf(stderr,"usage: %s [options]\n",name); fprintf(stderr,"List contents of a fif file to stdout\n"); @@ -131,7 +131,7 @@ void MneShowFiffSettings::usage(char *name) //************************************************************************************************************* -bool MneShowFiffSettings::check_unrecognized_args(int argc, char **argv) +bool MNEShowFiffSettings::check_unrecognized_args(int argc, char **argv) { int k; @@ -149,7 +149,7 @@ bool MneShowFiffSettings::check_unrecognized_args(int argc, char **argv) //************************************************************************************************************* -bool MneShowFiffSettings::check_args (int *argc,char **argv) +bool MNEShowFiffSettings::check_args (int *argc,char **argv) { int k; int p; diff --git a/src/applications/mne_show_fiff/mne_show_fiff_settings.h b/src/applications/mne_show_fiff/mne_show_fiff_settings.h index 23804d93370..529c3a3daf6 100644 --- a/src/applications/mne_show_fiff/mne_show_fiff_settings.h +++ b/src/applications/mne_show_fiff/mne_show_fiff_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneShowFiffSettings class declaration. + * @brief MNEShowFiffSettings class declaration. * */ @@ -79,17 +79,17 @@ namespace SHOWFIFF * * @brief Show Fiff setting implementation */ -class MneShowFiffSettings +class MNEShowFiffSettings { public: - typedef QSharedPointer SPtr; /**< Shared pointer type for MneShowFiffSettings. */ - typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MneShowFiffSettings. */ + typedef QSharedPointer SPtr; /**< Shared pointer type for MNEShowFiffSettings. */ + typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for MNEShowFiffSettings. */ //========================================================================================================= /** * Default Constructor */ - explicit MneShowFiffSettings(); + explicit MNEShowFiffSettings(); //========================================================================================================= /** @@ -98,13 +98,13 @@ class MneShowFiffSettings * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started. * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started. */ - explicit MneShowFiffSettings(int *argc,char **argv); + explicit MNEShowFiffSettings(int *argc,char **argv); //========================================================================================================= /** * Destructs the Show Fiff Settings */ - virtual ~MneShowFiffSettings(); + virtual ~MNEShowFiffSettings(); //========================================================================================================= /** diff --git a/src/applications/mne_surf2bem/main.cpp b/src/applications/mne_surf2bem/main.cpp index 0b1199758b6..28d3b393740 100644 --- a/src/applications/mne_surf2bem/main.cpp +++ b/src/applications/mne_surf2bem/main.cpp @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("mne_surf2bem"); QCoreApplication::setApplicationVersion("1.0"); - MneSurf2BemSettings settings(&argc, argv); + MNESurf2BemSettings settings(&argc, argv); Surf2Bem surf2bem(settings); return surf2bem.run(); diff --git a/src/applications/mne_surf2bem/mne_surf2bem_settings.cpp b/src/applications/mne_surf2bem/mne_surf2bem_settings.cpp index 476403a61a4..2b73b025931 100644 --- a/src/applications/mne_surf2bem/mne_surf2bem_settings.cpp +++ b/src/applications/mne_surf2bem/mne_surf2bem_settings.cpp @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSurf2BemSettings class definition. + * @brief MNESurf2BemSettings class definition. * * Command-line parsing replicates the original MNE C tool's behavior * where options like --id, --swap, --shift apply to the most recently @@ -62,7 +62,7 @@ using namespace MNESURF2BEM; // DEFINE MEMBER METHODS //============================================================================================================= -MneSurf2BemSettings::MneSurf2BemSettings(int *argc, char **argv) +MNESurf2BemSettings::MNESurf2BemSettings(int *argc, char **argv) : m_iCoordFrame(FIFFV_COORD_MRI) , m_bCheck(false) , m_bCheckMore(false) @@ -251,42 +251,42 @@ MneSurf2BemSettings::MneSurf2BemSettings(int *argc, char **argv) //============================================================================================================= -const QVector& MneSurf2BemSettings::surfaces() const +const QVector& MNESurf2BemSettings::surfaces() const { return m_surfaces; } //============================================================================================================= -QString MneSurf2BemSettings::outputFile() const +QString MNESurf2BemSettings::outputFile() const { return m_sOutputFile; } //============================================================================================================= -int MneSurf2BemSettings::coordFrame() const +int MNESurf2BemSettings::coordFrame() const { return m_iCoordFrame; } //============================================================================================================= -bool MneSurf2BemSettings::check() const +bool MNESurf2BemSettings::check() const { return m_bCheck; } //============================================================================================================= -bool MneSurf2BemSettings::checkMore() const +bool MNESurf2BemSettings::checkMore() const { return m_bCheckMore; } //============================================================================================================= -bool MneSurf2BemSettings::force() const +bool MNESurf2BemSettings::force() const { return m_bForce; } diff --git a/src/applications/mne_surf2bem/mne_surf2bem_settings.h b/src/applications/mne_surf2bem/mne_surf2bem_settings.h index aaa8d7a0f96..f831330f54f 100644 --- a/src/applications/mne_surf2bem/mne_surf2bem_settings.h +++ b/src/applications/mne_surf2bem/mne_surf2bem_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneSurf2BemSettings class declaration. + * @brief MNESurf2BemSettings class declaration. * */ @@ -97,7 +97,7 @@ struct SurfaceInput * * @brief Command-line settings for mne_surf2bem. */ -class MneSurf2BemSettings +class MNESurf2BemSettings { public: //========================================================================================================= @@ -107,7 +107,7 @@ class MneSurf2BemSettings * @param[in] argc Number of arguments. * @param[in] argv Argument array. */ - MneSurf2BemSettings(int *argc, char **argv); + MNESurf2BemSettings(int *argc, char **argv); //========================================================================================================= /** diff --git a/src/applications/mne_surf2bem/surf2bem.cpp b/src/applications/mne_surf2bem/surf2bem.cpp index f03f9e519bf..c5ec019ddb5 100644 --- a/src/applications/mne_surf2bem/surf2bem.cpp +++ b/src/applications/mne_surf2bem/surf2bem.cpp @@ -79,7 +79,7 @@ using namespace Eigen; // DEFINE MEMBER METHODS //============================================================================================================= -Surf2Bem::Surf2Bem(const MneSurf2BemSettings& settings) +Surf2Bem::Surf2Bem(const MNESurf2BemSettings& settings) : m_settings(settings) { } @@ -286,10 +286,10 @@ bool Surf2Bem::readFreeSurferSurface(const SurfaceInput& input, MNEBemSurface& b bemSurf.ntri = nface; bemSurf.coord_frame = FIFFV_COORD_MRI; bemSurf.rr = verts.block(0, 0, nvert, 3); - bemSurf.tris = faces.block(0, 0, nface, 3); + bemSurf.itris = faces.block(0, 0, nface, 3); // Compute vertex normals - bemSurf.nn = Surface::compute_normals(bemSurf.rr, bemSurf.tris); + bemSurf.nn = Surface::compute_normals(Eigen::MatrixX3f(bemSurf.rr), Eigen::MatrixX3i(bemSurf.itris)); fprintf(stderr, "Read FreeSurfer surface: %d vertices, %d triangles\n", bemSurf.np, bemSurf.ntri); @@ -385,10 +385,10 @@ bool Surf2Bem::readAsciiTriSurface(const SurfaceInput& input, MNEBemSurface& bem bemSurf.np = nvert; bemSurf.ntri = ntri; bemSurf.rr = rr; - bemSurf.tris = tris; + bemSurf.itris = tris; // Compute vertex normals - bemSurf.nn = Surface::compute_normals(bemSurf.rr, bemSurf.tris); + bemSurf.nn = Surface::compute_normals(Eigen::MatrixX3f(bemSurf.rr), Eigen::MatrixX3i(bemSurf.itris)); fprintf(stderr, "Read ASCII triangle surface: %d vertices, %d triangles\n", bemSurf.np, bemSurf.ntri); @@ -413,7 +413,7 @@ bool Surf2Bem::shiftVertices(MNEBemSurface& surf, float shift) } // Recompute normals after shifting - surf.nn = Surface::compute_normals(surf.rr, surf.tris); + surf.nn = Surface::compute_normals(Eigen::MatrixX3f(surf.rr), Eigen::MatrixX3i(surf.itris)); fprintf(stderr, "%s vertex locations shifted by %6.1f mm.\n", qPrintable(SurfaceChecks::getNameOf(surf.id)), diff --git a/src/applications/mne_surf2bem/surf2bem.h b/src/applications/mne_surf2bem/surf2bem.h index 40d744929c3..381884c3447 100644 --- a/src/applications/mne_surf2bem/surf2bem.h +++ b/src/applications/mne_surf2bem/surf2bem.h @@ -71,7 +71,7 @@ namespace MNESURF2BEM { // FORWARD DECLARATIONS //============================================================================================================= -class MneSurf2BemSettings; +class MNESurf2BemSettings; struct SurfaceInput; //============================================================================================================= @@ -97,7 +97,7 @@ class Surf2Bem * * @param[in] settings The parsed command-line settings. */ - Surf2Bem(const MneSurf2BemSettings& settings); + Surf2Bem(const MNESurf2BemSettings& settings); //========================================================================================================= /** @@ -156,7 +156,7 @@ class Surf2Bem //========================================================================================================= - const MneSurf2BemSettings& m_settings; /**< Command-line settings. */ + const MNESurf2BemSettings& m_settings; /**< Command-line settings. */ }; } // namespace MNESURF2BEM diff --git a/src/applications/mne_surf2bem/surfacechecks.cpp b/src/applications/mne_surf2bem/surfacechecks.cpp index 29f5e4dfdca..de58d0ef136 100644 --- a/src/applications/mne_surf2bem/surfacechecks.cpp +++ b/src/applications/mne_surf2bem/surfacechecks.cpp @@ -116,9 +116,9 @@ double SurfaceChecks::sumSolids(const Vector3f& from, const MNEBemSurface& surf) { double totAngle = 0.0; for (int k = 0; k < surf.ntri; ++k) { - Vector3f v0 = surf.rr.row(surf.tris(k, 0)); - Vector3f v1 = surf.rr.row(surf.tris(k, 1)); - Vector3f v2 = surf.rr.row(surf.tris(k, 2)); + Vector3f v0 = surf.rr.row(surf.itris(k, 0)); + Vector3f v1 = surf.rr.row(surf.itris(k, 1)); + Vector3f v2 = surf.rr.row(surf.itris(k, 2)); totAngle += solidAngle(from, v0, v1, v2); } return totAngle; diff --git a/src/applications/mne_watershed_bem/main.cpp b/src/applications/mne_watershed_bem/main.cpp index 7977ca502b8..c9c6cb669c8 100644 --- a/src/applications/mne_watershed_bem/main.cpp +++ b/src/applications/mne_watershed_bem/main.cpp @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("mne_watershed_bem"); QCoreApplication::setApplicationVersion("1.0"); - MneWatershedBemSettings settings(&argc, argv); + MNEWatershedBemSettings settings(&argc, argv); WatershedBem watershedBem(settings); return watershedBem.run(); diff --git a/src/applications/mne_watershed_bem/mne_watershed_bem_settings.cpp b/src/applications/mne_watershed_bem/mne_watershed_bem_settings.cpp index 1df67d779b6..9d10743021c 100644 --- a/src/applications/mne_watershed_bem/mne_watershed_bem_settings.cpp +++ b/src/applications/mne_watershed_bem/mne_watershed_bem_settings.cpp @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneWatershedBemSettings class definition. + * @brief MNEWatershedBemSettings class definition. * */ @@ -56,7 +56,7 @@ using namespace MNEWATERSHEDBEM; // DEFINE MEMBER METHODS //============================================================================================================= -MneWatershedBemSettings::MneWatershedBemSettings(int *argc, char **argv) +MNEWatershedBemSettings::MNEWatershedBemSettings(int *argc, char **argv) : m_sVolume("T1") , m_bOverwrite(false) , m_bAtlas(false) @@ -173,63 +173,63 @@ MneWatershedBemSettings::MneWatershedBemSettings(int *argc, char **argv) //============================================================================================================= -QString MneWatershedBemSettings::subject() const +QString MNEWatershedBemSettings::subject() const { return m_sSubject; } //============================================================================================================= -QString MneWatershedBemSettings::subjectsDir() const +QString MNEWatershedBemSettings::subjectsDir() const { return m_sSubjectsDir; } //============================================================================================================= -QString MneWatershedBemSettings::freeSurferHome() const +QString MNEWatershedBemSettings::freeSurferHome() const { return m_sFreeSurferHome; } //============================================================================================================= -QString MneWatershedBemSettings::volume() const +QString MNEWatershedBemSettings::volume() const { return m_sVolume; } //============================================================================================================= -bool MneWatershedBemSettings::overwrite() const +bool MNEWatershedBemSettings::overwrite() const { return m_bOverwrite; } //============================================================================================================= -bool MneWatershedBemSettings::atlas() const +bool MNEWatershedBemSettings::atlas() const { return m_bAtlas; } //============================================================================================================= -bool MneWatershedBemSettings::gcaAtlas() const +bool MNEWatershedBemSettings::gcaAtlas() const { return m_bGcaAtlas; } //============================================================================================================= -int MneWatershedBemSettings::preflood() const +int MNEWatershedBemSettings::preflood() const { return m_iPreflood; } //============================================================================================================= -bool MneWatershedBemSettings::verbose() const +bool MNEWatershedBemSettings::verbose() const { return m_bVerbose; } diff --git a/src/applications/mne_watershed_bem/mne_watershed_bem_settings.h b/src/applications/mne_watershed_bem/mne_watershed_bem_settings.h index 86420098071..4503b94b839 100644 --- a/src/applications/mne_watershed_bem/mne_watershed_bem_settings.h +++ b/src/applications/mne_watershed_bem/mne_watershed_bem_settings.h @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * - * @brief MneWatershedBemSettings class declaration. + * @brief MNEWatershedBemSettings class declaration. * */ @@ -61,7 +61,7 @@ namespace MNEWATERSHEDBEM { * * @brief Command-line settings for mne_watershed_bem. */ -class MneWatershedBemSettings +class MNEWatershedBemSettings { public: //========================================================================================================= @@ -71,7 +71,7 @@ class MneWatershedBemSettings * @param[in] argc Number of arguments. * @param[in] argv Argument array. */ - MneWatershedBemSettings(int *argc, char **argv); + MNEWatershedBemSettings(int *argc, char **argv); //========================================================================================================= /** diff --git a/src/applications/mne_watershed_bem/watershedbem.cpp b/src/applications/mne_watershed_bem/watershedbem.cpp index 8520474835a..6a9af90cdc8 100644 --- a/src/applications/mne_watershed_bem/watershedbem.cpp +++ b/src/applications/mne_watershed_bem/watershedbem.cpp @@ -87,7 +87,7 @@ using namespace Eigen; // DEFINE MEMBER METHODS //============================================================================================================= -WatershedBem::WatershedBem(const MneWatershedBemSettings& settings) +WatershedBem::WatershedBem(const MNEWatershedBemSettings& settings) : m_settings(settings) { } @@ -361,7 +361,7 @@ bool WatershedBem::convertSurfaces(const QString& wsDir, const QString& mgzFile) if (surf.rr().rows() == 0) { qWarning() << "Surface" << surfPath << "has no vertices."; } else if (m_settings.verbose()) { - printf(" %d vertices, %d triangles\n", (int)surf.rr().rows(), (int)surf.tris().rows()); + printf(" %d vertices, %d triangles\n", (int)surf.rr().rows(), (int)surf.itris().rows()); } } @@ -386,13 +386,13 @@ bool WatershedBem::createBemFif(const QString& surfFile, const QString& fifFile) Surface fsSurface; Surface::read(surfFile, fsSurface, false); - if (fsSurface.rr().rows() == 0 || fsSurface.tris().rows() == 0) { + if (fsSurface.rr().rows() == 0 || fsSurface.itris().rows() == 0) { qCritical() << "Failed to read surface from" << surfFile; return false; } printf("Read surface: %d vertices, %d triangles\n", - (int)fsSurface.rr().rows(), (int)fsSurface.tris().rows()); + (int)fsSurface.rr().rows(), (int)fsSurface.itris().rows()); // // Create BEM surface @@ -402,16 +402,16 @@ bool WatershedBem::createBemFif(const QString& surfFile, const QString& fifFile) MNEBemSurface bemSurface; bemSurface.id = FIFFV_BEM_SURF_ID_HEAD; // 4 = head surface bemSurface.np = fsSurface.rr().rows(); - bemSurface.ntri = fsSurface.tris().rows(); + bemSurface.ntri = fsSurface.itris().rows(); bemSurface.coord_frame = FIFFV_COORD_MRI; bemSurface.sigma = 0.0f; // Default conductivity // Copy vertex coordinates and triangles bemSurface.rr = fsSurface.rr(); - bemSurface.tris = fsSurface.tris(); + bemSurface.itris = fsSurface.itris(); // Compute vertex normals - bemSurface.nn = Surface::compute_normals(bemSurface.rr, bemSurface.tris); + bemSurface.nn = Surface::compute_normals(Eigen::MatrixX3f(bemSurface.rr), Eigen::MatrixX3i(bemSurface.itris)); // // Create BEM and write to FIFF file diff --git a/src/applications/mne_watershed_bem/watershedbem.h b/src/applications/mne_watershed_bem/watershedbem.h index 1e235d5b8be..4e68dec6b35 100644 --- a/src/applications/mne_watershed_bem/watershedbem.h +++ b/src/applications/mne_watershed_bem/watershedbem.h @@ -71,7 +71,7 @@ namespace MNEWATERSHEDBEM { // FORWARD DECLARATIONS //============================================================================================================= -class MneWatershedBemSettings; +class MNEWatershedBemSettings; //============================================================================================================= /** @@ -104,7 +104,7 @@ class WatershedBem * * @param[in] settings The parsed command-line settings. */ - WatershedBem(const MneWatershedBemSettings& settings); + WatershedBem(const MNEWatershedBemSettings& settings); //========================================================================================================= /** @@ -160,7 +160,7 @@ class WatershedBem //========================================================================================================= - const MneWatershedBemSettings& m_settings; /**< Command-line settings. */ + const MNEWatershedBemSettings& m_settings; /**< Command-line settings. */ }; } // namespace MNEWATERSHEDBEM diff --git a/src/examples/ex_clustered_inverse_mne/main.cpp b/src/examples/ex_clustered_inverse_mne/main.cpp index 3375605be81..5e121acbab4 100644 --- a/src/examples/ex_clustered_inverse_mne/main.cpp +++ b/src/examples/ex_clustered_inverse_mne/main.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include diff --git a/src/examples/ex_clustered_inverse_mne_raw/main.cpp b/src/examples/ex_clustered_inverse_mne_raw/main.cpp index 4b33dda9bda..12dd87a06bf 100644 --- a/src/examples/ex_clustered_inverse_mne_raw/main.cpp +++ b/src/examples/ex_clustered_inverse_mne_raw/main.cpp @@ -49,7 +49,7 @@ #include #include -#include +#include #include diff --git a/src/examples/ex_clustered_inverse_pwl_rap_music_raw/main.cpp b/src/examples/ex_clustered_inverse_pwl_rap_music_raw/main.cpp index 5bc8e2ece67..4e9c7d84c82 100644 --- a/src/examples/ex_clustered_inverse_pwl_rap_music_raw/main.cpp +++ b/src/examples/ex_clustered_inverse_pwl_rap_music_raw/main.cpp @@ -49,7 +49,7 @@ #include #include -#include +#include #include @@ -614,7 +614,7 @@ int main(int argc, char *argv[]) QList