Skip to content

Commit 4ee27e4

Browse files
authored
edt: add build-edt.yml for riscv64 wheels (#1377)
* **Package**: `edt` * **Version**: `3.1.2` * **Source**: https://github.com/seung-lab/euclidean-distance-transform-3d/ * **Docs**: https://github.com/seung-lab/euclidean-distance-transform-3d/ Multi-label anisotropic Euclidean distance transform for numpy arrays, compiled from a Cython/C++ extension. Upstream publishes no riscv64 wheel. Mirrors [upstream's `build_wheels.yml`](https://github.com/seung-lab/euclidean-distance-transform-3d/blob/3.1.2/.github/workflows/build_wheels.yml). **Differs from upstream** - numpy pinned to our riscv64 registry (`PIP_ONLY_BINARY=numpy`) - PyPI ships no riscv64 numpy wheel. - Runs upstream's `tests.yml` suite (`automated_test.py`) via `CIBW_TEST_COMMAND` - `build_wheels.yml` itself builds without testing. **Testing** - `python -m pytest automated_test.py`, same suite as upstream's separate `tests.yml`. **License**: Patched `setup.cfg`'s `license_files` (`COPYING`, `COPYING.LESSER`) so the wheel ships the LGPL-3.0-or-later text; upstream's own PyPI wheels currently ship none. **Patches** - `0001-Ship-the-LGPL-license-files-in-the-wheel.patch` - To upstream [not yet submitted]. Without it the wheel has no `dist-info/licenses/` entry at all; reproduces on any platform, not riscv64-specific. Built on cp312 equivalent (macOS arm64, local `pip wheel`, no cibuildwheel/riscv64); 84 passed.
1 parent 399019a commit 4ee27e4

2 files changed

Lines changed: 144 additions & 0 deletions

File tree

.github/workflows/build-edt.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# Based on: https://github.com/seung-lab/euclidean-distance-transform-3d/blob/3.1.2/.github/workflows/build_wheels.yml
5+
name: Build edt wheels (riscv64)
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'edt version to build (git tag, e.g. 3.1.2)'
12+
required: true
13+
default: '3.1.2'
14+
pull_request:
15+
paths:
16+
- '.github/workflows/build-edt.yml'
17+
- 'patches/edt/**'
18+
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ inputs.version || '3.1.2' }}-${{ github.head_ref || github.run_id }}
21+
cancel-in-progress: true
22+
23+
permissions:
24+
contents: read # to fetch code (actions/checkout)
25+
26+
env:
27+
EDT_VERSION: ${{ inputs.version || '3.1.2' }}
28+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
29+
30+
jobs:
31+
setup:
32+
uses: $/.github/workflows/_setup.yml
33+
34+
build_wheels:
35+
needs: [setup]
36+
name: Build edt ${{ inputs.version || '3.1.2' }} ${{ matrix.python }}-manylinux_riscv64
37+
runs-on: ubuntu-24.04-riscv
38+
timeout-minutes: 60
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
python: ["cp312", "cp313", "cp314", "cp314t"]
43+
44+
steps:
45+
- name: Checkout edt ${{ env.EDT_VERSION }}
46+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47+
with:
48+
repository: seung-lab/euclidean-distance-transform-3d
49+
ref: ${{ env.EDT_VERSION }}
50+
persist-credentials: false
51+
52+
- name: Checkout python-wheels
53+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
54+
with:
55+
path: python-wheels
56+
persist-credentials: false
57+
58+
- name: Apply patches
59+
run: git apply python-wheels/patches/edt/${{ env.EDT_VERSION }}/*.patch
60+
61+
- uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
62+
with:
63+
output-dir: wheelhouse/
64+
only: ${{ matrix.python }}-manylinux_riscv64
65+
env:
66+
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
67+
# numpy is a build-time requirement (headers, via pyproject.toml's
68+
# build-system.requires) and, despite not being declared as a
69+
# runtime dependency by name, an implicit one too (the compiled
70+
# extension calls numpy's C API at import time). Only our registry
71+
# has it for riscv64; only-binary keeps a newer PyPI release from
72+
# winning the resolution and then compiling from sdist.
73+
CIBW_ENVIRONMENT: >-
74+
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
75+
PIP_ONLY_BINARY=numpy
76+
CIBW_TEST_REQUIRES: pytest numpy scipy
77+
CIBW_TEST_COMMAND: python -m pytest -v {project}/automated_test.py
78+
79+
- name: Check wheel contents
80+
run: |
81+
python3 - wheelhouse/*.whl <<'EOF'
82+
import sys, zipfile
83+
names = zipfile.ZipFile(sys.argv[1]).namelist()
84+
exts = {n.split("/")[-1].split(".")[0] for n in names if n.endswith(".so")}
85+
assert exts == {"edt"}, exts
86+
licences = {n.rsplit("/", 1)[-1] for n in names if ".dist-info/licenses/" in n} - {""}
87+
assert licences == {"COPYING", "COPYING.LESSER"}, licences
88+
EOF
89+
90+
- name: Store wheels
91+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
92+
with:
93+
name: edt-${{ env.EDT_VERSION }}-${{ matrix.python }}-manylinux_riscv64
94+
path: ./wheelhouse/*.whl
95+
if-no-files-found: error
96+
97+
publish:
98+
name: Publish edt ${{ inputs.version || '3.1.2' }}
99+
needs: [setup, build_wheels]
100+
permissions:
101+
contents: write
102+
pull-requests: write
103+
uses: $/.github/workflows/_publish-wheel.yml
104+
with:
105+
artifact-pattern: edt-${{ inputs.version || '3.1.2' }}-*-manylinux_riscv64
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
From 28d7662d54333ee225c4567fb26a22f7608a8479 Mon Sep 17 00:00:00 2001
2+
From: Ludovic Henry <git@ludovic.dev>
3+
Date: Mon, 7 Sep 2026 16:03:48 +0200
4+
Subject: [PATCH] Ship the LGPL license files in the wheel
5+
6+
setup.cfg names license_files = LICENSE, but the project has no LICENSE
7+
file at the root -- only COPYING (GPLv3 text) and COPYING.LESSER (the
8+
LGPLv3 addendum, per the standard GNU dual-file convention). An explicit
9+
license_files list turns off setuptools' default LICEN[CS]E*/COPYING*
10+
glob, so the mismatch means every published wheel (verified on PyPI's
11+
edt-3.1.2 manylinux wheels) ships no license file at all in
12+
dist-info/licenses/.
13+
14+
Point license_files at the files that actually exist so the wheel
15+
carries the LGPL-3.0-or-later text it declares.
16+
17+
Upstream-Status: To upstream [not yet submitted; same gap exists in every edt wheel on PyPI historically, needs maintainer discussion not a drive-by PR]
18+
---
19+
setup.cfg | 4 +++-
20+
1 file changed, 3 insertions(+), 1 deletion(-)
21+
22+
diff --git a/setup.cfg b/setup.cfg
23+
index 43efb4b..464890d 100644
24+
--- a/setup.cfg
25+
+++ b/setup.cfg
26+
@@ -7,7 +7,9 @@ description_file = README.md
27+
author = William Silversmith
28+
author_email = ws9@princeton.edu
29+
home_page = https://github.com/seung-lab/euclidean-distance-transform-3d/
30+
-license_files = LICENSE
31+
+license_files =
32+
+ COPYING
33+
+ COPYING.LESSER
34+
license = LGPL-3.0-or-later
35+
classifier =
36+
Intended Audience :: Developers
37+
--
38+
2.50.1 (Apple Git-155)
39+

0 commit comments

Comments
 (0)