Skip to content

Build fastuuid wheels (riscv64) #7

Build fastuuid wheels (riscv64)

Build fastuuid wheels (riscv64) #7

# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on: https://github.com/fastuuid/fastuuid/blob/0.14.0/.github/workflows/ci-cd.yml
name: Build fastuuid wheels (riscv64)
on:
workflow_dispatch:
inputs:
version:
description: 'fastuuid version to build (git tag without leading v, e.g. 0.14.0)'
required: true
default: '0.14.0'
pull_request:
paths:
- '.github/workflows/build-fastuuid.yml'
concurrency:
group: ${{ github.workflow }}-${{ inputs.version || '0.14.0' }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
env:
# `inputs.version` is empty on pull_request events; default to 0.14.0 there.
FASTUUID_VERSION: ${{ inputs.version || '0.14.0' }}
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
# fastuuid gitignores Cargo.lock, so a fresh resolve floats the `uuid` crate to
# the newest 1.x. uuid >=1.21 deprecated the `uuid::Context` alias (renamed to
# `ContextV1`), and the crate builds under `#![deny(warnings)]`, so that
# deprecation becomes a hard compile error. Pin uuid to the version upstream
# released 0.14.0 against (what their release sdist's Cargo.lock ships), which
# reproduces a clean build. Bump this in lockstep with FASTUUID_VERSION.
UUID_CRATE_VERSION: '1.18.1'
jobs:
# Build the sdist ourselves from an upstream checkout (never consume the
# prebuilt PyPI sdist). maturin bundles the pinned Cargo.lock + the `.cargo/
# config.toml` (which sets `--cfg uuid_unstable`, required by the uuid crate's
# v1/v7 features) + the tests/ suite into the sdist, so the riscv64 bdist
# builds reproducibly from it. The sdist is arch-independent, so build it once
# on ubuntu-latest (see gotcha 4).
python_sdist:
runs-on: ubuntu-latest
outputs:
sdist_artifact_name: ${{ steps.build_sdist.outputs.sdist_artifact_name }}
package_version: ${{ steps.build_sdist.outputs.package_version }}
steps:
- name: Checkout fastuuid ${{ env.FASTUUID_VERSION }}
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: fastuuid/fastuuid
ref: ${{ env.FASTUUID_VERSION }}
persist-credentials: false
- name: Install Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
python-version: '3.12'
activate-environment: true
enable-cache: false
- name: Pin uuid crate and build sdist
id: build_sdist
run: |
set -euo pipefail
rm -rf dist
# Lock uuid to the release version before maturin captures Cargo.lock
# into the sdist (see UUID_CRATE_VERSION rationale above).
cargo generate-lockfile
cargo update -p uuid --precise "${UUID_CRATE_VERSION}"
uv pip install 'maturin>=1.0,<2.0' build
python -m build --sdist --outdir dist
sdist_name="$(ls dist)"
{
echo "sdist_artifact_name=${sdist_name}"
echo "package_version=$(echo "${sdist_name}" | sed -En 's/fastuuid-(.+)\.tar\.gz/\1/p')"
} >> "$GITHUB_OUTPUT"
- name: Upload sdist artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ steps.build_sdist.outputs.sdist_artifact_name }}
path: dist/${{ steps.build_sdist.outputs.sdist_artifact_name }}
if-no-files-found: error
build_wheels:
needs: [python_sdist]
name: Build fastuuid ${{ inputs.version || '0.14.0' }} ${{ matrix.python }}-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
# fastuuid is a PyO3 extension built per-interpreter (not abi3 - upstream
# ships cp3x-cp3x wheels), so every Python version needs its own build.
# Repo-standard riscv64 target set. Upstream doesn't build for 3.14t yet,
# so skip it for now.
python: ["cp312", "cp313", "cp314"]
steps:
- name: Fetch sdist artifact
id: fetch_sdist
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ needs.python_sdist.outputs.sdist_artifact_name }}
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
python-version: '3.12'
activate-environment: true
enable-cache: false
- name: Build and test wheel
env:
CIBW_ARCHS: riscv64
# Only manylinux: rustup.rs ships no riscv64 musl host toolchain, so
# musllinux can't build (same reason build-tiktoken.yml skips it).
CIBW_BUILD: ${{ matrix.python }}-manylinux_riscv64
CIBW_BUILD_VERBOSITY: '1'
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
# fastuuid ships no [tool.cibuildwheel], so the Rust toolchain its
# maturin backend needs is installed in-container here and put on PATH
# for the build (build-tiktoken.yml carries the equivalent in its own
# pyproject before-all/environment).
CIBW_BEFORE_ALL_LINUX: >-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
CIBW_ENVIRONMENT_LINUX: 'PATH="$PATH:$HOME/.cargo/bin"'
# Test each wheel the way upstream does - run its pytest suite (tox's
# black/isort steps are dev-only lint, not wheel tests, so skipped).
# All test deps are pure-Python wheels on public PyPI, so no registry
# plumbing is needed; uuid7 provides the `uuid_extensions` module the
# benchmarks import. HYPOTHESIS_PROFILE=dev caps property-test examples
# (the "ci" default is 2000) and --benchmark-disable runs each benchmark
# once for coverage (incl. the GIL-releasing bulk/threaded paths)
# without spending CI time on perf timing. Tests live inside the sdist
# dir we pass to cibuildwheel, so reference them via {package} (=
# /project/fastuuid), NOT {project} (= the invocation dir /project) -
# see gotcha 5.
CIBW_TEST_REQUIRES: pytest hypothesis pytest-benchmark uuid7
CIBW_TEST_COMMAND: HYPOTHESIS_PROFILE=dev pytest -q {package}/tests --benchmark-disable
run: |
set -euo pipefail
mkdir fastuuid
tar zxf "${{ steps.fetch_sdist.outputs.download-path }}/${{ needs.python_sdist.outputs.sdist_artifact_name }}" \
--strip-components=1 -C fastuuid
uv pip install --upgrade cibuildwheel
python -m cibuildwheel --output-dir wheelhouse ./fastuuid
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: fastuuid-${{ env.FASTUUID_VERSION }}-${{ matrix.python }}-manylinux_riscv64
path: ./wheelhouse/*.whl
if-no-files-found: error
publish:
name: Publish fastuuid ${{ inputs.version || '0.14.0' }} to GitLab
needs: [build_wheels]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Publish wheels and open docs PR
uses: riseproject-dev/python-wheels/actions/publish-wheels@main
with:
artifact-pattern: fastuuid-${{ env.FASTUUID_VERSION }}-*-manylinux_riscv64
gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }}
gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }}
gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }}
gh-token: ${{ secrets.GITHUB_TOKEN }}