forked from iiasa/message-ix-models
-
Notifications
You must be signed in to change notification settings - Fork 0
242 lines (208 loc) · 8.09 KB
/
pytest.yaml
File metadata and controls
242 lines (208 loc) · 8.09 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
name: Test
on:
# To debug the workflow, uncomment this entry AND comment pull_request_target
# pull_request:
# branches: [ main ]
pull_request_target:
branches: [ main, "migrate**" ]
types: [ labeled, opened, reopened, synchronize ]
schedule:
- cron: "0 5 * * *" # = 06:00 CET = 07:00 CEST
# Cancel previous runs that have not completed
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
gams-version: 48.7.0
label: "safe to test"
python-version: "3.14"
jobs:
check:
name: Check permissions, identify ref to test
runs-on: ubuntu-latest
steps:
- if: >
!(
github.event_name == 'schedule'
|| github.repository == github.event.pull_request.head.repo.full_name
|| contains(github.event.pull_request.labels.*.name, env.label)
)
run: |
echo "Pytest workflow will not run for branch in fork without label \`${{ env.label }}\`." >>$GITHUB_STEP_SUMMARY
exit 1
- name: Identify ref to check out
id: ref
run: echo "ref=${{ github.event_name != 'pull_request_target' && github.ref || github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
outputs:
ref: ${{ steps.ref.outputs.ref }}
warm-lfs-cache:
name: Warm Git LFS cache
needs: check
strategy:
matrix:
os: [ macos-15-intel, macos-latest, ubuntu-latest, windows-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: francisbilham11/action-cached-lfs-checkout@v3
with:
ref: ${{ needs.check.outputs.ref }}
- name: Cache static data
uses: actions/cache@v4
with:
path: message-static-data
key: static-data-${{ matrix.os }}
- uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: |
${{ secrets.MESSAGE_STATIC_DATA_PRIVATE_KEY }}
- name: Check out message-static-data
uses: actions/checkout@v6
with:
repository: iiasa/message-static-data
path: message-static-data
ssh-key: ${{ secrets.MESSAGE_STATIC_DATA_PRIVATE_KEY }}
lfs: true
# Only check out the following directories, in order to limit bandwidth usage:
sparse-checkout: |
iea/eei
ssp
pytest:
needs: [ check, warm-lfs-cache ]
strategy:
matrix:
os:
- macos-15-intel
- macos-latest
- ubuntu-latest
- windows-latest
version:
# In each group:
# - Versions of ixmp and message_ix to test.
# - Latest supported Python version for those or other dependencies.
# Minimum version given in pyproject.toml + earlier version of Python
# For this job only, the oldest version of Python supported by message-ix-models
- { upstream: v3.8.0, python: "3.10" } # Released 2024-01-12
- { upstream: v3.9.0, python: "3.13" } # 2024-06-04
- { upstream: v3.10.0, python: "3.14" } # 2025-02-21
# Latest released version + latest released Python
- { upstream: v3.11.0, python: "3.14" } # 2025-05-27
# Development version + latest released Python
- { upstream: main, python: "3.14" }
exclude:
# Specific version combinations that are invalid / not to be used
# These versions of ixmp are not able locate the arm64 GAMS API binaries
- { os: macos-latest, version: { upstream: v3.8.0 }}
- { os: macos-latest, version: { upstream: v3.9.0 }}
# Redundant with macos-latest
- { os: macos-15-intel, version: { upstream: v3.10.0 }}
- { os: macos-15-intel, version: { upstream: v3.11.0 }}
- { os: macos-15-intel, version: { upstream: main }}
fail-fast: false
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }}-py${{ matrix.version.python }}-upstream-${{ matrix.version.upstream }}
steps:
- name: Cache test data
uses: actions/cache@v4
with:
path: |
local-data
.pytest_cache/d
key: local-data-${{ matrix.os }}-upstream-${{ matrix.version.upstream }}
- name: Check out message-ix-models
uses: francisbilham11/action-cached-lfs-checkout@v3
with:
ref: ${{ needs.check.outputs.ref }}
- name: Restore message-static-data from cache
uses: actions/cache/restore@v4
with:
path: message-static-data
key: static-data-${{ matrix.os }}
- name: Set up uv, Python
uses: astral-sh/setup-uv@v7
with:
activate-environment: true
python-version: ${{ matrix.version.python }}
- uses: iiasa/actions/setup-gams@main
with:
version: ${{ env.gams-version }}
license: ${{ secrets.GAMS_LICENSE }}
- uses: ts-graphviz/setup-graphviz@v2
- name: Set Java version on Windows
if: startsWith(matrix.os, 'windows-')
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'
- name: Install packaging
run: uv pip install packaging
- name: Determine extra dependencies
id: dependencies
run : |
from os import environ
from packaging.version import Version, parse
from pathlib import Path
version_string = "${{ matrix.version.upstream }}"
if version_string != "main":
v, result = parse(version_string), []
for condition, dependency in (
(v < Version("v3.9"), "pytest == 8.0.0"), # Upstream versions < 3.9.0 use a hook argument removed in pytest 8.1.0 (#155)
(Version("v3.8") < v < Version("v3.11"), "ixmp4 < 0.11"), # https://github.com/iiasa/message-ix-models/issues/366
):
result.extend([f'"{dependency}"'] if condition else [])
Path(environ["GITHUB_OUTPUT"]).write_text(f"value={' '.join(result)}\n")
shell: python
- name: Install packages and dependencies
# By default, install:
# - ixmp, message_ix: from GitHub branches/tags per matrix.version.upstream (above)
# - dask: work around https://github.com/khaeru/genno/issues/171
# - other dependencies: from PyPI.
#
# To test against unreleased code (on `main`, or other branches for open PRs),
# temporarily edit or add lines below as needed. DO NOT merge such changes to `main`.
run: |
uv pip install --upgrade \
${{ steps.dependencies.outputs.value }} \
"dask < 2025.4.0" \
"ixmp @ git+https://github.com/iiasa/ixmp.git@${{ matrix.version.upstream }}" \
"message-ix @ git+https://github.com/iiasa/message_ix.git@${{ matrix.version.upstream }}" \
"message-ix-buildings @ git+https://github.com/iiasa/message-ix-buildings@main" \
.[docs,tests]
- name: Configure local data path
run: |
mkdir -p local-data
mix-models config set "message local data" "$(realpath local-data)"
mix-models config show
# Symlink message-static-data into local data path
mkdir -p ${{ github.workspace }}/local-data
cp -rsv $(realpath message-static-data)/* local-data/
- name: Run test suite using pytest
run: |
pytest message_ix_models \
-m "not (ece_db or snapshot)" \
--color=yes --durations=20 -rA --verbose \
--cov-report=term-missing --cov-report=xml \
--numprocesses=auto --dist=loadscope \
--local-cache --jvmargs="-Xmx6G"
- name: Upload test coverage to Codecov.io
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }} # Required
pre-commit:
name: Code quality
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with: { ref: "${{ needs.check.outputs.ref }}" }
- uses: astral-sh/setup-uv@v7
with: { python-version: "${{ env.python-version }}" }
- name: Clear and re-create the pre-commit environments
run: uvx pre-commit clean
if: github.event_name == 'schedule' # Comment this line to force clear
- run: |
uvx --with=pre-commit-uv \
pre-commit run \
--all-files --color=always --show-diff-on-failure --verbose