Skip to content

Commit 6c4cd65

Browse files
committed
ci: build native Rust extension in workflows and make it the default backend
1 parent 852c632 commit 6c4cd65

25 files changed

Lines changed: 150 additions & 635 deletions

.github/workflows/pr.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,31 @@ jobs:
3737
with:
3838
python-version: "3.11"
3939

40+
- name: Install Rust
41+
uses: dtolnay/rust-toolchain@stable
42+
4043
- name: Install uv
4144
uses: astral-sh/setup-uv@v3
4245

4346
- name: Sync dependencies (locked)
4447
run: |
4548
uv sync --locked --all-groups
4649
50+
- name: Build & install native extension (maturin develop)
51+
uses: PyO3/maturin-action@v1
52+
with:
53+
command: develop
54+
args: --release
55+
manylinux: "2_28"
56+
57+
- name: Sanity check (import Rust extension)
58+
run: |
59+
python -c "import typeid; import typeid._base32; print('Rust extension OK')"
60+
4761
- name: Run tests
4862
run: |
4963
make test
50-
64+
5165
- name: Run doc tests
5266
run: |
5367
make test-docs

.github/workflows/publish.yml

Lines changed: 85 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,83 @@ permissions:
88
contents: write
99
id-token: write
1010

11+
env:
12+
PROJECT_NAME: typeid-python
13+
1114
jobs:
1215
test:
13-
uses: ./.github/workflows/test.yml
16+
runs-on: ubuntu-latest
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 9
27+
submodules: false
28+
29+
- name: Set up Python ${{ matrix.python-version }}
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: ${{ matrix.python-version }}
33+
34+
- name: Install uv
35+
uses: astral-sh/setup-uv@v3
36+
37+
- name: Sync dependencies (locked)
38+
run: |
39+
uv sync --locked --all-groups
40+
41+
- name: Run tests
42+
run: |
43+
make test
44+
45+
- name: Run linters
46+
run: |
47+
make check-linting
48+
49+
test-native:
50+
name: Build + import native extension (${{ matrix.os }}, py${{ matrix.python-version }})
51+
runs-on: ${{ matrix.os }}
52+
needs:
53+
- test
54+
strategy:
55+
fail-fast: false
56+
matrix:
57+
os: [ubuntu-latest, macos-latest, windows-latest]
58+
python-version: ["3.11"]
59+
60+
steps:
61+
- name: Checkout
62+
uses: actions/checkout@v4
63+
64+
- name: Set up Python ${{ matrix.python-version }}
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: ${{ matrix.python-version }}
68+
69+
- name: Install Rust
70+
uses: dtolnay/rust-toolchain@stable
71+
72+
# Build & install the package in-place with the extension
73+
- name: Build & install (maturin develop)
74+
uses: PyO3/maturin-action@v1
75+
with:
76+
command: develop
77+
args: --release
78+
79+
- name: Sanity check (import extension)
80+
run: |
81+
python -c "import typeid; import typeid._base32; print('native ext OK')"
82+
1483
1584
build-wheels:
16-
name: Build wheels (${{ matrix.os }})
85+
name: Build wheels (${{ matrix.os }}, py${{ matrix.python-version }})
1786
runs-on: ${{ matrix.os }}
18-
needs: test
87+
needs: test-native
1988
strategy:
2089
fail-fast: false
2190
matrix:
@@ -36,10 +105,8 @@ jobs:
36105
- name: Install Rust
37106
uses: dtolnay/rust-toolchain@stable
38107

