1- name : CI
1+ name : Release to PyPI
22
33on :
4+ workflow_dispatch : # Manual trigger only
45 push :
5- branches : ["main"]
6- pull_request :
7- branches : ["main"]
8- concurrency :
9- group : ${{ github.repository }}-${{ github.ref }}-${{ github.head_ref }}
10- cancel-in-progress : true
6+ tags :
7+ - " v[0-9]*" # Trigger on version tags like v1.0.0
118
12- env :
13- CARGO_TERM_COLOR : always
9+ permissions :
10+ # IMPORTANT: this permission is mandatory for Trusted Publishing
11+ id-token : write
12+ contents : read
1413
1514jobs :
16- build :
17- name : Build (Linux x86-64)
18- runs-on : ubuntu-latest
15+ publish-binaries :
16+ name : Publish binaries
17+ runs-on : ${{ matrix.build.os }}
18+ environment : pypi_release
19+ strategy :
20+ fail-fast : false
21+ matrix :
22+ build :
23+ - {
24+ NAME : linux-x64-glibc,
25+ OS : ubuntu-24.04,
26+ TOOLCHAIN : stable,
27+ TARGET : x86_64-unknown-linux-gnu,
28+ }
29+ - {
30+ NAME : linux-x64-musl,
31+ OS : ubuntu-24.04,
32+ TOOLCHAIN : stable,
33+ TARGET : x86_64-unknown-linux-musl,
34+ }
35+ - {
36+ NAME : linux-arm64-glibc,
37+ OS : ubuntu-24.04-arm,
38+ TOOLCHAIN : stable,
39+ TARGET : aarch64-unknown-linux-gnu,
40+ }
41+ - {
42+ NAME : linux-arm64-musl,
43+ OS : ubuntu-24.04-arm,
44+ TOOLCHAIN : stable,
45+ TARGET : aarch64-unknown-linux-musl,
46+ }
47+ - {
48+ NAME : win32-x64-msvc,
49+ OS : windows-2025,
50+ TOOLCHAIN : stable,
51+ TARGET : x86_64-pc-windows-msvc,
52+ }
53+ - {
54+ NAME : darwin-arm64,
55+ OS : macos-15,
56+ TOOLCHAIN : stable,
57+ TARGET : aarch64-apple-darwin,
58+ }
1959 steps :
20- - uses : actions/checkout@v4
21-
22- - name : Install Rust 1.90.0
23- uses : dtolnay/rust-toolchain@1.90.0
24-
25- - name : Build with locked dependencies
26- run : cargo build --locked
60+ - name : Checkout
61+ uses : actions/checkout@v4
2762
28- format :
29- name : Format Check
30- runs-on : ubuntu-latest
31- steps :
32- - uses : actions/checkout@v4
33-
34- - name : Install Rust stable
35- uses : dtolnay/rust-toolchain@stable
63+ - name : Install dependencies
64+ shell : bash
65+ run : |
66+ if [[ "${{ matrix.build.NAME }}" = *"-musl" ]]; then
67+ sudo apt-get update
68+ sudo apt-get install -y --no-install-recommends \
69+ --allow-unauthenticated musl-tools
70+ fi
71+
72+ - name : Install Rust ${{ matrix.build.TOOLCHAIN }}
73+ uses : dtolnay/rust-toolchain@master
3674 with :
37- components : rustfmt
38-
39- - name : Check formatting
40- run : cargo fmt --all -- --check
75+ toolchain : ${{ matrix.build.TOOLCHAIN }}
76+ targets : ${{ matrix.build.TARGET }}
4177
42- clippy :
43- name : Clippy
44- runs-on : ubuntu-latest
45- steps :
46- - uses : actions/checkout@v4
47-
48- - name : Install Rust 1.90.0
49- uses : dtolnay/rust-toolchain@1.90.0
78+ - name : Build Python wheels (linux x86-64 with sdist)
79+ if : matrix.build.TARGET == 'x86_64-unknown-linux-gnu'
80+ uses : PyO3/maturin-action@v1
5081 with :
51- components : clippy
52-
53- - name : Run Clippy
54- run : cargo clippy --all-targets --all-features -- -D warnings
82+ working-directory : pypi
83+ target : ${{ matrix.build.TARGET }}
84+ args : --release --sdist --out dist
85+ sccache : " true"
86+ manylinux : auto
5587
56- test :
57- name : Test
58- needs : [build, format, clippy]
59- strategy :
60- fail-fast : false
61- matrix :
62- include :
63- - os : ubuntu-latest
64- target : x86_64-unknown-linux-gnu
65- rust : stable
66- - os : ubuntu-24.04-arm
67- target : aarch64-unknown-linux-gnu
68- rust : stable
69- - os : macos-latest
70- target : aarch64-apple-darwin
71- rust : stable
72- - os : windows-latest
73- target : x86_64-pc-windows-msvc
74- rust : stable
75- runs-on : ${{ matrix.os }}
76- steps :
77- - uses : actions/checkout@v4
78-
79- - name : Install Rust ${{ matrix.rust }}
80- uses : dtolnay/rust-toolchain@master
88+ - name : Build Python wheels (linux non-x86-64)
89+ if : startsWith(matrix.build.NAME, 'linux') && matrix.build.TARGET != 'x86_64-unknown-linux-gnu'
90+ uses : PyO3/maturin-action@v1
8191 with :
82- toolchain : ${{ matrix.rust }}
83- targets : ${{ matrix.target }}
84-
85- - name : Run tests
86- run : cargo test --target ${{ matrix.target }}
92+ working-directory : pypi
93+ target : ${{ matrix.build.TARGET }}
94+ args : --release --out dist
95+ sccache : " true "
96+ manylinux : ${{ matrix.build.TARGET == 'aarch64-unknown-linux-gnu' && '2_28' || (endsWith( matrix.build.TARGET, 'musl') && 'musllinux_1_2' || 'auto') }}
8797
88- docs :
89- name : Documentation
90- needs : [build, format, clippy]
91- runs-on : ubuntu-latest
92- steps :
93- - uses : actions/checkout@v4
94-
95- - name : Install Rust stable
96- uses : dtolnay/rust-toolchain@stable
97-
98- - name : Build documentation
99- run : cargo doc --no-deps --all-features
100- env :
101- RUSTDOCFLAGS : " -D warnings"
102-
103- - name : Upload documentation
98+ - name : Build Python wheels (macos & windows)
99+ if : startsWith(matrix.build.OS, 'macos') || startsWith(matrix.build.OS, 'windows')
100+ uses : PyO3/maturin-action@v1
101+ with :
102+ working-directory : pypi
103+ target : ${{ matrix.build.TARGET }}
104+ args : --release --out dist
105+ sccache : " true"
106+
107+ - name : Upload Python wheels
104108 uses : actions/upload-artifact@v4
105109 with :
106- name : documentation
107- path : target/doc/
108- retention-days : 1
110+ name : " wheels-${{ matrix.build.TARGET }}"
111+ path : pypi/dist
112+
113+ publish-pypi :
114+ name : Publish PyPI package
115+ runs-on : ubuntu-24.04
116+ needs : publish-binaries
117+ environment : pypi_release
118+ permissions :
119+ id-token : write
120+ contents : read
121+ steps :
122+ - name : Download all wheels
123+ uses : actions/download-artifact@v4
124+ with :
125+ path : dist
126+ pattern : wheels-*
127+ merge-multiple : true
128+
129+ - name : Install uv
130+ uses : astral-sh/setup-uv@v5
131+ with :
132+ version : " 0.9.22"
133+
134+ - name : Publish to PyPI
135+ run : uv publish --trusted-publishing always dist/*
0 commit comments