Skip to content

Commit de28b3c

Browse files
authored
ci: Factorize skore*.yml in pytest.yml (#1666)
Factorize `skore*.yml` workflows in `pytest.yml` to run jobs on all packages defined by `vars.PACKAGES`, managed in the GitHub interface.
1 parent 72c4358 commit de28b3c

File tree

4 files changed

+107
-467
lines changed

4 files changed

+107
-467
lines changed

.github/workflows/pr-display-code-coverage.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@ name: pr-display-code-coverage
22

33
on:
44
workflow_run:
5-
workflows: [skore, skore-hub-project, skore-local-project]
5+
workflows: [pytest]
66
types: [completed]
77

88
concurrency:
9-
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.workflow_run.name }}
9+
group: ${{ github.workflow }}-${{ github.ref }}
1010
cancel-in-progress: true
1111

1212
permissions: {}
1313

1414
jobs:
1515
pr-display-code-coverage:
16-
if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }}
1716
runs-on: ubuntu-latest
17+
if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }}
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
package: ${{ fromJSON(vars.PACKAGES) }}
1822
permissions:
1923
actions: read
2024
contents: read
@@ -30,18 +34,21 @@ jobs:
3034
uses: ./.github/actions/workflow-run/context
3135

3236
- name: Download coverage reports
37+
id: download-coverage-reports
38+
continue-on-error: True
3339
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
3440
with:
35-
name: ${{ github.event.workflow_run.name }}-coverage
41+
name: ${{ matrix.package }}-coverage
3642
path: coverage/
3743
github-token: ${{ github.token }}
3844
run-id: ${{ github.event.workflow_run.id }}
3945

4046
- name: Display coverage reports
47+
if: ${{ steps.download-coverage-reports.outcome == 'success' }}
4148
uses: MishaKav/pytest-coverage-comment@13d3c18e21895566c746187c9ea74736372e5e91 # v1.1.54
4249
with:
4350
issue-number: ${{ steps.acquire-pr-context.outputs.pr-number }}
4451
pytest-xml-coverage-path: coverage/pytest-coverage.xml
4552
junitxml-path: coverage/pytest.xml
46-
title: Coverage Report for `${{ github.event.workflow_run.name }}/`
47-
unique-id-for-comment: ${{ github.event.workflow_run.name }}
53+
title: Coverage Report for `${{ matrix.package }}/`
54+
unique-id-for-comment: ${{ matrix.package }}

.github/workflows/skore-local-project.yml renamed to .github/workflows/pytest.yml

Lines changed: 94 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1-
name: skore-local-project
1+
name: pytest
2+
3+
# **How it works**
4+
# ================
5+
#
6+
# The workflow runs `pytest` jobs on all the repository packages, identified by the JSON
7+
# list `vars.PACKAGES` managed in the GitHub interface. If you want to run this workflow
8+
# on a new package, you only have to add its name in the above list.
9+
#
10+
# It's important to notice that only one workflow is triggered for all packages.
11+
#
12+
# The workflow is triggered on:
13+
# - __pull_request__ or __merge_group__ event (A),
14+
# - __push__ event on the main branch (B).
15+
#
16+
# On (A), the workflow is started and runs jobs on modified packages, and only on modified
17+
# packages.
18+
#
19+
# On (B), the workflow is started and runs jobs on all packages, no matter if they have
20+
# modification. Indeed it's important to know on main, at each commit, if all workflows
21+
# are green.
222

323
on:
424
pull_request:
@@ -16,33 +36,45 @@ permissions: {}
1636

1737
defaults:
1838
run:
19-
shell: "bash"
39+
shell: bash
2040

2141
jobs:
22-
skore-local-project-changes:
42+
pytest-changes:
2343
runs-on: ubuntu-latest
2444
outputs:
25-
changes: ${{ steps.filter.outputs.skore-local-project }}
45+
modified-packages: ${{ steps.filter.outputs.changes }}
2646
permissions:
2747
pull-requests: read
2848
steps:
2949
- name: Checkout code
3050
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3151

