From 7522fa6771f8e4b0c87527fb85049e62646141ec Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 15 Oct 2026 23:30:21 +0000 Subject: [PATCH] Add pytera riscv64 wheel build Templating-engine native-accelerator candidate distinct from the already-published minijinja/markdown-it-pyrs and the already-parked genshi/cheetah3 (ct3): pytera is a PyO3 binding to Rust's Tera template engine, a single abi3-py38 extension module (one wheel reused across every CPython 3.8+ interpreter). Mirrors upstream's own maturin-generated ci.yml linux/musllinux jobs (PyO3/maturin-action), narrowed to riscv64. Drops the free-threaded (python3.13t) leg upstream builds separately, since abi3 already can't target it and pyo3 0.23's free-threaded support is out of scope for this first port. Adds license-files: the real v0.1.2 tag's tree has no LICENSE file at all (added to the repo one commit after that tag) and its legacy `license = {text = "MIT"}` table form gets no automatic license-files discovery, so the released PyPI wheel ships no licence text on any platform. --- .github/workflows/build-pytera.yml | 115 ++++++++++++++++++ docs/packages/pytera.yaml | 5 + ...he-projects-mit-licence-in-the-wheel.patch | 58 +++++++++ 3 files changed, 178 insertions(+) create mode 100644 .github/workflows/build-pytera.yml create mode 100644 docs/packages/pytera.yaml create mode 100644 patches/pytera/0.1.2/0001-pyproject-ship-the-projects-mit-licence-in-the-wheel.patch diff --git a/.github/workflows/build-pytera.yml b/.github/workflows/build-pytera.yml new file mode 100644 index 000000000000..d4a4480fd82b --- /dev/null +++ b/.github/workflows/build-pytera.yml @@ -0,0 +1,115 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on: https://github.com/PyO3Lab/pytera/blob/v0.1.2/.github/workflows/ci.yml +name: Build pytera wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/pytera.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-pytera.yml' + - 'docs/packages/pytera.yaml' + - 'patches/pytera/**' + push: + branches: [main] + paths: + - '.github/workflows/build-pytera.yml' + - 'docs/packages/pytera.yaml' + - 'patches/pytera/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: pytera + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build pytera ${{ matrix.version }} cp38-abi3-${{ matrix.libc }}_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + libc: ["manylinux", "musllinux"] + + env: + PYTERA_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout pytera v${{ env.PYTERA_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: PyO3Lab/pytera + ref: v${{ env.PYTERA_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Patch pytera source + run: git apply python-wheels/patches/pytera/${{ env.PYTERA_VERSION }}/*.patch + + - name: Build wheel + uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + target: riscv64gc-unknown-linux-gnu + args: --release --out dist + manylinux: ${{ matrix.libc == 'musllinux' && 'musllinux_1_2' || '2_39' }} + + - name: Install Python + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + python-version: '3.12' + activate-environment: true + enable-cache: false + + - name: Test wheel + run: | + set -euo pipefail + uv pip install pytest dist/*.whl + python -c "import pytera._core as m; assert m.__file__.endswith('.so'), m.__file__" + pytest tests + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: pytera-${{ env.PYTERA_VERSION }}-cp38-abi3-${{ matrix.libc }}_riscv64 + path: dist/*.whl + if-no-files-found: error + + publish: + name: Publish pytera ${{ matrix.version }} + needs: [setup, build_wheels] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: pytera-${{ matrix.version }}-*riscv64 diff --git a/docs/packages/pytera.yaml b/docs/packages/pytera.yaml new file mode 100644 index 000000000000..b68a591edd35 --- /dev/null +++ b/docs/packages/pytera.yaml @@ -0,0 +1,5 @@ +package-name: pytera +source-code: https://github.com/PyO3Lab/pytera +license: MIT +versions: +- version: 0.1.2 diff --git a/patches/pytera/0.1.2/0001-pyproject-ship-the-projects-mit-licence-in-the-wheel.patch b/patches/pytera/0.1.2/0001-pyproject-ship-the-projects-mit-licence-in-the-wheel.patch new file mode 100644 index 000000000000..d5d1376e3266 --- /dev/null +++ b/patches/pytera/0.1.2/0001-pyproject-ship-the-projects-mit-licence-in-the-wheel.patch @@ -0,0 +1,58 @@ +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] pyproject: ship the project's MIT licence in the wheel + +v0.1.2's released tree carries no LICENSE file at all - it was added to +the repository one commit after the v0.1.2 tag - and pyproject.toml's +legacy `license = { text = "MIT" }` table form has no automatic +license-files discovery, so the real PyPI 0.1.2 wheel ships no licence +text on any platform. + +Adding the file (as it now exists on the default branch) and declaring +license-files lets the wheel build stage it into .dist-info/licenses/. + +Upstream-Status: To upstream [affects every platform's wheel, not a riscv64-only build detail] +--- + LICENSE | 21 +++++++++++++++++++++ + pyproject.toml | 1 + + 2 files changed, 22 insertions(+) + +diff --git a/LICENSE b/LICENSE +new file mode 100644 +index 0000000..85093ef +--- /dev/null ++++ b/LICENSE +@@ -0,0 +1,21 @@ ++MIT License ++ ++Copyright (c) 2025 PyO3 Lab ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy ++of this software and associated documentation files (the "Software"), to deal ++in the Software without restriction, including without limitation the rights ++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++copies of the Software, and to permit persons to whom the Software is ++furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in all ++copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++SOFTWARE. +diff --git a/pyproject.toml b/pyproject.toml +index cea429f..aff4e3d 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -4,6 +4,7 @@ version = "0.1.2" + description = "A fast, Python templating engine powered by Rust's Tera library" + readme = "README.md" + license = { text = "MIT" } ++license-files = ["LICENSE"] + authors = [ + { name = "un4gt", email = "mt3085570450@outlook.com" } + ]