Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions .github/workflows/build-protovalidate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on the `ext-linux` job of
# https://github.com/bufbuild/protovalidate-py/blob/v2.0.0/.github/workflows/release.yaml
name: Build protovalidate wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'protovalidate version to build (git tag without the leading v, e.g. 2.0.0)'
required: true
default: '2.0.0'
pull_request:
paths:
- '.github/workflows/build-protovalidate.yml'
- 'patches/protovalidate/**'

concurrency:
group: ${{ github.workflow }}-${{ inputs.version || '2.0.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 2.0.0 there.
PROTOVALIDATE_VERSION: ${{ inputs.version || '2.0.0' }}
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64

jobs:
setup:
uses: $/.github/workflows/_setup.yml

build_wheels:
needs: [setup]
name: Build protovalidate ${{ inputs.version || '2.0.0' }} ${{ matrix.tag }}-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 360
strategy:
fail-fast: false
matrix:
include:
# [tool.maturin] features already lists pyo3/abi3-py310, so one
# abi3 wheel serves every GIL-ful interpreter; pyo3 disables abi3
# under Py_GIL_DISABLED, giving the free-threaded build its own
# wheel. Matches upstream's own `-i 3.10 -i 3.14t` maturin-action
# invocation.
- tag: cp310-abi3
build: >-
cp312-manylinux_riscv64 cp313-manylinux_riscv64
cp314-manylinux_riscv64
- tag: cp314t
build: cp314t-manylinux_riscv64

steps:
- name: Checkout protovalidate-py v${{ env.PROTOVALIDATE_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: bufbuild/protovalidate-py
ref: v${{ env.PROTOVALIDATE_VERSION }}
submodules: recursive
fetch-depth: 1
persist-credentials: false

- name: Checkout python-wheels
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: python-wheels
fetch-depth: 1
persist-credentials: false

- name: Patch source
run: git apply python-wheels/patches/protovalidate/${{ env.PROTOVALIDATE_VERSION }}/*.patch

- name: Build wheels
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
env:
CIBW_BUILD: ${{ matrix.build }}
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
# protovalidate ships no [tool.cibuildwheel], so the Rust toolchain
# its maturin backend needs is installed in-container here. `go` is
# also needed: test/conformance/test_conformance.py shells out to
# `go run github.com/bufbuild/protovalidate/tools/protovalidate-conformance`,
# which isn't present on the manylinux image otherwise.
CIBW_BEFORE_ALL_LINUX: >-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y &&
dnf -y install golang
CIBW_ENVIRONMENT_LINUX: PATH="$PATH:$HOME/.cargo/bin"
CIBW_TEST_REQUIRES: >-
pytest==9.1.1 pytest-benchmark==5.2.3 pydantic==2.13.4
protobuf>=6.31.0
# The `protovalidate` python package (protobuf-py, at repo root)
# would otherwise shadow the installed wheel's compiled extension.
CIBW_TEST_SOURCES: test pyproject.toml
# protobuf (Google's package, used for legacy conformance coverage)
# has no riscv64 wheel on public PyPI yet.
CIBW_TEST_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
CIBW_TEST_COMMAND: >-
python -c "import protovalidate._protovalidate as m; assert m.__file__.endswith('.so'), m.__file__" &&
python -m pytest test -v

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: protovalidate-${{ env.PROTOVALIDATE_VERSION }}-${{ matrix.tag }}-manylinux_riscv64
path: wheelhouse/*.whl
if-no-files-found: error

publish:
name: Publish protovalidate ${{ inputs.version || '2.0.0' }}
needs: [setup, build_wheels]
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
with:
artifact-pattern: protovalidate-${{ inputs.version || '2.0.0' }}-*-manylinux_riscv64
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 27 Aug 2026 00:00:00 +0000
Subject: [PATCH] pyproject: list vendored C++ licence files in
[project].license-files

protovalidate._protovalidate statically links six vendored C++ projects
(abseil-cpp, antlr4, cel-cpp, protobuf + its bundled utf8_range, re2,
protovalidate-cc) compiled from crates/protovalidate-rs/build.rs, but
[project].license-files only names the package's own root LICENSE.
maturin has no default glob for a PEP 639 project (gotcha 105/146 in
this repo's porting skill), so every published wheel - on every
platform, not just riscv64 - ships none of the six licence texts the
compiled binary actually requires. All six are permissive (Apache-2.0
x3, BSD-3-Clause x3 for protobuf/antlr4/re2, plus utf8_range's MIT),
so this only adds licence-files entries; no GPL text is involved.

Upstream-Status: To upstream [not submitted: this session's policy is to not open issues/PRs on third-party repos]

Signed-off-by: Ludovic Henry <git@ludovic.dev>
---
pyproject.toml | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/pyproject.toml b/pyproject.toml
index e654ad9..25070f3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,16 @@ description = "Protocol Buffer Validation for Python"
readme = "README.md"
requires-python = ">=3.10"
license = "Apache-2.0"
-license-files = ["LICENSE"]
+license-files = [
+ "LICENSE",
+ "crates/protovalidate-rs/third_party/abseil-cpp/LICENSE",
+ "crates/protovalidate-rs/third_party/antlr4/LICENSE.txt",
+ "crates/protovalidate-rs/third_party/cel-cpp/LICENSE",
+ "crates/protovalidate-rs/third_party/protobuf/LICENSE",
+ "crates/protovalidate-rs/third_party/protobuf/third_party/utf8_range/LICENSE",
+ "crates/protovalidate-rs/third_party/protovalidate-cc/LICENSE",
+ "crates/protovalidate-rs/third_party/re2/LICENSE",
+]
keywords = ["protobuf", "protocol buffer", "validate"]
classifiers = [
"Operating System :: OS Independent",
--
2.51.0