Skip to content

Commit 49722d9

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 49722d9

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
82-
# }}}
83-
# Windows {{{
84-
- os: windows-latest
85-
arch: x86
86-
- os: windows-latest
87-
arch: AMD64
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
88111
# }}}
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+
- uses: astral-sh/setup-uv@v7
118+
if: matrix.platform.unittests
119+
with:
120+
python-version: "3.10"
121+
cache-python: "true"
122+
ignore-nothing-to-cache: "true"
123+
- name: Build abi3 wheel
124+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
125+
with:
126+
target: ${{ matrix.platform.target }}
127+
args: --release --out dist -i python3.10
128+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
129+
manylinux: ${{ matrix.platform.manylinux }}
130+
- name: Run unittests with Python 3.10
131+
if: matrix.platform.unittests
132+
env:
133+
UV_PYTHON: cp310
99134
shell: bash
135+
run: |-
136+
echo "::group::Prepare test environment"
137+
uv sync --group test --no-install-project
138+
. .venv/bin/activate
139+
uv pip install dist/*-"$UV_PYTHON"-*.whl
140+
echo "::endgroup::"
141+
142+
make test
143+
- name: Build 3.13t wheel
144+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
145+
with:
146+
target: ${{ matrix.platform.target }}
147+
args: --release --out dist -i python3.13t
148+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
149+
manylinux: ${{ matrix.platform.manylinux }}
150+
- name: Build 3.14t wheel
151+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
152+
with:
153+
target: ${{ matrix.platform.target }}
154+
args: --release --out dist -i python3.14t
155+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
156+
manylinux: ${{ matrix.platform.manylinux }}
157+
- name: Run unittests with Python 3.14t
158+
if: matrix.platform.unittests
100159
env:
101-
ENV_TAG: ${{runner.os}}-${{matrix.arch}}-${{matrix.manylinux}}
102-
MANYLINUX: ${{matrix.manylinux}}
160+
UV_PYTHON: cp314t
161+
shell: bash
103162
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"
163+
echo "::group::Prepare test environment"
164+
uv sync --group test --no-install-project
165+
. .venv/bin/activate
166+
uv pip install dist/*-"$UV_PYTHON"-*.whl
167+
echo "::endgroup::"
168+
169+
make test
170+
- name: Assert that exactly one abi3 wheel exists
171+
shell: bash
172+
run: |-
173+
wheels=(dist/*-abi3-*.whl)
174+
if [[ "${#wheels[@]}" -eq 1 ]] && [[ -e "${wheels[0]}" ]]; then
175+
echo "OK"
107176
else
108-
echo "CIBW_BUILD=cp310-$MANYLINUX* cp314-$MANYLINUX*" >> "$GITHUB_ENV"
177+
echo "Expected exactly one abi3 wheel, found ${#wheels[@]}:"
178+
printf ' - %s\n' "${wheels[@]}"
179+
exit 1
109180
fi
110-
- name: Build wheels
111-
uses: pypa/cibuildwheel@v3.3.0
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 }}
126215
- uses: astral-sh/setup-uv@v7
216+
if: matrix.platform.unittests
127217
with:
128-
enable-cache: true
129-
cache-dependency-glob: "**/pyproject.toml"
130-
python-version: "3.13"
131-
- name: Build the wheel
218+
python-version: "3.10"
219+
cache-python: "true"
220+
ignore-nothing-to-cache: "true"
221+
- name: Build abi3 wheel
222+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
223+
with:
224+
target: ${{ matrix.platform.target }}
225+
args: --release --out dist -i python3.10
226+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
227+
- name: Run unittests with Python 3.10
228+
if: matrix.platform.unittests
229+
env:
230+
UV_PYTHON: cp310
231+
shell: bash
132232
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
233+
echo "::group::Prepare test environment"
234+
uv sync --group test --no-install-project
235+
. .venv/Scripts/activate
236+
uv pip install dist/*-"$UV_PYTHON"-*.whl
237+
echo "::endgroup::"
147238
148-
make wheel
149-
- name: Run unittests
239+
make test
240+
- name: Build 3.13t wheel
241+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
242+
with:
243+
target: ${{ matrix.platform.target }}
244+
args: --release --out dist -i python3.13t
245+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
246+
- name: Build 3.14t wheel
247+
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
248+
with:
249+
target: ${{ matrix.platform.target }}
250+
args: --release --out dist -i python3.14t
251+
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
252+
- name: Run unittests with Python 3.14t
253+
if: matrix.platform.unittests
254+
env:
255+
UV_PYTHON: cp314t
256+
shell: bash
150257
run: |-
151258
echo "::group::Prepare test environment"
152259
uv sync --group test --no-install-project
153-
. .venv/bin/activate
154-
uv pip install dist/*.whl
260+
. .venv/Scripts/activate
261+
uv pip install dist/*-"$UV_PYTHON"-*.whl
155262
echo "::endgroup::"
156263
157-
coverage run
264+
make test
265+
- name: Assert that exactly one abi3 wheel exists
266+
shell: bash
267+
run: |-
268+
wheels=(dist/*-abi3-*.whl)
269+
if [[ "${#wheels[@]}" -eq 1 ]] && [[ -e "${wheels[0]}" ]]; then
270+
echo "OK"
271+
else
272+
echo "Expected exactly one abi3 wheel, found ${#wheels[@]}:"
273+
printf ' - %s\n' "${wheels[@]}"
274+
exit 1
275+
fi
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)