forked from pydantic/pydantic
-
Notifications
You must be signed in to change notification settings - Fork 0
439 lines (359 loc) · 12.6 KB
/
ci.yml
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
name: CI
on:
push:
branches:
- main
tags:
- '**'
pull_request: {}
env:
COLUMNS: 150
PDM_DEPS: 'urllib3<2'
FINDPYTHON_GET_VERSION_TIMEOUT: 30
jobs:
lint:
runs-on: ubuntu-latest
name: lint ${{ matrix.python-version }}
strategy:
fail-fast: false
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: ${{ matrix.python-version }}
cache: true
allow-python-prereleases: true
- name: install
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G linting -G email
- uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files --verbose
env:
SKIP: no-commit-to-branch
docs-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
# cloudflare pages build containers run 3.8, hence using it here
python-version: '3.8'
- name: install dependencies
# Unlike the docs build, we don't use mkdocs_material-insiders
# Because the secret for accessing the library is not accessible from forks, but we still want to run
# this job on public CI runs.
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G docs
- run: pdm run python -c 'import docs.plugins.main'
# Adding local symlinks gets nice source locations like
# pydantic_core/core_schema.py
# instead of
# .venv/lib/python3.10/site-packages/pydantic_core/core_schema.py
- name: prepare shortcuts for extra modules
run: |
ln -s .venv/lib/python*/site-packages/pydantic_core pydantic_core
ln -s .venv/lib/python*/site-packages/pydantic_settings pydantic_settings
ln -s .venv/lib/python*/site-packages/pydantic_extra_types pydantic_extra_types
- run: pdm run mkdocs build
test-memray:
name: test memray
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: '3.12'
cache: true
- name: install deps
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G testing -G testing-extra -G email -G memray
pdm add pytest-memray
- name: test
run: pdm run pytest --ignore=tests/mypy/ --ignore=tests/test_docs.py --memray
test:
name: test ${{ matrix.os }} / ${{ matrix.python-version }}
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos, windows]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
include:
# no pydantic-core binaries for pypy on windows, so tests take absolute ages
# macos tests with pypy take ages (>10mins) since pypy is very slow
# so we only test pypy on ubuntu
- os: ubuntu
python-version: 'pypy3.9'
- os: ubuntu
python-version: 'pypy3.10'
env:
OS: ${{ matrix.os }}
DEPS: yes
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: ${{ matrix.python-version }}
cache: true
allow-python-prereleases: true
- name: install deps
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G testing -G email
- run: pdm info && pdm list
- run: 'pdm run python -c "import pydantic.version; print(pydantic.version.version_info())"'
- run: mkdir coverage
- name: test without deps
# speed up by skipping this step on pypy
if: "!startsWith(matrix.python-version, 'pypy')"
run: make test
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}-without-deps
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-without-deps
- name: install extra deps
run: pdm install -G testing-extra -G email
- name: test with deps
run: make test
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}-with-deps
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-with-deps
- name: store coverage files
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.os }}-${{ matrix.python-version }}
path: coverage
test-fastapi:
# If some tests start failing due to out-of-date schemas/validation errors/etc.,
# update the `tests/test_fastapi.sh` script to exclude tests that have known-acceptable failures.
name: test fastapi
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: set up python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: test
run: make test-fastapi
test-plugin:
name: test pydantic plugin
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: '3.12'
cache: true
- name: install deps
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G testing
- name: install example plugin
run: pdm add ./tests/plugin
- run: pdm run pytest ./tests/plugin
env:
TEST_PLUGIN: 1
# uninstalling is necessary to avoid creating a pdm cache shared with other jobs
# which includes the plugin
- name: uninstall example plugin
run: pdm remove ./tests/plugin
test-mypy:
name: mypy ${{ matrix.mypy-version }} / ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# test recent mypy versions on 3.10 and mypy 1.0.1 on all supported python versions
# if you change the value in the lockfile add the old value to this list
mypy-version: ['1.0.1', 'lockfile', '1.2.0', '1.4.1', '1.5.1']
python-version: ['3.10']
include:
- mypy-version: 'lockfile'
python-version: '3.8'
- mypy-version: 'lockfile'
python-version: '3.9'
- mypy-version: 'lockfile'
python-version: '3.11'
# TODO: Once Python 3.7 is removed, and mypy is bumped on the lockfile, we can add 'lockfile' again.
- mypy-version: '1.5.1'
python-version: '3.12'
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: ${{ matrix.python-version }}
cache: true
allow-python-prereleases: true
- name: install deps
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G testing -G mypy
- name: install mypy
if: steps.cache.outputs.cache-hit != 'true'
run: |
if [ ${{ matrix.mypy-version }} != 'lockfile' ]; then
pdm remove -G linting mypy && pdm remove -G mypy mypy && pdm add mypy==${{ matrix.mypy-version }}
fi
pdm list
- run: mkdir coverage
- name: run mypy tests
run: pdm run coverage run -m pytest tests/mypy --test-mypy
env:
COVERAGE_FILE: coverage/.coverage.linux-py${{ matrix.python-version }}-mypy${{ matrix.mypy-version }}
CONTEXT: linux-py${{ matrix.python-version }}-mypy${{ matrix.mypy-version }}
- name: install node for pyright
uses: actions/setup-node@v4
with:
node-version: '18'
- name: install pyright
run: npm install -g pyright@1.1.345 # try to keep this in sync with .pre-commit-config.yaml
- name: run pyright tests
run: make test-pyright
env:
COVERAGE_FILE: coverage/.coverage.linux-py${{ matrix.python-version }}-pyright
CONTEXT: linux-py${{ matrix.python-version }}-pyright
- name: store coverage files
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.os }}-${{ matrix.python-version }}-mypy${{ matrix.mypy-version }}
path: coverage
coverage-combine:
needs: [test, test-mypy]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: get coverage files
uses: actions/download-artifact@v4
with:
merge-multiple: true
pattern: coverage-*
path: coverage
- run: pip install coverage[toml]
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage report
- run: coverage html --show-contexts --title "pydantic coverage for ${{ github.sha }}"
- name: Store coverage html
uses: actions/upload-artifact@v4
with:
name: coverage-html
path: htmlcov
test-typing-extensions:
name: test typing-extensions ${{ matrix.typing-extensions-version }} on Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# test the oldest supported version and main
typing-extensions-version: ['4.6.1', 'main']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: pdm-project/setup-pdm@v4
with:
python-version: ${{ matrix.python-version }}
cache: true
allow-python-prereleases: true
- name: install deps
run: |
pdm venv create --with-pip --force $PYTHON
pdm install -G testing -G email
- name: install typing-extensions
run: |
if [ ${{ matrix.typing-extensions-version }} == 'main' ]; then
pdm remove typing-extensions && pdm add 'typing-extensions @ git+https://github.com/python/typing_extensions.git'
else
pdm remove typing-extensions && pdm add 'typing-extensions==${{ matrix.typing-extensions-version }}'
fi
pdm list
- name: test
run: make test
# https://github.com/marketplace/actions/alls-green
check: # This job does nothing and is only used for the branch protection
if: always()
outputs:
result: ${{ steps.all-green.outputs.result }}
needs:
- lint
- docs-build
- test
- test-memray
- test-mypy
- test-fastapi
- test-plugin
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
id: all-green
with:
jobs: ${{ toJSON(needs) }}
release:
needs: [check]
if: needs.check.outputs.result == 'success' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
outputs:
pydantic-version: ${{ steps.check-tag.outputs.VERSION }}
steps:
- uses: actions/checkout@v4
- name: set up python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: install
run: pip install -U build
- name: check version
id: check-tag
uses: samuelcolvin/check-python-version@v4.1
with:
version_file_path: pydantic/version.py
- name: build
run: python -m build
- name: Upload package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
send-tweet:
name: Send tweet
needs: [release]
if: needs.release.result == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install tweepy==4.14.0
- name: Send tweet
shell: python
run: |
import os
import tweepy
client = tweepy.Client(
access_token=os.getenv("TWITTER_ACCESS_TOKEN"),
access_token_secret=os.getenv("TWITTER_ACCESS_TOKEN_SECRET"),
consumer_key=os.getenv("TWITTER_CONSUMER_KEY"),
consumer_secret=os.getenv("TWITTER_CONSUMER_SECRET"),
)
version = os.getenv("VERSION").strip('"')
tweet = os.getenv("TWEET").format(version=version)
client.create_tweet(text=tweet)
env:
VERSION: ${{ needs.release.outputs.pydantic-version }}
TWEET: |
Pydantic version {version} is out! 🎉
https://github.com/pydantic/pydantic/releases/tag/v{version}
TWITTER_CONSUMER_KEY: ${{ secrets.TWITTER_CONSUMER_KEY }}
TWITTER_CONSUMER_SECRET: ${{ secrets.TWITTER_CONSUMER_SECRET }}
TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}