Repository navigation
246 lines (231 loc) · 9.55 KB
/
Copy pathreusable-python-pytest.yml
File metadata and controls
246 lines (231 loc) · 9.55 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
239
240
241
242
243
244
245
246
name: Pytest on any OS
on:
workflow_call:
inputs:
package-manager:
description: Package manager to use (e.g. "conda", "poetry", "pixi")
required: true
type: string
default: poetry
python-versions:
description: 'List of Python versions to test against (e.g. ["3.10", "3.11", "3.12"])'
required: false
type: string
default: "['3.10']"
os:
description: 'List of OS to test against (e.g. ["ubuntu-latest", "macos-latest"])'
required: false
type: string
default: "['ubuntu-latest']"
cache-number:
description: Cache number to reset cache if poetry.lock has not changed
required: false
type: number
default: 1
codecov-reference-python-version:
description: >
Python version to use as reference for Codecov. When using pixi-environments,
set this to the pixi environment name that should upload coverage.
required: false
type: string
codecov-reference-os:
description: List of OS to use as reference for Codecov
required: false
type: string
default: "['windows-latest']"
install-extras:
description: 'Extra dependencies for pip to install (e.g. ["torch", "cuda"])'
required: false
type: string
conda-channels:
description: 'List of conda channels to pull from (e.g. ["conda-forge", "pytorch"])'
required: false
type: string
virtual-repo-names:
description: >
List of repository names to resolve on for pip or Conda
(e.g. ["public-pypi-dev"], or ["public-conda-dev"])
required: false
type: string
pixi-version:
description: Version of Pixi to use
required: false
type: string
default: v0.67.2 # default to last version before lock file version v7
pixi-environments:
description: >
JSON list of Pixi environment names to install (e.g. '["test-engine", "test-evals"]').
When provided, drives the matrix instead of python-versions.
required: false
type: string
pixi-task:
description: >
Pixi task name to run tests (e.g. 'test-engine'). Must match a task
defined in pixi.toml. Validated against available tasks before execution.
required: false
type: string
pixi-task-args:
description: >
JSON list of extra arguments to pass to the pixi task after '--'
(e.g. '["-k", "test_interpolation"]'). Optional.
required: false
type: string
lfs:
description: Boolean to indicate if GitHub LFS is needed
required: false
type: boolean
default: false
timeout-minutes:
description: Timeout in minutes for the job
required: false
type: number
default: 20
private-github-repos:
description: >
Comma-separated list of repositories to request a GitHub App token for
(e.g. 'scigeoh5,petro-lingo'). When provided, GH_APP_ID and GH_APP_PRIVATE_KEY
secrets must also be passed.
required: false
type: string
secrets:
CODECOV_TOKEN:
description: Codecov token
required: false
JFROG_ARTIFACTORY_URL:
description: JFrog Artifactory URL, needed if packages are on Artifactory
required: false
JFROG_ARTIFACTORY_TOKEN:
description: JFrog Artifactory Token, needed if packages are on Artifactory
required: false
GH_CLIENT_ID:
description: GitHub App ID for accessing private repositories
required: false
GH_APP_PRIVATE_KEY:
description: GitHub App private key for accessing private repositories
required: false
jobs:
pytest:
name: Pytest
if: ${{ (github.event_name != 'pull_request') || (github.event.pull_request.draft == false) }}
strategy:
fail-fast: false
matrix:
python-version: ${{ fromJSON((inputs.package-manager == 'pixi' && inputs.pixi-environments) || inputs.python-versions) }}
os: ${{ fromJson(inputs.os)}}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: 'bash -l {0}'
timeout-minutes: ${{ inputs.timeout-minutes }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
lfs: ${{ inputs.lfs }}
fetch-depth: 0
persist-credentials: false
- name: Set up Python version
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
if: ${{ inputs.package-manager == 'poetry' || inputs.package-manager == 'hatch' }}
with:
python-version: ${{ matrix.python-version }}
- uses: $/.github/actions/reusable-python-setup_conda
name: Setup conda env
if: ${{ inputs.package-manager == 'conda' }}
env:
GIT_LFS_SKIP_SMUDGE: "1"
with:
cache-number: ${{ inputs.cache-number }}
python-version: ${{ matrix.python-version }}
virtual-repo-names: ${{ inputs.virtual-repo-names }}
JFROG_ARTIFACTORY_URL: ${{ secrets.JFROG_ARTIFACTORY_URL }}
JFROG_ARTIFACTORY_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }}
- uses: $/.github/actions/reusable-python-setup_poetry
name: Setup poetry env
if: ${{ inputs.package-manager == 'poetry' }}
with:
cache-number: ${{ inputs.cache-number }}
runner-os: ${{ runner.os }}
install-extras: ${{ inputs.install-extras }}
virtual-repo-names: ${{ inputs.virtual-repo-names }}
JFROG_ARTIFACTORY_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }}
- uses: $/.github/actions/reusable-python-setup_hatch
name: Setup hatch env
if: ${{ inputs.package-manager == 'hatch' }}
with:
cache-number: ${{ inputs.cache-number }}
runner-os: ${{ runner.os }}
- name: Configure git for pixi environments
if: ${{ inputs.package-manager == 'pixi' }}
shell: bash
run: |
git config --global core.longpaths true
echo "GIT_LFS_SKIP_SMUDGE=1" >> "$GITHUB_ENV"
- name: Generate GitHub App token for private repos
if: ${{ inputs.private-github-repos != '' }}
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
client-id: ${{ secrets.GH_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
repositories: ${{ inputs.private-github-repos }}
- name: Register the personal access token
if: ${{ inputs.private-github-repos != '' }}
shell: bash
run: echo "${{ steps.app-token.outputs.token }}" | gh auth login --with-token
- name: Configure the Git credential helper
if: ${{ inputs.private-github-repos != '' }}
shell: bash
run: gh auth setup-git
- uses: $/.github/actions/reusable-python-setup_pixi
name: Setup pixi env
if: ${{ inputs.package-manager == 'pixi' }}
with:
cache-number: ${{ inputs.cache-number }}
python-version: ${{ inputs.pixi-environments && '' || matrix.python-version }}
pixi-version: ${{ inputs.pixi-version }}
environment-name: ${{ inputs.pixi-environments && matrix.python-version || '' }}
JFROG_ARTIFACTORY_URL: ${{ secrets.JFROG_ARTIFACTORY_URL }}
JFROG_ARTIFACTORY_TOKEN: ${{ secrets.JFROG_ARTIFACTORY_TOKEN }}
- name: Validate pixi task
if: ${{ inputs.package-manager == 'pixi' && inputs.pixi-task }}
env:
PIXI_TASK: ${{ inputs.pixi-task }}
run: |
jq_filter='any(.. | objects; .name == $task and (has("cmd") or has("depends_on") or has("cwd") or has("clean_env")))'
if ! pixi task list --json | jq -e --arg task "$PIXI_TASK" "$jq_filter"; then
echo "::error::Pixi task '$PIXI_TASK' is not defined in pixi.toml."
exit 1
fi
- name: Run Pytest
env:
PIXI_TASK: ${{ inputs.pixi-task }}
PIXI_TASK_ARGS: ${{ inputs.pixi-task-args }}
run: |
if ${{ inputs.package-manager == 'conda' }}; then
pytest --cov --cov-report=xml
elif ${{ inputs.package-manager == 'poetry' }}; then
poetry run pytest --cov --cov-report=xml
elif ${{ inputs.package-manager == 'pixi' }}; then
if [ -n "$PIXI_TASK" ]; then
if [ -n "$PIXI_TASK_ARGS" ]; then
if ! echo "$PIXI_TASK_ARGS" | jq -e 'type == "array" and all(.[]; type == "string")' > /dev/null; then
echo "::error::Invalid pixi-task-args. Must be a JSON array of strings."
exit 1
fi
echo "$PIXI_TASK_ARGS" | jq -r '.[]' | xargs -d '\n' pixi run "$PIXI_TASK" --
else
pixi run "$PIXI_TASK"
fi
else
pixi run pytest --cov --cov-report=xml
fi
else
hatch run pytest --cov --cov-report=xml
fi
- name: Codecov
if: ${{ (inputs.codecov-reference-python-version) && (matrix.python-version == inputs.codecov-reference-python-version) && contains(inputs.codecov-reference-os, matrix.os) && !(github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]') }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6.0.2
with:
name: GitHub
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}