a b/azure-pipelines.yml
1
trigger:
2
  # start a new build for every push
3
  batch: false
4
  branches:
5
    include:
6
      - 'main'
7
      - 'maint/*'
8
pr:
9
  branches:
10
    include:
11
      - '*'  # must quote since "*" is a YAML reserved character; we want a string
12
13
14
stages:
15
16
  - stage: Check
17
    jobs:
18
      - job: Skip
19
        pool:
20
          vmImage: 'ubuntu-latest'
21
        variables:
22
          DECODE_PERCENTS: 'false'
23
          RET: 'true'
24
          BUILD_REASON: $(Build.Reason)
25
        steps:
26
          - bash: |
27
              git_log=`git log --format=oneline -n 1 --skip=1`
28
              echo "##vso[task.setvariable variable=log]$git_log"
29
          - bash: echo "##vso[task.setvariable variable=RET]false"
30
            condition: and(eq(variables.BUILD_REASON, 'PullRequest'), or(contains(variables.log, '[skip azp]'), contains(variables.log, '[azp skip]'), contains(variables.log, '[skip ci]'), contains(variables.log, '[ci skip]')))
31
          - bash: echo "##vso[task.setvariable variable=start_main;isOutput=true]$RET"
32
            name: result
33
34
  - stage: Style
35
    variables:
36
      AZURE_CI: 'true'
37
    jobs:
38
      - job: All
39
        pool:
40
          vmImage: 'ubuntu-latest'
41
        variables:
42
          PYTHON_VERSION: '3.11'
43
          PYTHON_ARCH: 'x64'
44
        steps:
45
          - bash: echo $(COMMIT_MSG)
46
          - task: UsePythonVersion@0
47
            inputs:
48
              versionSpec: $(PYTHON_VERSION)
49
              architecture: $(PYTHON_ARCH)
50
              addToPath: true
51
            displayName: 'Get Python'
52
          - bash: |
53
              set -eo pipefail
54
              python -m pip install --progress-bar off --upgrade pip build
55
              python -m pip install --progress-bar off -ve .[hdf5,test]
56
              python -m pip uninstall -yq pytest-qt  # don't want to set up display, etc. for this
57
              pre-commit install --install-hooks
58
            displayName: Install dependencies
59
          - bash: |
60
              make pre-commit
61
            displayName: make pre-commit
62
            condition: always()
63
          - bash: |
64
              make nesting
65
            displayName: make nesting
66
            condition: always()
67
          - bash: |
68
              make check-readme
69
            displayName: make check-readme
70
            condition: always()
71
          - bash: mypy
72
            displayName: mypy
73
            condition: always()
74
          - bash: vulture
75
            displayName: vulture
76
            condition: always()
77
78
79
  - stage: Test
80
    condition: and(succeeded(), eq(dependencies.Check.outputs['Skip.result.start_main'], 'true'))
81
    dependsOn: ['Style', 'Check']
82
    variables:
83
      AZURE_CI: 'true'
84
    jobs:
85
      - job: Ultraslow_PG
86
        pool:
87
          vmImage: 'ubuntu-22.04'
88
        variables:
89
          DISPLAY: ':99'
90
          OPENBLAS_NUM_THREADS: '1'
91
          MNE_TEST_ALLOW_SKIP: '^.*(PySide6 causes segfaults).*$'
92
          MNE_BROWSER_PRECOMPUTE: 'false'
93
        steps:
94
          - bash: |
95
              set -e
96
              ./tools/setup_xvfb.sh
97
              sudo apt install -yq tcsh
98
            displayName: 'Install Ubuntu dependencies'
99
          - bash: |
100
              source tools/get_minimal_commands.sh
101
            displayName: 'Install minimal commands'
102
          - bash: |
103
              echo $PATH
104
              mne_surf2bem --version
105
              fsl_rigid_register --version
106
            displayName: 'Test minimal commands'
107
          - task: UsePythonVersion@0
108
            inputs:
109
              versionSpec: '3.12'
110
              architecture: 'x64'
111
              addToPath: true
112
            displayName: 'Get Python'
113
          - bash: |
114
              set -e
115
              python -m pip install --progress-bar off --upgrade pip
116
              python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git" pyvista scikit-learn python-picard qtpy nibabel sphinx-gallery "PySide6!=6.8.0,!=6.8.0.1,!=6.8.1.1" pandas neo pymatreader antio defusedxml