39-
- name: Install uv
40-
uses: astral-sh/setup-uv@v3
41-
42-
- name: Build wheels (Rust-enabled)
108+
# Build typeid-python wheel (includes rust extension)
109+
- name: Build wheels (maturin)
43110
uses: PyO3/maturin-action@v1
44111
with:
45112
command: build
@@ -51,7 +118,7 @@ jobs:
51118
uses: actions/upload-artifact@v4
52119
with:
53120
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
54-
path: rust-base32/dist/*.whl
121+
path: dist/*.whl
55122

56123
build-sdist:
57124
runs-on: ubuntu-latest
@@ -67,49 +134,25 @@ jobs:
67134
with:
68135
python-version: "3.11"
69136

70-
- name: Install uv
71-
uses: astral-sh/setup-uv@v3
72-
73-
- name: Sync deps (including build tools)
74-
run: |
75-
uv sync --all-extras --dev
76-
77-
- name: Build sdist
78-
run: |
79-
make build-sdist
137+
- name: Install Rust
138+
uses: dtolnay/rust-toolchain@stable
80139

81-
- name: Upload sdist
82-
uses: actions/upload-artifact@v4
83-
with:
84-
name: sdist
85-
path: dist/*.tar.gz
86-
87-
build-rust-sdist:
88-
runs-on: ubuntu-latest
89-
needs: test
90-
steps:
91-
- uses: actions/checkout@v4
92-
- uses: actions/setup-python@v5
93-
with:
94-
python-version: "3.11"
95-
- uses: dtolnay/rust-toolchain@stable
96-
- name: Build rust sdist
140+
# Build typeid-python sdist (maturin)
141+
- name: Build sdist (maturin)
97142
uses: PyO3/maturin-action@v1
98143
with:
99144
command: sdist
100145
args: --out dist
101-
working-directory: rust-base32
102146

103-
- uses: actions/upload-artifact@v4
147+
- name: Upload sdist
148+
uses: actions/upload-artifact@v4
104149
with:
105-
name: rust-sdist
106-
path: rust-base32/dist/*.tar.gz
150+
name: sdist
151+
path: dist/*.tar.gz
107152

108153
publish-package:
109154
runs-on: ubuntu-latest
110-
needs:
111-
- build-sdist
112-
- build-rust-sdist
155+
needs: build-sdist
113156
permissions:
114157
contents: read
115158
id-token: write
@@ -149,4 +192,4 @@ jobs:
149192
uv sync --locked --all-groups
150193
151194
- name: Deploy to Pages
152-
run: uv run mkdocs gh-deploy --force
195+
run: uv run mkdocs gh-deploy --force

.github/workflows/test.yml

Lines changed: 0 additions & 94 deletions
This file was deleted.

README.md

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,17 @@ See [`Docs: Performance`](https://akhundmurad.github.io/typeid-python/performanc
5656

5757
## Installation
5858

59-
### Core (pure Python)
59+
### Core
6060

6161
```console
6262
$ pip install typeid-python
6363
```
6464

65-
### With Rust acceleration (recommended)
66-
67-
```console
68-
$ pip install typeid-python[rust]
69-
```
70-
71-
This enables:
65+
Included:
7266

7367
* Rust base32 encode/decode
7468
* `uuid-utils` for fast UUIDv7 generation
7569

76-
If Rust is unavailable, TypeID automatically falls back to the pure-Python implementation.
77-
7870
### Other optional extras
7971

8072
```console
@@ -111,7 +103,7 @@ assert tid.prefix == "user"
111103

112104
```python
113105
from typeid import TypeID
114-
from uuid6 import uuid7
106+
from uuid_utils import uuid7
115107

116108
u = uuid7()
117109
tid = TypeID.from_uuid(prefix="user", suffix=u)

bench/README.md

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ Benchmarks were run with:
1717
- OS: macOS / Linux
1818
- CPU: Apple Silicon / x86_64
1919
- Tooling: `pytest-benchmark`
20-
- UUID backends:
21-
- `uuid-utils` (Rust, optional)
22-
- `uuid6` (Python, legacy comparison)
20+
- UUID backend: `uuid-utils` (Rust)
2321

2422
Exact environment details are embedded in each JSON result file.
2523

@@ -64,7 +62,7 @@ These files are the **source of truth**.
6462

6563
## Comparison summary (mean time, µs)
6664

67-
| Benchmark | 0001 – Before Rust | 0002 – Rust + optimizations | Speedup (0004 vs 0001) |
65+
| Benchmark | 0001 – Before Rust | 0002 – Rust + optimizations | Speedup (0002 vs 0001) |
6866
| ------------------- | -----------------: | --------------------------: | ---------------------: |
6967
| **TypeID generate** | 3.467 µs | **0.701 µs** | **4.94× faster** |
7068
| **TypeID parse** | 2.076 µs | **1.296 µs** | **1.60× faster** |
@@ -88,24 +86,6 @@ These files are the **source of truth**.
8886

8987
Result: parse and workflow became faster than the original Python baseline.
9088

91-
## UUID backend comparison (context)
92-
93-
These numbers represent the approximate lower bound:
94-
95-
| Operation | uuid-utils | uuid6 |
96-
| --------- | ---------: | -------: |
97-
| Generate | ~0.08 µs | ~1.51 µs |
98-
| Parse | ~0.12 µs | ~0.53 µs |
99-
100-
TypeID adds overhead for:
101-
102-
* base32 encoding
103-
* prefix handling
104-
* validation
105-
* safety guarantees
106-
107-
This overhead is now reduced to approximately **1–2 µs**, depending on the operation.
108-
10989
## Cold path vs warm path
11090

11191
All benchmarks measure cold-path performance: each iteration operates on a new identifier.

0 commit comments

Comments
 (0)