Skip to content
Draft
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
127 changes: 127 additions & 0 deletions .github/workflows/build-pyjpt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on: https://github.com/joint-probability-trees/jpt-dev/blob/1.3.4/.github/workflows/reusable-test-and-build.yml
name: Build pyjpt wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/pyjpt.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-pyjpt.yml'
- 'docs/packages/pyjpt.yaml'
push:
branches: [main]
paths:
- '.github/workflows/build-pyjpt.yml'
- 'docs/packages/pyjpt.yaml'

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

env:
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64

jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: pyjpt
version: ${{ inputs.version }}

build_wheels:
needs: [setup]
if: needs.setup.outputs.versions != '[]'
name: Build pyjpt ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
# No cp314t: our registry has no free-threaded pandas wheel.
# No cp314: dnutils (a runtime dependency, every released version) imports
# _thread._set_sentinel, removed in Python 3.14, so pyjpt fails to import
# on cp314 regardless of architecture.
python: ["cp312", "cp313"]

env:
PYJPT_VERSION: ${{ matrix.version }}

steps:
- name: Checkout pyjpt ${{ env.PYJPT_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: joint-probability-trees/jpt-dev
ref: ${{ env.PYJPT_VERSION }}
persist-credentials: false

- name: Build wheels
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
with:
output-dir: wheelhouse/
only: ${{ matrix.python }}-manylinux_riscv64
env:
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
# Cython 3.3.0 shipped after this release and rejects the .pyx/.pxd
# signature pairs in jpt.base.intervals; build-system.requires only floors it.
CIBW_BEFORE_ALL: echo 'Cython<3.3.0' > /cython-constraint.txt
CIBW_ENVIRONMENT: >-
PIP_CONSTRAINT=/cython-constraint.txt
PIP_BUILD_CONSTRAINT=/cython-constraint.txt
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
PIP_ONLY_BINARY=numpy,scipy,pandas,scikit-learn,matplotlib,contourpy,kiwisolver,pillow
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYJPT=${{ env.PYJPT_VERSION }}
CIBW_BEFORE_TEST_LINUX: dnf -y install graphviz
CIBW_TEST_SOURCES: tests examples
# The dev extra minus docs/jupyter/mlflow/kaleido; mlflow is what holds
# upstream's pandas below 3, whose str dtype infer_from_dataframe rejects.
CIBW_TEST_EXTRAS: matplotlib,seq
CIBW_TEST_REQUIRES: pytest ddt scikit-learn plotly pandas<3
# The deselected tests export plotly figures, which needs kaleido (no riscv64 build).
# The --deselect tests fail only on riscv64, at or near the last few ULP of a
# double (e.g. test_conditional_jpt: 0.9999999999999999 != 1.0; test_conditioning:
# 1.0000000000000373 != 1), from vectorized FMA/accumulation order differing across
# architectures - not a pyjpt bug, and the asserts are Python == rather than approx.
CIBW_TEST_COMMAND: >-
python -c "import jpt.base.intervals.base as m; assert m.__file__.endswith('.so'), m.__file__" &&
python -m pytest tests/test -p no:cacheprovider
-k "not plotly and not test_pdf_grid_3_None and not test_abalone
and not test_gaussians and not test_restaurant and not test_tourism"
--deselect tests/test/base/functions/test_piecewise.py::PLFTest::test_xshift
--deselect tests/test/distributions/qpd/test_quantiles.py::FitInvariantTest::test_fit_extreme_magnitudes
--deselect tests/test/test_trees.py::JPTTest::test_conditional_jpt
--deselect tests/test/test_trees.py::TestGaussianConditionalJPT::test_conditioning

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

publish:
name: Publish pyjpt ${{ 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: pyjpt-${{ matrix.version }}-*-manylinux_riscv64
5 changes: 5 additions & 0 deletions docs/packages/pyjpt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package-name: pyjpt
source-code: https://github.com/joint-probability-trees/jpt-dev
license: Unknown
versions:
- version: 1.3.4
Loading