117
              python -m pip uninstall -yq mne
118
              python -m pip install --progress-bar off --upgrade -e .[test]
119
            displayName: 'Install dependencies with pip'
120
          - bash: |
121
              set -e
122
              mne sys_info -pd
123
              mne sys_info -pd | grep "qtpy .*(PySide6=.*)$"
124
            displayName: Print config
125
          - bash: |
126
              set -e
127
              LD_DEBUG=libs python -c "from PySide6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()"
128
          - bash: source tools/get_testing_version.sh
129
            displayName: 'Get testing version'
130
          - task: Cache@2
131
            inputs:
132
              key: $(testing_version)
133
              path: /home/vsts/mne_data
134
            displayName: 'Cache testing data'
135
          - script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
136
            displayName: 'Get test data'
137
          - script: pytest -m "ultraslowtest or pgtest" --tb=short --cov=mne --cov-report=xml -vv mne
138
            displayName: 'slow and mne-qt-browser tests'
139
          # Coverage
140
          - bash: bash <(curl -s https://codecov.io/bash)
141
            displayName: 'Codecov'
142
            condition: succeededOrFailed()
143
          - task: PublishTestResults@2
144
            inputs:
145
              testResultsFiles: '**/junit-*.xml'
146
              testRunTitle: 'Publish test results for $(Agent.JobName)'
147
              failTaskOnFailedTests: true
148
            condition: succeededOrFailed()
149
          - task: PublishCodeCoverageResults@2
150
            inputs:
151
              summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
152
153
      - job: Qt
154
        pool:
155
          vmImage: 'ubuntu-22.04'
156
        variables:
157
          DISPLAY: ':99'
158
          OPENBLAS_NUM_THREADS: '1'
159
          TEST_OPTIONS: "--tb=short --cov=mne --cov-report=xml --cov-append -vv mne/viz/_brain mne/viz/backends mne/viz/tests/test_evoked.py mne/gui mne/report"
160
          MNE_TEST_ALLOW_SKIP: '^.*(PySide6 causes segfaults).*$'
161
        steps:
162
          - bash: ./tools/setup_xvfb.sh
163
            displayName: 'Install Ubuntu dependencies'
164
          - task: UsePythonVersion@0
165
            inputs:
166
              versionSpec: '3.10'
167
              architecture: 'x64'
168
              addToPath: true
169
            displayName: 'Get Python'
170
          - bash: |
171
              set -e
172
              python -m pip install --progress-bar off --upgrade pip
173
              python -m pip install --progress-bar off --upgrade --pre --only-binary=\"numpy,scipy,matplotlib,vtk\" numpy scipy matplotlib vtk
174
              python -c "import vtk"
175
              python -m pip install --progress-bar off --upgrade -ve .[full,test_extra]
176
            displayName: 'Install dependencies with pip'
177
          - bash: |
178
              set -e
179
              which mne
180
              mne sys_info -pd
181
              python ./tools/check_mne_location.py
182
            displayName: Print config
183
          - bash: source tools/get_testing_version.sh
184
            displayName: 'Get testing version'
185
          - task: Cache@2
186
            inputs:
187
              key: $(testing_version)
188
              path: /home/vsts/mne_data
189
            displayName: 'Cache testing data'
190
          - script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
191
            displayName: 'Get test data'
192
          - bash: |
193
              set -eo pipefail
194
              python -m pip install PyQt6
195
              LD_DEBUG=libs python -c "from PyQt6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()"
196
            displayName: 'Check Qt import'
197
          - bash: |
198
              set -eo pipefail
199
              mne sys_info -pd
200
              mne sys_info -pd | grep "qtpy .* (PyQt6=.*)$"
201
              PYTEST_QT_API=PyQt6 pytest ${TEST_OPTIONS}
202
              python -m pip uninstall -yq PyQt6 PyQt6-sip PyQt6-Qt6
203
            displayName: 'PyQt6'
204
          - bash: |
205
              set -eo pipefail
206
              python -m pip install "PySide6!=6.8.0,!=6.8.0.1"
207
              mne sys_info -pd
208
              mne sys_info -pd | grep "qtpy .* (PySide6=.*)$"
209
              PYTEST_QT_API=PySide6 pytest ${TEST_OPTIONS}
210
              python -m pip uninstall -yq PySide6
211
            displayName: 'PySide6'
212
          # PyQt5 leaves cruft behind, so run it last
213
          - bash: |
214
              set -eo pipefail
215
              python -m pip install PyQt5
216
              mne sys_info -pd
217
              mne sys_info -pd | grep "qtpy .* (PyQt5=.*)$"
218
              PYTEST_QT_API=PyQt5 pytest ${TEST_OPTIONS}
219
              python -m pip uninstall -yq PyQt5 PyQt5-sip PyQt5-Qt5
220
            displayName: 'PyQt5'
221
          # Coverage
222
          - bash: bash <(curl -s https://codecov.io/bash)
223
            displayName: 'Codecov'
224
            condition: succeededOrFailed()
225
          - task: PublishTestResults@2
226
            inputs:
227
              testResultsFiles: '**/junit-*.xml'
228
              testRunTitle: 'Publish test results for $(Agent.JobName)'
229
              failTaskOnFailedTests: true
230
            condition: succeededOrFailed()
231
          - task: PublishCodeCoverageResults@2
232
            inputs:
233
              summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
234
235
      - job: Windows
236
        pool:
237
          vmImage: 'windows-latest'
238
        variables:
239
          MNE_LOGGING_LEVEL: 'warning'
240
          MNE_FORCE_SERIAL: 'true'
241
          OPENBLAS_NUM_THREADS: '2'
242
          OMP_DYNAMIC: 'false'
243
          PYTHONUNBUFFERED: 1
244
          PYTHONIOENCODING: 'utf-8'
245
          AZURE_CI_WINDOWS: 'true'
246
          PYTHON_ARCH: 'x64'
247
        timeoutInMinutes: 90
248
        strategy:
249
          maxParallel: 4
250
          matrix:
251
            3.10 pip:
252
              TEST_MODE: 'pip'
253
              PYTHON_VERSION: '3.10'
254
            3.12 pip pre:
255
              TEST_MODE: 'pip-pre'
256
              PYTHON_VERSION: '3.12'
257
        steps:
258
          - task: UsePythonVersion@0
259
            inputs:
260
              versionSpec: $(PYTHON_VERSION)
261
              architecture: $(PYTHON_ARCH)
262
              addToPath: true
263
            displayName: 'Get Python'
264
          - bash: |
265
              set -eo pipefail
266
              git clone --depth 1 https://github.com/pyvista/setup-headless-display-action.git
267
              MESA3D_VERSION=24.3.0 bash setup-headless-display-action/windows/install_opengl.sh
268
            displayName: Install OpenGL
269
          - bash: ./tools/azure_dependencies.sh
270
            displayName: Install dependencies with pip
271
          - script: pip install -e .
272
            displayName: 'Install MNE-Python dev'
273
          - script: mne sys_info -pd
274
            displayName: 'Print config'
275
          - script: python -c "import numpy; numpy.show_config()"
276
            displayName: Print NumPy config
277
          - script: python -c "import numpy; import scipy.linalg; import sklearn.neighbors; from threadpoolctl import threadpool_info; from pprint import pprint; pprint(threadpool_info())"
278
            displayName: Print threadpoolctl info
279
          - bash: source tools/get_testing_version.sh
280
            displayName: 'Get testing version'
281
          - task: Cache@2
282
            inputs:
283
              key: $(testing_version)
284
              path: C:\Users\VssAdministrator\mne_data
285
            displayName: 'Cache testing data'
286
          - script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
287
            displayName: 'Get test data'
288
          - script: pytest -m "not (slowtest or pgtest)" --tb=short --cov=mne --cov-report=xml -vv mne
289
            displayName: 'Run tests'
290
          - bash: bash <(curl -s https://codecov.io/bash)
291
            displayName: 'Codecov'
292
            condition: succeededOrFailed()
293
          - task: PublishTestResults@2
294
            inputs:
295
              testResultsFiles: '**/junit-*.xml'
296
              testRunTitle: 'Publish test results for $(Agent.JobName) $(TEST_MODE) $(PYTHON_VERSION)'
297
              failTaskOnFailedTests: true
298
            condition: succeededOrFailed()
299
          - task: PublishCodeCoverageResults@2
300
            inputs:
301
              summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'