forked from scikit-learn/scikit-learn
-
Notifications
You must be signed in to change notification settings - Fork 0
226 lines (198 loc) · 7.88 KB
/
unit-tests.yml
File metadata and controls
226 lines (198 loc) · 7.88 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
name: Unit tests
permissions:
contents: read
on:
push:
pull_request:
schedule:
# Nightly build at 02:30 UTC
- cron: "30 2 * * *"
# Manual run
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
env:
VIRTUALENV: testvenv
TEST_DIR: ${{ github.workspace }}/tmp_folder
CCACHE_DIR: ${{ github.workspace }}/ccache
COVERAGE: 'true'
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
if: github.repository == 'scikit-learn/scikit-learn'
steps:
- name: Checkout
uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: 'pip'
- name: Install linters
run: |
source build_tools/shared.sh
# Include pytest compatibility with mypy
pip install pytest $(get_dep ruff min) $(get_dep mypy min) cython-lint
- name: Run linters
run: ./build_tools/linting.sh
- name: Run Meson OpenMP checks
run: |
pip install ninja meson scipy
python build_tools/check-meson-openmp-dependencies.py
retrieve-commit-message:
name: Retrieve the latest commit message
runs-on: ubuntu-latest
if: github.repository == 'scikit-learn/scikit-learn'
outputs:
message: ${{ steps.git-log.outputs.message }}
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- id: git-log
name: Retrieve the latest commit message
shell: bash
run: |
set -eu
message=$(git log --format=%B -n 1)
{
echo 'message<<EOF'
echo "${message}"
echo EOF
} >> "${GITHUB_OUTPUT}"
retrieve-selected-tests:
# Parse the commit message to check if `build_tools/azure/test_script.sh` should run
# only specific tests.
#
# If so, selected tests will be run with SKLEARN_TESTS_GLOBAL_RANDOM_SEED="all".
#
# The commit message must take the form:
# <title> [all random seeds]
# <test_name_1>
# <test_name_2>
# ...
name: Retrieve the selected tests
runs-on: ubuntu-latest
if: github.repository == 'scikit-learn/scikit-learn'
outputs:
tests: ${{ steps.selected-tests.outputs.tests }}
needs: [retrieve-commit-message]
steps:
- id: selected-tests
name: Retrieve the selected tests
shell: python
env:
COMMIT_MESSAGE: ${{ needs.retrieve-commit-message.outputs.message }}
run: |
import os
commit_message = os.environ["COMMIT_MESSAGE"]
# Retrieve selected tests from commit message
if "[all random seeds]" in commit_message:
selected_tests = commit_message.split("[all random seeds]")[1].strip()
selected_tests = selected_tests.replace("\n", " or ")
# quote 'selected_tests' to cover the case of multiple selected tests
selected_tests = f"{selected_tests!r}"
else:
selected_tests = ""
# Write selected tests to `GITHUB_OUTPUT`
with open(os.environ["GITHUB_OUTPUT"], "a") as file:
file.write(f"tests={selected_tests}\n")
unit-tests:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
if: github.repository == 'scikit-learn/scikit-learn'
needs: [lint, retrieve-commit-message, retrieve-selected-tests]
strategy:
# Ensures that all builds run to completion even if one of them fails
fail-fast: false
matrix:
include:
- name: Linux pymin_conda_forge_arm
os: ubuntu-24.04-arm
DISTRIB: conda
LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock
# Linux environment to test the latest available dependencies.
# It runs tests requiring lightgbm, pandas and PyAMG.
- name: Linux pylatest_pip_openblas_pandas
os: ubuntu-24.04
DISTRIB: conda
LOCK_FILE: build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock
SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 3 # non-default seed
SCIPY_ARRAY_API: 1
CHECK_PYTEST_SOFT_DEPENDENCY: true
SKLEARN_WARNINGS_AS_ERRORS: 1
# disable pytest-xdist to have 1 job where OpenMP and BLAS are not single
# threaded because by default the tests configuration (sklearn/conftest.py)
# makes sure that they are single threaded in each xdist subprocess.
PYTEST_XDIST_VERSION: none
PIP_BUILD_ISOLATION: true
- name: macOS pylatest_conda_forge_arm
os: macOS-15
DISTRIB: conda
LOCK_FILE: build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock
SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 5 # non-default seed
SCIPY_ARRAY_API: 1
PYTORCH_ENABLE_MPS_FALLBACK: 1
CHECK_PYTEST_SOFT_DEPENDENCY: true
env: ${{ matrix }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Create cache for ccache
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-v1-${{ matrix.name }}-${{ hashFiles('**/*.pyx*', '**/*.pxd*', '**/*.pxi*', '**/*.h', '**/*.c', '**/*.cpp', format('{0}', matrix.LOCK_FILE)) }}
restore-keys: ccache-${{ matrix.name }}
- name: Set up conda
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
auto-activate-base: true
activate-environment: ""
- name: Build scikit-learn
run: bash -l build_tools/azure/install.sh
- name: Set random seed for nightly/manual runs
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV
- name: Run tests
env:
COMMIT_MESSAGE: ${{ needs.retrieve-commit-message.outputs.message }}
SELECTED_TESTS: ${{ needs.retrieve-selected-tests.outputs.tests }}
COVERAGE: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}}
run: bash -l build_tools/azure/test_script.sh
- name: Run doctests in .py and .rst files
run: bash -l build_tools/azure/test_docs.sh
if: ${{ needs.retrieve-selected-tests.outputs.tests == ''}}
- name: Run pytest soft dependency test
run: bash -l build_tools/azure/test_pytest_soft_dependency.sh
if: ${{ env.CHECK_PYTEST_SOFT_DEPENDENCY == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}}
- name: Combine coverage reports from parallel test runners
run: bash -l build_tools/azure/combine_coverage_reports.sh
if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}}
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v5
if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}}
with:
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
disable_search: true
- name: Update tracking issue
if: ${{ always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')}}
run: |
set -ex
if [[ ${{ job.status }} == "success" ]]; then
TESTS_PASSED=true
else
TESTS_PASSED=false
fi
pip install defusedxml PyGithub
python maint_tools/update_tracking_issue.py \
${{ secrets.BOT_GITHUB_TOKEN }} \
"$GITHUB_WORKFLOW ${{ matrix.name }}" \
"$GITHUB_REPOSITORY" \
https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \
--tests-passed $TESTS_PASSED \
--auto-close false \
--job-name "${{ matrix.name }}"