-
-
Notifications
You must be signed in to change notification settings - Fork 49
302 lines (268 loc) · 11.4 KB
/
Copy pathcibuildwheels.yml
File metadata and controls
302 lines (268 loc) · 11.4 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
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
name: Python wheels
on:
# Trigger the workflow only for tags and PRs to the main branch
push:
tags:
- '*'
pull_request:
branches:
- main
env:
CIBW_BUILD_VERBOSITY: 1
# Skip testing on aarch64 for now, as it is emulated on GitHub Actions and takes too long
# Now that github provides native arm64 runners, we can enable tests again
# CIBW_TEST_SKIP: "*linux*aarch64*"
# musllinux takes too long to build, and it's not worth it for now
# (PyPy needs opting in via `enable` since cibuildwheel 4, so no pp* here)
CIBW_SKIP: "*musllinux* *-win32"
# Intel Macs are EOL and Rust-based deps (pydantic-core) publish no cp315
# x86_64 wheels yet, so `pip install` of the test venv would cross-compile
# them from the arm64 runner -- which lacks the x86_64-apple-darwin Rust
# target. The wheel itself builds fine, so ship it and skip only its test.
# (`cp315*` so the free-threaded cp315t build is skipped for the same reason)
CIBW_TEST_SKIP: "cp315*-macosx_x86_64"
# Use explicit generator/compiler env vars; CMAKE_ARGS with spaces is not split on Windows.
CIBW_ENVIRONMENT_WINDOWS: >-
CMAKE_GENERATOR=Ninja
CC=clang-cl
CXX=clang-cl
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }} for ${{ matrix.arch }}
runs-on: ${{ matrix.runs-on || matrix.os }}
permissions:
contents: write
env:
CIBW_BUILD: ${{ matrix.cibw_pattern }}
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
CIBW_ARCHS_MACOS: "x86_64 arm64"
strategy:
fail-fast: false
matrix:
# Three builds per platform, not one per Python version:
#
# cp311 -> a single `cp311-abi3` wheel serving CPython 3.11+, via
# `wheel.py-api` in pyproject.toml. Building it on any
# other version would emit the *same* filename, so only
# the floor version is built.
# cp314t -> free-threaded 3.14. Cannot use abi3: the free-threaded
# cp315t ABI is distinct, and its stable variant (abi3t, PEP 803)
# starts at 3.15 and needs a PEP 793 module export hook
# that Cython does not emit yet. These stay
# version-specific until that lands upstream.
#
# cp313t is deliberately absent: 3.13's free-threaded build was still
# experimental (PEP 703 phase I) with a large single-thread penalty.
# cibuildwheel keeps it behind CIBW_ENABLE: cpython-freethreading.
#
# NOTE: cibuildwheel only tests a wheel on the interpreter that built
# it, so the abi3 wheel is exercised on 3.11 alone here. The
# test_abi3_matrix job below installs it on every supported version.
include:
# Linux x86_64 builds
- os: ubuntu-latest
arch: x86_64
cibw_pattern: "cp311-manylinux* cp314t-manylinux* cp315t-manylinux*"
artifact_name: "linux-x86_64"
# Linux ARM64 builds (native runners)
- os: ubuntu-24.04-arm
arch: aarch64
cibw_pattern: "cp311-manylinux* cp314t-manylinux* cp315t-manylinux*"
artifact_name: "linux-aarch64"
# Don't use native runners for now (looks like wait times are too long)
#runs-on: ["ubuntu-latest", "arm64"]
# Windows builds
- os: windows-latest
arch: x86_64
cibw_pattern: "cp311-win_amd64 cp314t-win_amd64 cp315t-win_amd64"
artifact_name: "windows-x86_64"
# macOS builds (universal2)
- os: macos-latest
arch: x86_64
cibw_pattern: "cp311-macosx* cp314t-macosx* cp315t-macosx*"
artifact_name: "macos-universal2"
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v7
with:
# Use the most recent released python
python-version: '3.x'
# For some reason, this is still needed, even when using new arm64 runners
# - name: Set up QEMU
# if: ${{ matrix.arch == 'aarch64' }}
# uses: docker/setup-qemu-action@v3
- name: Install Ninja
id: ninja
uses: turtlesec-no/get-ninja@main
- name: Add LLVM to PATH (Windows)
if: ${{ matrix.os == 'windows-latest' }}
run: echo "C:\\Program Files\\LLVM\\bin" >> $env:GITHUB_PATH
- name: Install MSVC amd64
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: amd64
- name: Build wheels
uses: pypa/cibuildwheel@v4.2
- name: Make sdist
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
python -m pip install build
python -m build --sdist --outdir wheelhouse .
- name: Build building extension from sdist package
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
cd ./wheelhouse
tar -xzf blosc2-*.tar.gz
cd ./blosc2-*/
python -m venv sdist_test_env
source sdist_test_env/bin/activate
pip install pip --upgrade
pip install --break-system-packages -e . --group test
- name: Test sdist package with pytest
if: ${{ matrix.os == 'ubuntu-latest' }}
timeout-minutes: 10
run: |
cd ./wheelhouse/blosc2-*/
source sdist_test_env/bin/activate
python -m pytest tests/test_open.py tests/test_vlmeta.py tests/ndarray/test_evaluate.py
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact_name }}
path: |
./wheelhouse/*.whl
./wheelhouse/*.tar.gz
build_wheels_wasm:
name: Build WASM/Pyodide wheels for ${{ matrix.p_ver }}
runs-on: ubuntu-latest
env:
CIBW_BUILD: ${{ matrix.cibw_build }}
# WASM/Pyodide has no SIMD/runtime CPU detection; disable optimised paths
CMAKE_ARGS: "-DWITH_ZLIB_OPTIM=OFF -DWITH_OPTIM=OFF -DWITH_RUNTIME_CPU_DETECTION=OFF"
CIBW_TEST_COMMAND: "pytest {project}/tests"
# Pin the Pyodide version explicitly per target for reproducible builds.
# Note: in-memory SChunk get_slice is broken on the Pyodide 0.29.x
# Emscripten toolchain (works on 314); see gh-664. The affected test is
# xfailed on WASM, so the cp313 pin just matches cibuildwheel's default.
CIBW_PYODIDE_VERSION: ${{ matrix.pyodide_version }}
strategy:
fail-fast: false
matrix:
include:
# Python 3.13 -> pyemscripten_2025_0
- p_ver: "3.13"
cibw_build: "cp313-*"
pyodide_version: "0.29.4"
artifact_name: "wasm-pyodide-cp313"
# Python 3.14 -> pyemscripten_2026_0
- p_ver: "3.14"
cibw_build: "cp314-*"
pyodide_version: "314.0.0"
artifact_name: "wasm-pyodide-cp314"
steps:
- name: Checkout repo
uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: '3.x'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake
- name: Install cibuildwheel
run: pip install "cibuildwheel==4.1.*"
- name: Build wheels
# Testing is performed automatically by cibuildwheel (via node).
# platform=pyodide can only be set via the CLI flag, not an env var.
run: cibuildwheel --platform pyodide
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact_name }}
path: ./wheelhouse/*.whl
# The abi3 wheel is built once, on 3.11, and cibuildwheel only tests a wheel
# on the interpreter that produced it. Every other supported version would
# therefore ship untested, so install the one wheel on each of them and run a
# slice of the suite. This is also the job that would catch a CPython release
# breaking the stable ABI -- the failure mode abi3 trades away rebuilds for.
test_abi3_matrix:
name: Test abi3 wheel on ${{ matrix.python-version }} (${{ matrix.os }})
needs: [ build_wheels ]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Both are real matrix dimensions so they cross-product (15 short jobs).
# The `include` entries key on `os`, which is an existing dimension, so
# they attach artifact_name to the matching combinations rather than
# being appended as extra jobs.
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
include:
- os: ubuntu-latest
artifact_name: "linux-x86_64"
- os: windows-latest
artifact_name: "windows-x86_64"
- os: macos-latest
artifact_name: "macos-universal2"
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
# 3.15 is still a pre-release until October
allow-prereleases: true
- uses: actions/download-artifact@v8
with:
name: ${{ matrix.artifact_name }}
path: ./wheelhouse
# Pin the exact version so pip resolves blosc2 from ./wheelhouse (picking
# the arch-compatible file) while still pulling dependencies from PyPI.
- name: Install the abi3 wheel
shell: bash
run: |
WHL=$(ls wheelhouse/blosc2-*abi3*.whl | head -1)
echo "Installing $WHL on $(python -V)"
python -m pip install --upgrade pip
python -m pip install --find-links ./wheelhouse "blosc2==$(basename "$WHL" | cut -d- -f2)"
# Check that the module is not version-tagged, rather than looking for a
# literal ".abi3." -- that infix is a POSIX convention. On Windows a
# limited-API module is just `blosc2_ext.pyd`, versus
# `blosc2_ext.cp314-win_amd64.pyd` for a version-specific build.
# EXTENSION_SUFFIXES[0] is the version-tagged suffix on every platform,
# so "does not end with it" is the portable way to say "this is abi3".
- name: Confirm the abi3 module was the one loaded
shell: bash
run: |
python -c "
import importlib.machinery as machinery, os
import blosc2, blosc2.blosc2_ext as ext
name = os.path.basename(ext.__file__)
tagged = machinery.EXTENSION_SUFFIXES[0]
print('module:', name, '| version-tagged suffix:', tagged)
assert not name.endswith(tagged), f'version-specific module: {name}'
print('OK: loaded a version-independent (abi3) module')
blosc2.print_versions()
"
- name: Run a slice of the test suite
shell: bash
run: |
python -m pip install pytest
python -m pytest tests/test_open.py tests/test_vlmeta.py \
tests/ndarray/test_evaluate.py -q -p no:cacheprovider
upload_pypi:
needs: [ build_wheels, build_wheels_wasm, test_abi3_matrix ]
runs-on: ubuntu-latest
# Only upload wheels when tagging (typically a release)
if: startsWith(github.event.ref, 'refs/tags')
steps:
- uses: actions/download-artifact@v8
with:
path: ./wheelhouse
merge-multiple: true # Merge all the wheels artifacts into one directory
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.blosc_pypi_secret }}
packages-dir: wheelhouse/