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
143 changes: 143 additions & 0 deletions .github/workflows/build-scipp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# Mirrors the Linux leg of upstream's .github/workflows/wheel.yml (called from
# pr_and_main.yml/release.yml): a scikit-build-core/CMake/pybind11 build, with
# lib/cmake/scipp-cpm.cmake fetching llnl/units, Boost headers, Eigen3, GoogleTest and
# oneTBB at configure time. GoogleTest is test-only and never installed into the wheel;
# units/Boost/Eigen3 are statically compiled in, and oneTBB's libtbb.so ships inside the
# wheel (scipp/lib64/libtbb.so). musllinux is skipped upstream too (`skip = ["*musllinux*"]`
# in pyproject.toml).
name: Build scipp wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/scipp.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-scipp.yml'
- 'docs/packages/scipp.yaml'
push:
branches: [main]
paths:
- '.github/workflows/build-scipp.yml'
- 'docs/packages/scipp.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: scipp
version: ${{ inputs.version }}

build_wheels:
needs: [setup]
if: needs.setup.outputs.versions != '[]'
name: Build scipp ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
python: ["cp311", "cp312", "cp313", "cp314", "cp314t"]

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

steps:
- name: Checkout scipp/scipp v${{ env.SCIPP_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: scipp/scipp
ref: ${{ env.SCIPP_VERSION }}
fetch-depth: 0 # setuptools_scm needs history to determine the version
persist-credentials: false

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

- name: Patch scipp source
run: git apply python-wheels/patches/scipp/${{ env.SCIPP_VERSION }}/00*.patch

# pyproject.toml's license-files is an explicit ["LICENSE"] list (patched to also
# match LICENSE.*), so scikit-build-core's default licence glob never runs. The CPM
# dependencies ship no licence in upstream's own wheel; stage the ones actually
# compiled or linked into it at the root (GoogleTest is test-only).
- name: Stage vendored dependency licences
run: |
set -euxo pipefail
curl -fsSL --retry 5 "https://raw.githubusercontent.com/llnl/units/v0.13.1/LICENSE" -o LICENSE.units
curl -fsSL --retry 5 "https://raw.githubusercontent.com/boostorg/boost/boost-1.90.0/LICENSE_1_0.txt" -o LICENSE.boost
curl -fsSL --retry 5 "https://gitlab.com/libeigen/eigen/-/raw/3.4.0/COPYING.MPL2" -o LICENSE.eigen
curl -fsSL --retry 5 "https://raw.githubusercontent.com/uxlfoundation/oneTBB/v2023.0.0/LICENSE.txt" -o LICENSE.tbb

- 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 }}
# pip resolves cmake>=3.28 (our registry's newest is 4.0.3); CPM-fetched
# dependencies' own cmake_minimum_required predates CMake 4's floor.
CIBW_ENVIRONMENT: >-
CMAKE_POLICY_VERSION_MINIMUM=3.5
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
CIBW_TEST_EXTRAS: test
CIBW_TEST_REQUIRES: scipy graphviz pooch hypothesis
CIBW_TEST_COMMAND: >-
python -c "import importlib.metadata as m; f = {p.name for p in m.files('scipp') if '.dist-info/licenses/' in str(p)}; assert f == {'LICENSE', 'LICENSE.units', 'LICENSE.boost', 'LICENSE.eigen', 'LICENSE.tbb'}, f"
&& pytest --ignore {project}/tests/plotting --ignore {project}/tests/hypothesis/ --ignore {project}/tests/experimental/ {project}/tests
# numpy/scipy have no riscv64 wheel on public PyPI; keep pip on our registry's copies.
CIBW_TEST_ENVIRONMENT: PIP_ONLY_BINARY=numpy,scipy

- name: Check wheel contents
run: |
python3 - wheelhouse/*.whl <<'EOF'
import sys, zipfile
path = sys.argv[1]
names = zipfile.ZipFile(path).namelist()
exts = [n for n in names if n.endswith(".so")]
assert exts, "no compiled extension in wheel"
EOF

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

publish:
name: Publish scipp ${{ 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: scipp-${{ matrix.version }}-*-manylinux_riscv64
5 changes: 5 additions & 0 deletions docs/packages/scipp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package-name: scipp
source-code: https://github.com/scipp/scipp
license: 'BSD-3-Clause, Third Party: Apache-2.0 (oneTBB), BSL-1.0 (Boost), MPL-2.0 (Eigen3), BSD-3-Clause (units)'
versions:
- version: 26.8.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Tue, 13 Oct 2026 00:00:00 +0200
Subject: [PATCH] Widen license-files to cover vendored CPM dependencies

pyproject.toml declares the PEP 639 license-files = ["LICENSE"] as an
explicit list, so scikit-build-core's default LICEN[CS]E*/COPYING*/
NOTICE*/AUTHORS* glob never runs and only that one path is ever
collected. The wheel statically links several dependencies that
lib/cmake/scipp-cpm.cmake fetches and builds from source for every
wheel build (llnl/units, Boost headers, Eigen3) and dynamically links
oneTBB's built libtbb.so into the wheel itself (visible in the
published wheel as scipp/lib64/libtbb.so). None of those licences ship
in any published wheel; verified against the real scipp-26.8.0 wheels
on PyPI, which have the same gap.

Widening the explicit list to also match LICENSE.* lets the build add
LICENSE.units/LICENSE.boost/LICENSE.eigen/LICENSE.tbb at the project
root with no other packaging change (GoogleTest, the only other CPM
dependency, is test-only and never installed into the wheel).

Upstream-Status: To upstream [not yet submitted; this port may only touch riseproject-dev/python-wheels]
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pyproject.toml b/pyproject.toml
index eb38d37a6..b29e5cc93 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ name = "scipp"
description = "Multi-dimensional data arrays with labeled dimensions"
readme = "README.md"
license = "BSD-3-Clause"
-license-files = ["LICENSE"]
+license-files = ["LICENSE", "LICENSE.*"]
authors = [{ name = "Scipp contributors (https://github.com/scipp)" }]
classifiers = [
"Intended Audience :: Science/Research",
--
2.43.0
Loading