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
145 changes: 145 additions & 0 deletions .github/workflows/build-fastjet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on: https://github.com/scikit-hep/fastjet/blob/v3.5.1.4/.github/workflows/wheels.yml
name: Build fastjet wheels (riscv64)

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

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: fastjet
version: ${{ inputs.version }}

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

steps:
- name: Checkout fastjet ${{ env.FASTJET_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: scikit-hep/fastjet
ref: v${{ env.FASTJET_VERSION }}
submodules: recursive
persist-credentials: false

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

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

- 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 }}
CIBW_CONFIG_SETTINGS: >
"cmake.define.FASTJET_ENABLE_CGAL"="ON"
# Licence notices of the CGAL and Boost headers compiled in by upstream's before-all.
CIBW_BEFORE_BUILD: >-
cp {project}/boost_1_88_0/LICENSE_1_0.txt {project}/LICENSE.boost &&
cp /usr/local/share/doc/CGAL/LICENSE {project}/LICENSE.CGAL &&
cp /usr/local/share/doc/CGAL/LICENSE.GPL {project}/LICENSE.CGAL.GPL &&
cp /usr/local/share/doc/CGAL/LICENSE.LGPL {project}/LICENSE.CGAL.LGPL
# Our registry carries awkward-cpp 56, not PyPI's newest 57: stay on awkward 2.13.0.
CIBW_ENVIRONMENT: >-
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_FASTJET=${{ env.FASTJET_VERSION }}
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
PIP_ONLY_BINARY=numpy,awkward-cpp,pyarrow,pandas,boost-histogram
# pandas (via dask-awkward[test]) has no free-threaded riscv64 wheel, so cp314t gets
# upstream's `test` extra minus dask-awkward's own [test] extra. Keep dask, dask-awkward
# and distributed in the same pip call: cibuildwheel installs the wheel's extras and
# test-requires in two separate pip runs, and splitting them let the second run pull
# distributed 2026.8.0, which upgraded dask past dask-awkward 2026.2.1's dask<2025.4.0
# pin and broke test_008-dask.py ("Cannot fuse tasks with multiple outputs").
CIBW_TEST_EXTRAS: ${{ matrix.python == 'cp314t' && 'dev' || 'test' }}
CIBW_TEST_REQUIRES: ${{ matrix.python == 'cp314t' && 'uproot>=5 dask>=2023.4.0 dask-awkward>=2023.4.2 distributed>=2023.4.0' || '' }}

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

- name: Check the wheel ships the extensions and the bundled licences
run: |
python3 - wheelhouse/*.whl <<'EOF'
import sys, zipfile

names = zipfile.ZipFile(sys.argv[1]).namelist()
for mod in ("fastjet/_ext.", "fastjet/_swig/_fastjet_swig."):
assert any(n.startswith(mod) and n.endswith(".so") for n in names), mod
for lib in ("fastjet", "fastjettools", "fastjetplugins", "siscone", "fastjetcontribfragile"):
assert f"fastjet/lib64/lib{lib}.so" in names, lib
assert not any(n.startswith("fastjet.libs/") for n in names), names
licences = {n.split(".dist-info/licenses/", 1)[1] for n in names if ".dist-info/licenses/" in n} - {""}
for want in ("LICENSE", "LICENSE.boost", "LICENSE.CGAL", "LICENSE.CGAL.GPL", "LICENSE.CGAL.LGPL",
"extern/fastjet-core/COPYING", "extern/fastjet-core/plugins/SISCone/siscone/COPYING",
"extern/fastjet-contrib/COPYING", "extern/fastjet-contrib/Nsubjettiness/COPYING"):
assert want in licences, (want, sorted(licences))
print(sys.argv[1], len(licences), "licence files ok")
EOF

publish:
name: Publish fastjet ${{ 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: fastjet-${{ matrix.version }}-*-manylinux_riscv64
6 changes: 6 additions & 0 deletions docs/packages/fastjet.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package-name: fastjet
source-code: https://github.com/scikit-hep/fastjet
license: BSD-3-Clause AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-or-later AND BSL-1.0
versions:
- version: 3.5.1.4
patched: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Fri, 2 Oct 2026 12:00:00 +0200
Subject: [PATCH] pyproject: ship licence files of bundled libraries

The wheels compile and ship FastJet (extern/fastjet-core, GPL-2.0-or-later),
SISCone (GPL-2.0-or-later) and the fastjet-contrib packages (each under
its own COPYING) as fastjet/lib64/*.so, and compile CGAL (GPL-3.0-or-later
/ LGPL-3.0-or-later) and Boost (BSL-1.0) headers into libfastjet, but
only carry the binding's own BSD-3-Clause LICENSE.

List the in-tree COPYING files, and widen LICENSE to LICENSE* so the
CGAL and Boost notices staged as LICENSE.<dep> at the project root
before the wheel build are packaged into dist-info/licenses/ too. The
sdist still only matches LICENSE at its root.

Upstream-Status: To upstream [not yet submitted; the same gap exists in every fastjet wheel on PyPI, so it needs a maintainer discussion rather than a drive-by PR]
---
pyproject.toml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/pyproject.toml b/pyproject.toml
index ade2171..741d23d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,13 @@ dynamic = ["version"]
requires-python = ">=3.10"
readme = "README.md"
license = "BSD-3-clause"
-license-files = ["LICENSE"]
+license-files = [
+ "LICENSE*",
+ "extern/fastjet-core/COPYING",
+ "extern/fastjet-core/plugins/SISCone/siscone/COPYING",
+ "extern/fastjet-contrib/COPYING",
+ "extern/fastjet-contrib/*/COPYING",
+]
classifiers = [
"Development Status :: 1 - Planning",
"Intended Audience :: Developers",
--
2.43.0

Loading