-
Notifications
You must be signed in to change notification settings - Fork 89
238 lines (207 loc) · 9.67 KB
/
python-test.yml
File metadata and controls
238 lines (207 loc) · 9.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: CI-PyTest
on:
push:
branches: [master]
pull_request: {}
jobs:
# Matrix strategy for parallel test execution
test-matrix:
runs-on: ubuntu-latest
outputs:
other_modified_files_count: ${{ steps.dependencies.outputs.other_modified_files_count }}
strategy:
fail-fast: false
matrix:
test-group: [
"generic",
"classification-histology",
"classification-standard",
"segmentation-2d",
"segmentation-3d",
"regression",
"transunet",
"entrypoints",
"update_version"
]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Call reusable workflow to install dependencies
id: dependencies
uses: ./.github/workflows/dependencies
- name: Run test group - ${{ matrix.test-group }}
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}}
run: |
case "${{ matrix.test-group }}" in
"generic")
pytest --cov=. --cov-report=xml:coverage-generic.xml -k "generic" --cov-context=test | tee pytest-generic.log
;;
"classification-histology")
pytest --cov=. --cov-report=xml:coverage-classification-histology.xml -k "classification and histology" --cov-context=test | tee pytest-classification-histology.log
;;
"classification-standard")
pytest --cov=. --cov-report=xml:coverage-classification-standard.xml -k "classification and not histology" --cov-context=test | tee pytest-classification-standard.log
;;
"segmentation-2d")
pytest --cov=. --cov-report=xml:coverage-segmentation-2d.xml -k "segmentation and 2d and not transunet" --cov-context=test | tee pytest-segmentation-2d.log
;;
"segmentation-3d")
pytest --cov=. --cov-report=xml:coverage-segmentation-3d.xml -k "segmentation and 3d and not transunet" --cov-context=test | tee pytest-segmentation-3d.log
;;
"regression")
pytest --cov=. --cov-report=xml:coverage-regression.xml -k "regression" --cov-context=test | tee pytest-regression.log
;;
"transunet")
pytest --cov=. --cov-report=xml:coverage-transunet.xml -k "transunet" --cov-context=test | tee pytest-transunet.log
;;
"entrypoints")
pytest --cov=. --cov-report=xml:coverage-entrypoints.xml -k "entrypoints" --cov-context=test | tee pytest-entrypoints.log
;;
"update_version")
pytest --cov=. --cov-report=xml:coverage-update_version.xml -k "update_version" --cov-context=test | tee pytest-update_version.log
;;
esac
shell: bash
- name: Upload coverage artifact
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}}
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.test-group }}
path: coverage-${{ matrix.test-group }}.xml
retention-days: 1
# Job to combine all coverage reports
combine-coverage:
needs: test-matrix
runs-on: ubuntu-latest
if: ${{ needs.test-matrix.outputs.other_modified_files_count > 0 && (always() && (needs.test-matrix.result == 'success' || needs.test-matrix.result == 'failure')) }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Download all coverage artifacts
uses: actions/download-artifact@v4
with:
pattern: coverage-*
path: coverage-reports
merge-multiple: true
- name: List downloaded coverage files
run: |
find coverage-reports -name "*.xml" -type f
- name: Combine coverage reports
run: |
# Install coverage tools if not already available
pip install coverage
# Create combined coverage directory
mkdir -p combined-coverage
# Combine all XML coverage reports
python -c "
import xml.etree.ElementTree as ET
import glob
import os
coverage_files = glob.glob('coverage-reports/**/*.xml', recursive=True)
print(f'Found {len(coverage_files)} coverage files')
if not coverage_files:
print('No coverage files found')
exit(1)
# Use the first file as base
combined_tree = ET.parse(coverage_files[0])
combined_root = combined_tree.getroot()
# Merge coverage from other files
for coverage_file in coverage_files[1:]:
tree = ET.parse(coverage_file)
root = tree.getroot()
# Merge packages
for package in root.findall('.//package'):
package_name = package.get('name')
existing_package = combined_root.find(f'.//package[@name=\"{package_name}\"]')
if existing_package is None:
# Add new package
packages = combined_root.find('.//packages')
if packages is not None:
packages.append(package)
else:
# Merge classes within package
for class_elem in package.findall('classes/class'):
class_name = class_elem.get('name')
existing_class = existing_package.find(f'.//class[@name=\"{class_name}\"]')
if existing_class is None:
classes = existing_package.find('classes')
if classes is not None:
classes.append(class_elem)
# Write combined coverage
combined_tree.write('combined-coverage/coverage.xml', encoding='utf-8', xml_declaration=True)
print('Combined coverage report created')
"
- name: Upload combined coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./combined-coverage/coverage.xml
flags: unittests
name: combined-coverage
- name: Upload coverage to Codacy
if: github.ref == 'refs/heads/master'
uses: codacy/codacy-coverage-reporter-action@v1.3.0
with:
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
coverage-reports: ./combined-coverage/coverage.xml
# Legacy single-system job for backward compatibility (optional)
full-test:
runs-on: ubuntu-latest
if: false # Disable this job since we are using the matrix approach
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Call reusable workflow to install dependencies
id: dependencies
uses: ./.github/workflows/dependencies
- name: Run generic unit tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml -k "generic"
- name: Run classification unit tests with histology
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "classification and histology"
- name: Run classification unit tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "classification and not histology"
- name: Run segmentation unit tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "segmentation and not transunet"
- name: Run regression unit tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "regression"
- name: Run transunet unit tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "transunet"
- name: Run entrypoints tests
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "entrypoints"
- name: Run test for update_version
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
run: |
pytest --cov=. --cov-report=xml --cov-append -k "update_version"
- name: Upload coverage
if: ${{steps.dependencies.outputs.other_modified_files_count > 0}} # Run on any non-docs change
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
flags: unittests
- name: Upload coverage to Codacy
if: github.ref == 'refs/heads/master' # only run when on master
uses: codacy/codacy-coverage-reporter-action@v1.3.0
with:
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
coverage-reports: ./coverage.xml