Skip to content

Commit 3d2213a

Browse files
luhenryclaude
andcommitted
fastuuid: build riscv64 wheels
Add build-fastuuid.yml to build fastuuid 0.14.0 wheels for riscv64 and publish them to pypi.riseproject.dev. fastuuid is a PyO3/Rust extension built with maturin, with no C native dependencies (pure-Rust: pyo3, uuid, rand). We build our own sdist from an upstream checkout on ubuntu-latest, then build the riscv64 bdist from that sdist with cibuildwheel on the manylinux_2_39_riscv64 image. fastuuid gitignores Cargo.lock, so a fresh dependency resolve floats the `uuid` crate to the newest 1.x. uuid >=1.21 deprecated the `uuid::Context` alias (renamed to `ContextV1`), and the crate compiles under `#![deny(warnings)]`, so that deprecation is a hard compile error. We pin uuid to 1.18.1 (the version upstream released 0.14.0 against) before maturin captures Cargo.lock into the sdist, which restores a clean build. The sdist also carries the `.cargo/config.toml` that sets `--cfg uuid_unstable` (required by the uuid crate's v1/v7 features). The Rust toolchain is installed in-container with rustup (CIBW_BEFORE_ALL_LINUX) and put on PATH (CIBW_ENVIRONMENT_LINUX), since fastuuid ships no [tool.cibuildwheel] config of its own. Each wheel is tested the way upstream does, running its pytest suite (tests/test_uuid.py + test_benchmarks.py) inside the container against the matching interpreter. All test deps (pytest, hypothesis, pytest-benchmark, uuid7) are pure-Python wheels on public PyPI. Matrix cp312/cp313/cp314/cp314t: fastuuid is not abi3 (upstream ships per-interpreter wheels), so every Python version needs its own build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 32243b7 commit 3d2213a

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# This workflow is based on: https://github.com/fastuuid/fastuuid/blob/0.14.0/.github/workflows/ci-cd.yml
5+
name: Build fastuuid wheels (riscv64)
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'fastuuid version to build (git tag without leading v, e.g. 0.14.0)'
12+
required: true
13+
default: '0.14.0'
14+
pull_request:
15+
paths:
16+
- '.github/workflows/build-fastuuid.yml'
17+
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ inputs.version || '0.14.0' }}-${{ github.head_ref || github.run_id }}
20+
cancel-in-progress: true
21+
22+
permissions:
23+
contents: read # to fetch code (actions/checkout)
24+
25+
env:
26+
# `inputs.version` is empty on pull_request events; default to 0.14.0 there.
27+
FASTUUID_VERSION: ${{ inputs.version || '0.14.0' }}
28+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
29+
# fastuuid gitignores Cargo.lock, so a fresh resolve floats the `uuid` crate to
30+
# the newest 1.x. uuid >=1.21 deprecated the `uuid::Context` alias (renamed to
31+
# `ContextV1`), and the crate builds under `#![deny(warnings)]`, so that
32+
# deprecation becomes a hard compile error. Pin uuid to the version upstream
33+
# released 0.14.0 against (what their release sdist's Cargo.lock ships), which
34+
# reproduces a clean build. Bump this in lockstep with FASTUUID_VERSION.
35+
UUID_CRATE_VERSION: '1.18.1'
36+
37+
jobs:
38+
# Build the sdist ourselves from an upstream checkout (never consume the
39+
# prebuilt PyPI sdist). maturin bundles the pinned Cargo.lock + the `.cargo/
40+
# config.toml` (which sets `--cfg uuid_unstable`, required by the uuid crate's
41+
# v1/v7 features) + the tests/ suite into the sdist, so the riscv64 bdist
42+
# builds reproducibly from it. The sdist is arch-independent, so build it once
43+
# on ubuntu-latest (see gotcha 4).
44+
python_sdist:
45+
runs-on: ubuntu-latest
46+
outputs:
47+
sdist_artifact_name: ${{ steps.build_sdist.outputs.sdist_artifact_name }}
48+
package_version: ${{ steps.build_sdist.outputs.package_version }}
49+
steps:
50+
- name: Checkout fastuuid ${{ env.FASTUUID_VERSION }}
51+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
52+
with:
53+
repository: fastuuid/fastuuid
54+
ref: ${{ env.FASTUUID_VERSION }}
55+
persist-credentials: false
56+
57+
- name: Install Python
58+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
59+
with:
60+
python-version: '3.12'
61+
activate-environment: true
62+
enable-cache: false
63+
64+
- name: Pin uuid crate and build sdist
65+
id: build_sdist
66+
run: |
67+
set -euo pipefail
68+
rm -rf dist
69+
70+
# Lock uuid to the release version before maturin captures Cargo.lock
71+
# into the sdist (see UUID_CRATE_VERSION rationale above).
72+
cargo generate-lockfile
73+
cargo update -p uuid --precise "${UUID_CRATE_VERSION}"
74+
75+
uv pip install 'maturin>=1.0,<2.0' build
76+
python -m build --sdist --outdir dist
77+
78+
sdist_name="$(ls dist)"
79+
{
80+
echo "sdist_artifact_name=${sdist_name}"
81+
echo "package_version=$(echo "${sdist_name}" | sed -En 's/fastuuid-(.+)\.tar\.gz/\1/p')"
82+
} >> "$GITHUB_OUTPUT"
83+
84+
- name: Upload sdist artifact
85+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
86+
with:
87+
name: ${{ steps.build_sdist.outputs.sdist_artifact_name }}
88+
path: dist/${{ steps.build_sdist.outputs.sdist_artifact_name }}
89+
if-no-files-found: error
90+
91+
build_wheels:
92+
needs: [python_sdist]
93+
name: Build fastuuid ${{ inputs.version || '0.14.0' }} ${{ matrix.python }}-manylinux_riscv64
94+
runs-on: ubuntu-24.04-riscv
95+
timeout-minutes: 60
96+
strategy:
97+
fail-fast: false
98+
matrix:
99+
# fastuuid is a PyO3 extension built per-interpreter (not abi3 - upstream
100+
# ships cp3x-cp3x wheels), so every Python version needs its own build.
101+
# Repo-standard riscv64 target set.
102+
python: ["cp312", "cp313", "cp314", "cp314t"]
103+
104+
steps:
105+
- name: Fetch sdist artifact
106+
id: fetch_sdist
107+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
108+
with:
109+
name: ${{ needs.python_sdist.outputs.sdist_artifact_name }}
110+
111+
- name: Install uv
112+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
113+
with:
114+
python-version: '3.12'
115+
activate-environment: true
116+
enable-cache: false
117+
118+
- name: Build and test wheel
119+
env:
120+
CIBW_ARCHS: riscv64
121+
# Only manylinux: rustup.rs ships no riscv64 musl host toolchain, so
122+
# musllinux can't build (same reason build-tiktoken.yml skips it).
123+
CIBW_BUILD: ${{ matrix.python }}-manylinux_riscv64
124+
CIBW_BUILD_VERBOSITY: '1'
125+
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
126+
# fastuuid ships no [tool.cibuildwheel], so the Rust toolchain its
127+
# maturin backend needs is installed in-container here and put on PATH
128+
# for the build (build-tiktoken.yml carries the equivalent in its own
129+
# pyproject before-all/environment).
130+
CIBW_BEFORE_ALL_LINUX: >-
131+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
132+
CIBW_ENVIRONMENT_LINUX: 'PATH="$PATH:$HOME/.cargo/bin"'
133+
# Test each wheel the way upstream does - run its pytest suite (tox's
134+
# black/isort steps are dev-only lint, not wheel tests, so skipped).
135+
# All test deps are pure-Python wheels on public PyPI, so no registry
136+
# plumbing is needed; uuid7 provides the `uuid_extensions` module the
137+
# benchmarks import. HYPOTHESIS_PROFILE=dev caps property-test examples
138+
# (the "ci" default is 2000) and --benchmark-disable runs each benchmark
139+
# once for coverage (incl. the GIL-releasing bulk/threaded paths)
140+
# without spending CI time on perf timing.
141+
CIBW_TEST_REQUIRES: pytest hypothesis pytest-benchmark uuid7
142+
CIBW_TEST_COMMAND: HYPOTHESIS_PROFILE=dev pytest -q {project}/tests --benchmark-disable
143+
run: |
144+
set -euo pipefail
145+
mkdir fastuuid
146+
tar zxf "${{ steps.fetch_sdist.outputs.download-path }}/${{ needs.python_sdist.outputs.sdist_artifact_name }}" \
147+
--strip-components=1 -C fastuuid
148+
uv pip install --upgrade cibuildwheel
149+
python -m cibuildwheel --output-dir wheelhouse ./fastuuid
150+
151+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
152+
with:
153+
name: fastuuid-${{ env.FASTUUID_VERSION }}-${{ matrix.python }}-manylinux_riscv64
154+
path: ./wheelhouse/*.whl
155+
if-no-files-found: error
156+
157+
publish:
158+
name: Publish fastuuid ${{ inputs.version || '0.14.0' }} to GitLab
159+
needs: [build_wheels]
160+
runs-on: ubuntu-latest
161+
permissions:
162+
contents: write
163+
pull-requests: write
164+
165+
steps:
166+
- name: Publish wheels and open docs PR
167+
uses: riseproject-dev/python-wheels/actions/publish-wheels@main
168+
with:
169+
artifact-pattern: fastuuid-${{ env.FASTUUID_VERSION }}-*-manylinux_riscv64
170+
gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }}
171+
gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }}
172+
gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }}
173+
gh-token: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)