Skip to content

Commit 339c0b6

Browse files
committed
build: Switch to maturin as build backend
This commit replaces the used build backend and configuration, as well as the CI workflows, to use maturin instead of setuptools.
1 parent 5c77f02 commit 339c0b6

4 files changed

Lines changed: 214 additions & 116 deletions

File tree

.github/workflows/code-qa.yml

Lines changed: 201 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ on:
1111
tags: ["v*.*.*"]
1212
workflow_dispatch:
1313

14+
permissions:
15+
contents: read
16+
1417
concurrency:
1518
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref_type == 'tag' && github.sha || '0' }}
1619
cancel-in-progress: true
@@ -20,8 +23,6 @@ jobs:
2023
runs-on: ubuntu-latest
2124
steps:
2225
- uses: actions/checkout@v6
23-
with:
24-
fetch-depth: 0
2526
- uses: astral-sh/setup-uv@v7
2627
with:
2728
enable-cache: true
@@ -35,15 +36,11 @@ jobs:
3536
runs-on: ubuntu-latest
3637
steps:
3738
- uses: actions/checkout@v6
39+
- name: Build sdist
40+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
3841
with:
39-
fetch-depth: 0
40-
- uses: astral-sh/setup-uv@v7
41-
with:
42-
enable-cache: true
43-
cache-dependency-glob: "**/pyproject.toml"
44-
python-version: "3.13"
45-
- name: Package the sources
46-
run: make sdist
42+
command: sdist
43+
args: --out dist
4744
- name: Upload artifacts
4845
uses: actions/upload-artifact@v5
4946
with:
@@ -52,120 +49,241 @@ jobs:
5249
if-no-files-found: error
5350