52+
- name: Create dynamically filtering file, based on `vars.PACKAGES`
53+
run: |
54+
echo "${PACKAGES}" | jq -r '.[]' | while read package; do
55+
>>${FILEPATH} echo "${package}:
56+
- '.github/workflows/pytest.yml'
57+
- 'ci/requirements/${package}/**'
58+
- '${package}/**'"
59+
done
60+
env:
61+
PACKAGES: ${{ vars.PACKAGES }}
62+
FILEPATH: ${{ runner.temp }}/filters.yaml
63+
3264
- name: Define if at least one file has changed
33-
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
3465
id: filter
66+
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
3567
with:
36-
filters: |
37-
skore-local-project:
38-
- '.github/workflows/skore-local-project.yml'
39-
- 'ci/requirements/skore-local-project/**'
40-
- 'skore-local-project/**'
41-
42-
skore-local-project-lockfiles:
43-
runs-on: "ubuntu-latest"
44-
needs: [skore-local-project-changes]
45-
if: ${{ (contains(fromJSON('["pull_request", "merge_group"]'), github.event_name)) && (needs.skore-local-project-changes.outputs.changes == 'true') }}
68+
filters: ${{ runner.temp }}/filters.yaml
69+
70+
pytest-lockfiles:
71+
runs-on: ubuntu-latest
72+
needs: [pytest-changes]
73+
if: ${{ (contains(fromJSON('["pull_request", "merge_group"]'), github.event_name)) && (needs.pytest-changes.outputs.modified-packages != '[]') }}
74+
strategy:
75+
fail-fast: false
76+
matrix:
77+
package: ${{ fromJSON(needs.pytest-changes.outputs.modified-packages) }}
4678
permissions:
4779
contents: read
4880
steps:
@@ -72,34 +104,46 @@ jobs:
72104
changes=$(git diff --name-only HEAD^1 HEAD)
73105
74106
if
75-
(echo "${changes}" | grep -qE "skore-local-project/pyproject.toml") &&
76-
(echo "${changes}" | (! grep -qE "ci/requirements/skore-local-project/.*/test-requirements.txt"))
107+
(echo "${changes}" | grep -qE "${{ matrix.package }}/pyproject.toml") &&
108+
(echo "${changes}" | (! grep -qE "ci/requirements/${{ matrix.package }}/.*/test-requirements.txt"))
77109
then
78110
curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh
79-
bash ci/pip-compile.sh skore-local-project
111+
bash ci/pip-compile.sh ${{ matrix.package }}
80112
81-
if (git diff --name-only | grep -qE "ci/requirements/skore-local-project/.*/test-requirements.txt"); then
82-
echo '::error title=skore-local-project-lockfiles::Lockfiles obsolete, please execute `$ bash ci/pip-compile.sh skore-local-project`'
113+
if (git diff --name-only | grep -qE "ci/requirements/${{ matrix.package }}/.*/test-requirements.txt"); then
114+
echo '::error title=${{ matrix.package }}-lockfiles::Lockfiles obsolete, please execute `$ bash ci/pip-compile.sh ${{ matrix.package }}`'
83115
exit 1
84116
fi
85117
fi
86118
87-
skore-local-project-test:
88-
needs: [skore-local-project-changes]
89-
if: ${{ (github.event_name == 'push') || (needs.skore-local-project-changes.outputs.changes == 'true') }}
119+
pytest-test:
120+
needs: [pytest-changes]
121+
if: ${{ (github.event_name == 'push') || (needs.pytest-changes.outputs.modified-packages != '[]') }}
90122
strategy:
91123
fail-fast: false
92124
matrix:
125+
package: ${{ (github.event_name == 'push') && fromJSON(vars.PACKAGES) || fromJSON(needs.pytest-changes.outputs.modified-packages) }}
93126
os: ["ubuntu-latest", "windows-latest"]
94127
python: ["3.9", "3.10", "3.11", "3.12"]
95-
scikit-learn: ["1.6"]
96-
include:
97-
- os: "ubuntu-latest"
98-
python: "3.12"
128+
scikit-learn: ["1.4", "1.5", "1.6"]
129+
exclude:
130+
- python: "3.9"
99131
scikit-learn: "1.4"
100-
- os: "ubuntu-latest"
101-
python: "3.12"
132+
- python: "3.10"
133+
scikit-learn: "1.4"
134+
- python: "3.11"
135+
scikit-learn: "1.4"
136+
- os: "windows-latest"
137+
scikit-learn: "1.4"
138+
- python: "3.9"
139+
scikit-learn: "1.5"
140+
- python: "3.10"
102141
scikit-learn: "1.5"
142+
- python: "3.11"
143+
scikit-learn: "1.5"
144+
- os: "windows-latest"
145+
scikit-learn: "1.5"
146+
include:
103147
- os: "ubuntu-latest"
104148
python: "3.12"
105149
scikit-learn: "1.6"
@@ -123,15 +167,15 @@ jobs:
123167
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
124168
id: cache-python-venv
125169
with:
126-
path: 'skore-local-project/venv'
170+
path: ${{ matrix.package }}/venv
127171
key: >-
128172
python-venv
129173
-${{ matrix.os }}
130174
-${{ steps.setup-python.outputs.python-version }}
131-
-${{ hashFiles(format('ci/requirements/skore-local-project/python-{0}/scikit-learn-{1}/test-requirements.txt', matrix.python, matrix.scikit-learn)) }}
175+
-${{ hashFiles(format('ci/requirements/{0}/python-{1}/scikit-learn-{2}/test-requirements.txt', matrix.package, matrix.python, matrix.scikit-learn)) }}
132176
133177
- name: Setup python-venv
134-
working-directory: "skore-local-project/"
178+
working-directory: ${{ matrix.package }}/
135179
run: |
136180
set -eu
137181
@@ -140,15 +184,15 @@ jobs:
140184
141185
# Activate venv for each step depending on the OS
142186
if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
143-
echo "${GITHUB_WORKSPACE}/skore-local-project/venv/bin" >> ${GITHUB_PATH}
144-
echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/skore-local-project/venv" >> ${GITHUB_ENV}
187+
echo "${GITHUB_WORKSPACE}/${{ matrix.package }}/venv/bin" >> ${GITHUB_PATH}
188+
echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}/${{ matrix.package }}/venv" >> ${GITHUB_ENV}
145189
else
146-
echo "${GITHUB_WORKSPACE}\\skore-local-project\\venv\\Scripts" >> ${GITHUB_PATH}
147-
echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}\\skore-local-project\\venv" >> ${GITHUB_ENV}
190+
echo "${GITHUB_WORKSPACE}\\${{ matrix.package }}\\venv\\Scripts" >> ${GITHUB_PATH}
191+
echo "VIRTUAL_ENV=${GITHUB_WORKSPACE}\\${{ matrix.package }}\\venv" >> ${GITHUB_ENV}
148192
fi
149193
150194
- name: Install dependencies in python-venv
151-
working-directory: ${{ format('ci/requirements/skore-local-project/python-{0}/scikit-learn-{1}', matrix.python, matrix.scikit-learn) }}
195+
working-directory: ${{ format('ci/requirements/{0}/python-{1}/scikit-learn-{2}', matrix.package, matrix.python, matrix.scikit-learn) }}
152196
if: steps.cache-python-venv.outputs.cache-hit != 'true'
153197
run: |
154198
python -m pip install --upgrade pip build
@@ -158,27 +202,27 @@ jobs:
158202
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
159203
if: steps.cache-python-venv.outputs.cache-hit != 'true'
160204
with:
161-
path: 'skore-local-project/venv'
205+
path: ${{ matrix.package }}/venv
162206
key: ${{ steps.cache-python-venv.outputs.cache-primary-key }}
163207

164208
- name: Build
165-
working-directory: skore-local-project/
209+
working-directory: ${{ matrix.package }}/
166210
run: python -m build
167211

168212
- name: Install
169-
working-directory: skore-local-project/dist/
213+
working-directory: ${{ matrix.package }}/dist/
170214
run: wheel=(*.whl); python -m pip install --force-reinstall --no-deps "${wheel}"
171215

172216
- name: Test without coverage
173217
if: ${{ ! matrix.coverage }}
174218
timeout-minutes: 10
175-
working-directory: skore-local-project/
219+
working-directory: ${{ matrix.package }}/
176220
run: python -m pytest -n auto src/ tests/ --no-cov
177221

178222
- name: Test with coverage
179223
if: ${{ matrix.coverage }}
180224
timeout-minutes: 10
181-
working-directory: skore-local-project/
225+
working-directory: ${{ matrix.package }}/
182226
run: |
183227
mkdir coverage
184228
python -m pytest -n auto src/ tests/ --junitxml=coverage/pytest.xml --cov-config=pyproject.toml --cov-report=xml:coverage/pytest-coverage.xml --cov
@@ -187,17 +231,16 @@ jobs:
187231
if: ${{ matrix.coverage && (github.event_name == 'pull_request') }}
188232
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
189233
with:
190-
name: skore-local-project-coverage
191-
path: skore-local-project/coverage/
234+
name: ${{ matrix.package }}-coverage
235+
path: ${{ matrix.package }}/coverage/
192236

193-
skore-local-project:
237+
pytest:
194238
needs:
195-
- skore-local-project-changes
196-
- skore-local-project-lockfiles
197-
- skore-local-project-test
239+
- pytest-changes
240+
- pytest-lockfiles
241+
- pytest-test
198242
if: ${{ always() }}
199-
runs-on: Ubuntu-latest
243+
runs-on: ubuntu-latest
200244
steps:
201-
- shell: bash
202-
run: |
245+
- run: |
203246
[[ ${{ contains(needs.*.result, 'failure') }} = false ]]

0 commit comments

Comments
 (0)