5451
build: # {{{1
55-
name: Build wheel for ${{matrix.os}} / ${{matrix.arch}}${{ matrix.manylinux && ' / ' || '' }}${{ matrix.manylinux || '' }}
56-
runs-on: ${{matrix.os}}
52+
name: Build wheels for ${{ matrix.platform.tag }} ${{ matrix.platform.target }}
53+
runs-on: ${{ matrix.platform.runner }}
5754
strategy:
5855
fail-fast: false
5956
matrix:
60-
include:
57+
platform:
6158
# Linux manylinux {{{
62-
- os: ubuntu-latest
63-
arch: x86_64
64-
manylinux: manylinux
65-
- os: ubuntu-24.04-arm
66-
arch: aarch64
67-
manylinux: manylinux
59+
- runner: ubuntu-22.04
60+
target: x86_64
61+
tag: manylinux
62+
manylinux: auto
63+
unittests: true
64+
- runner: ubuntu-22.04
65+
target: x86
66+
tag: manylinux
67+
manylinux: auto
68+
- runner: ubuntu-22.04
69+
target: aarch64
70+
tag: manylinux
71+
manylinux: auto
72+
- runner: ubuntu-22.04
73+
target: armv7
74+
tag: manylinux
75+
manylinux: auto
76+
- runner: ubuntu-22.04
77+
target: s390x
78+
tag: manylinux
79+
manylinux: auto
80+
- runner: ubuntu-22.04
81+
target: ppc64le
82+
tag: manylinux
83+
manylinux: auto
6884
# }}}
6985
# Linux musllinux {{{
70-
- os: ubuntu-latest
71-
arch: x86_64
72-
manylinux: musllinux
73-
- os: ubuntu-24.04-arm
74-
arch: aarch64
75-
manylinux: musllinux
86+
- runner: ubuntu-22.04
87+
target: x86_64
88+
tag: musllinux
89+
manylinux: musllinux_1_2
90+
- runner: ubuntu-22.04
91+
target: x86
92+
tag: musllinux
93+
manylinux: musllinux_1_2
94+
- runner: ubuntu-22.04
95+
target: aarch64
96+
tag: musllinux
97+
manylinux: musllinux_1_2
98+
- runner: ubuntu-22.04
99+
target: armv7
100+
tag: musllinux
101+
manylinux: musllinux_1_2
76102
# }}}
77103
# macOS {{{
78-
- os: macos-15-intel
79-
arch: x86_64
80-
- os: macos-latest
81-
arch: arm64
104+
- runner: macos-15-intel
105+
target: x86_64
106+
tag: macos
107+
- runner: macos-latest
108+
target: aarch64
109+
tag: macos
110+
unittests: true
82111
# }}}
83-
# Windows {{{
84-
- os: windows-latest
85-
arch: x86
86-
- os: windows-latest
87-
arch: AMD64
88-
# }}}
89-
env:
90-
CIBW_ARCHS: ${{matrix.arch}}
91-
CIBW_ENVIRONMENT: 'PATH="$HOME/.cargo/bin:$PATH"'
92-
CIBW_ENVIRONMENT_WINDOWS: 'PATH="$UserProfile\.cargo\bin;$PATH"'
93-
MACOSX_DEPLOYMENT_TARGET: "11.0"
94112
steps:
95113
- uses: actions/checkout@v6
114+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
96115
with:
97-
fetch-depth: 0
98-
- name: Determine which Python versions to test against
116+
python-version: "3.10"
117+
- name: Build abi3 wheel
118+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
119+
with:
120+
target: ${{ matrix.platform.target }}
121+
args: --release --out dist -i python3.10
122+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
123+
manylinux: ${{ matrix.platform.manylinux }}
124+
- name: Build 3.13t wheel
125+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
126+
with:
127+
target: ${{ matrix.platform.target }}
128+
args: --release --out dist -i python3.13t
129+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
130+
manylinux: ${{ matrix.platform.manylinux }}
131+
- name: Build 3.14t wheel
132+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
133+
with:
134+
target: ${{ matrix.platform.target }}
135+
args: --release --out dist -i python3.14t
136+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
137+
manylinux: ${{ matrix.platform.manylinux }}
138+
- name: Assert that exactly one abi3 wheel exists
99139
shell: bash
100-
env:
101-
ENV_TAG: ${{runner.os}}-${{matrix.arch}}-${{matrix.manylinux}}
102-
MANYLINUX: ${{matrix.manylinux}}
103140
run: |-
104-
if [[ "$ENV_TAG" == "Linux-x86_64-manylinux" || "$ENV_TAG" == "macOS-arm64-" ]]; then
105-
echo "CIBW_BUILD=cp*-$MANYLINUX*" >> "$GITHUB_ENV"
106-
echo "CIBW_SKIP=cp*t-*" >> "$GITHUB_ENV"
141+
wheels=(dist/*-abi3-*.whl)
142+
if [[ "${#wheels[@]}" -eq 1 ]] && [[ -e "${wheels[0]}" ]]; then
143+
echo "OK"
107144
else
108-
echo "CIBW_BUILD=cp310-$MANYLINUX* cp314-$MANYLINUX*" >> "$GITHUB_ENV"
145+
echo "Expected exactly one abi3 wheel, found ${#wheels[@]}:"
146+
printf ' - %s\n' "${wheels[@]}"
147+
exit 1
109148
fi
110-
- name: Build wheels
111-
uses: pypa/cibuildwheel@v3.3.0
149+
- uses: astral-sh/setup-uv@v7
150+
if: matrix.platform.unittests
151+
with:
152+
python-version: "3.10"
153+
cache-python: "true"
154+
ignore-nothing-to-cache: "true"
155+
- name: Run unittests with Python 3.10
156+
if: matrix.platform.unittests
157+
env:
158+
UV_PYTHON: cp310
159+
shell: bash
160+
run: |-
161+
echo "::group::Prepare test environment"
162+
uv sync --group test --no-install-project
163+
. .venv/bin/activate
164+
uv pip install dist/*-"$UV_PYTHON"-*.whl
165+
echo "::endgroup::"
166+
167+
make test
168+
- name: Run unittests with Python 3.14t
169+
if: matrix.platform.unittests
170+
env:
171+
UV_PYTHON: cp314t
172+
shell: bash
173+
run: |-
174+
echo "::group::Prepare test environment"
175+
uv sync --group test --no-install-project
176+
. .venv/bin/activate
177+
uv pip install dist/*-"$UV_PYTHON"-*.whl
178+
echo "::endgroup::"
179+
180+
make test
112181
- name: Upload artifacts
113182
uses: actions/upload-artifact@v5
114183
with:
115-
name: wheel-${{runner.os}}-${{matrix.arch}}${{ matrix.manylinux && '-' || '' }}${{ matrix.manylinux || '' }}
116-
path: wheelhouse/
184+
name: wheels-${{ matrix.platform.tag }}-${{ matrix.platform.target }}
185+
path: dist/
117186
if-no-files-found: error
118187

119-
build-pure: # {{{1
120-
name: Build pure-Python wheel
121-
runs-on: ubuntu-latest
188+
build-windows: # {{{1
189+
name: Build wheels for windows ${{ matrix.platform.target }}
190+
runs-on: windows-latest
191+
strategy:
192+
fail-fast: false
193+
matrix:
194+
platform:
195+
- target: x64
196+
unittests: true
197+
- target: x86
122198
steps:
123199
- uses: actions/checkout@v6
200+
- name: Set up Python 3.10
201+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
124202
with:
125-
fetch-depth: 0
203+
python-version: "3.10"
204+
architecture: ${{ matrix.platform.target }}
205+
- name: Set up Python 3.13t
206+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
207+
with:
208+
python-version: "3.13t"
209+
architecture: ${{ matrix.platform.target }}
210+
- name: Set up Python 3.14t
211+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
212+
with:
213+
python-version: "3.14t"
214+
architecture: ${{ matrix.platform.target }}
215+
- name: Build abi3 wheel
216+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
217+
with:
218+
target: ${{ matrix.platform.target }}
219+
args: --release --out dist -i python3.10
220+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
221+
- name: Build 3.13t wheel
222+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
223+
with:
224+
target: ${{ matrix.platform.target }}
225+
args: --release --out dist -i python3.13t
226+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
227+
- name: Build 3.14t wheel
228+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
229+
with:
230+
target: ${{ matrix.platform.target }}
231+
args: --release --out dist -i python3.14t
232+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
233+
- name: Assert that exactly one abi3 wheel exists
234+
shell: bash
235+
run: |-
236+
wheels=(dist/*-abi3-*.whl)
237+
if [[ "${#wheels[@]}" -eq 1 ]] && [[ -e "${wheels[0]}" ]]; then
238+
echo "OK"
239+
else
240+
echo "Expected exactly one abi3 wheel, found ${#wheels[@]}:"
241+
printf ' - %s\n' "${wheels[@]}"
242+
exit 1
243+
fi
126244
- uses: astral-sh/setup-uv@v7
245+
if: matrix.platform.unittests
127246
with:
128-
enable-cache: true
129-
cache-dependency-glob: "**/pyproject.toml"
130-
python-version: "3.13"
131-
- name: Build the wheel
247+
python-version: "3.10"
248+
cache-python: "true"
249+
ignore-nothing-to-cache: "true"
250+
- name: Run unittests with Python 3.10
251+
if: matrix.platform.unittests
252+
env:
253+
UV_PYTHON: cp310
254+
shell: bash
132255
run: |-
133-
SETUPTOOLS_SCM_PRETEND_VERSION="$(
134-
uvx --with setuptools_scm python -c \
135-
"import setuptools_scm as scm; print(scm.get_version())"
136-
)"
137-
export SETUPTOOLS_SCM_PRETEND_VERSION
138-
139-
uvx --with tomli_w python <<EOF
140-
import tomllib, tomli_w
141-
with open("pyproject.toml", "rb") as f:
142-
metadata = tomllib.load(f)
143-
del metadata["tool"]["setuptools-rust"]
144-
with open("pyproject.toml", "wb") as f:
145-
tomli_w.dump(metadata, f)
146-
EOF
256+
echo "::group::Prepare test environment"
257+
uv sync --group test --no-install-project
258+
. .venv/bin/activate
259+
uv pip install dist/*-"$UV_PYTHON"-*.whl
260+
echo "::endgroup::"
147261
148-
make wheel
149-
- name: Run unittests
262+
make test
263+
- name: Run unittests with Python 3.14t
264+
if: matrix.platform.unittests
265+
env:
266+
UV_PYTHON: cp314t
267+
shell: bash
150268
run: |-
151269
echo "::group::Prepare test environment"
152270
uv sync --group test --no-install-project
153271
. .venv/bin/activate
154-
uv pip install dist/*.whl
272+
uv pip install dist/*-"$UV_PYTHON"-*.whl
155273
echo "::endgroup::"
156274
157-
coverage run
275+
make test
158276
- name: Upload artifacts
159277
uses: actions/upload-artifact@v5
160278
with:
161-
name: wheel-${{runner.os}}-pure
279+
name: wheels-windows-${{ matrix.platform.target }}
162280
path: dist/
163281
if-no-files-found: error
164282

165283
publish: # {{{1
166284
name: Publish release
167285
runs-on: ubuntu-latest
168-
needs: [build, build-pure, example-notebooks]
286+
needs: [build, build-windows, sdist, example-notebooks]
169287
if: startsWith(github.ref, 'refs/tags/v')
170288
environment:
171289
name: pypi
@@ -200,8 +318,6 @@ jobs:
200318
runs-on: ubuntu-latest
201319
steps:
202320
- uses: actions/checkout@v6
203-
with:
204-
fetch-depth: 0
205321
- uses: astral-sh/setup-uv@v7
206322
with:
207323
enable-cache: true
@@ -217,8 +333,6 @@ jobs:
217333
contents: write
218334
steps:
219335
- uses: actions/checkout@v6
220-
with:
221-
fetch-depth: 0
222336
- uses: astral-sh/setup-uv@v7
223337
with:
224338
enable-cache: true
@@ -261,7 +375,7 @@ jobs:
261375
- uses: actions/download-artifact@v6
262376
with:
263377
path: dist/
264-
name: wheel-Linux-x86_64-manylinux
378+
name: wheels-manylinux-x86_64
265379
- uses: astral-sh/setup-uv@v7
266380
with:
267381
enable-cache: true
@@ -277,5 +391,5 @@ jobs:
277391
uvx --with setuptools_scm python -c \
278392
"import setuptools_scm as scm; print(scm.get_version())"
279393
)" >> "$GITHUB_ENV"
280-
- run: uv add --dev ./dist/*.whl pytest pytest-xdist && uv sync
394+
- run: uv add --dev ./dist/*-abi3-*.whl pytest pytest-xdist && uv sync
281395
- run: uv run pytest -n auto

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ help: #: Show this help
1414
dev: .venv #: Set up development environment
1515
.venv: pyproject.toml
1616
uv sync --inexact
17+
.venv/bin/python -m maturin_import_hook site install
1718
touch -c .venv
1819

1920
.PHONY: install-hooks

0 commit comments

Comments
 (0)