Skip to content

Commit 818307f

Browse files
committed
Add gimli.units riscv64 wheel build
Unit-conversion candidate distinct from the already-published cf-units (SciTools/Iris climate stack): gimli.units is CSDMS's object-oriented Cython interface to UDUNITS-2, used for generic earth-science unit conversion rather than CF-convention data. Builds directly from an upstream checkout (mirroring upstream's own test.yml cibuildwheel job) since upstream stopped publishing an sdist at 0.3.3; expat 2.6.0 and UDUNITS-2 2.2.28 are vendored under extern/ and compiled to static libs via CMake in the project's own before-build commands, with no external dependency beyond a C compiler and cmake (both already in the manylinux_riscv64 image) - unlike cf-units, no EPEL workaround is needed since upstream already builds UDUNITS-2 from source on every platform. Widens license-files to ship the vendored expat/UDUNITS-2 notices alongside gimli.units' own LICENSE.md, matching the netcdf4/cf-units precedent.
1 parent fcfb5cd commit 818307f

3 files changed

Lines changed: 152 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# This workflow is based on: https://github.com/mcflugen/gimli/blob/v0.4.1/.github/workflows/test.yml
5+
name: Build gimli.units wheels (riscv64)
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'Version glob to (re)build; empty builds every version of docs/packages/gimli.units.yaml not released yet'
12+
required: false
13+
default: ''
14+
pull_request:
15+
branches: [main]
16+
paths:
17+
- '.github/workflows/build-gimli.units.yml'
18+
- 'docs/packages/gimli.units.yaml'
19+
- 'patches/gimli.units/**'
20+
push:
21+
branches: [main]
22+
paths:
23+
- '.github/workflows/build-gimli.units.yml'
24+
- 'docs/packages/gimli.units.yaml'
25+
- 'patches/gimli.units/**'
26+
27+
concurrency:
28+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
29+
cancel-in-progress: true
30+
31+
permissions:
32+
contents: read # to fetch code (actions/checkout)
33+
34+
env:
35+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
36+
MUSLLINUX_RISCV64_IMAGE: quay.io/pypa/musllinux_1_2_riscv64
37+
38+
jobs:
39+
setup:
40+
uses: $/.github/workflows/_setup.yml
41+
with:
42+
package: gimli.units
43+
version: ${{ inputs.version }}
44+
45+
build_wheels:
46+
needs: [setup]
47+
if: needs.setup.outputs.versions != '[]'
48+
name: Build gimli.units ${{ matrix.version }} ${{ matrix.python }}-${{ matrix.libc }}_riscv64
49+
runs-on: ubuntu-24.04-riscv
50+
timeout-minutes: 60
51+
strategy:
52+
fail-fast: false
53+
matrix:
54+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
55+
python: ["cp312", "cp313", "cp314"]
56+
libc: ["manylinux", "musllinux"]
57+
58+
env:
59+
GIMLI_UNITS_VERSION: ${{ matrix.version }}
60+
61+
steps:
62+
- name: Checkout gimli.units v${{ env.GIMLI_UNITS_VERSION }}
63+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
64+
with:
65+
repository: mcflugen/gimli
66+
ref: v${{ env.GIMLI_UNITS_VERSION }}
67+
persist-credentials: false
68+
69+
- name: Checkout python-wheels
70+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
71+
with:
72+
path: python-wheels
73+
persist-credentials: false
74+
75+
- name: Patch gimli.units source
76+
run: git apply python-wheels/patches/gimli.units/${{ env.GIMLI_UNITS_VERSION }}/*.patch
77+
78+
- uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
79+
with:
80+
output-dir: wheelhouse/
81+
env:
82+
CIBW_ARCHS: riscv64
83+
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.libc }}_riscv64
84+
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
85+
CIBW_MUSLLINUX_RISCV64_IMAGE: ${{ env.MUSLLINUX_RISCV64_IMAGE }}
86+
# Overriding CIBW_ENVIRONMENT replaces upstream's own pyproject.toml
87+
# `environment` setting wholesale, so UDUNITS2_PREFIX (needed by
88+
# setup.py's static-link lookup) is repeated here verbatim alongside
89+
# the registry index.
90+
CIBW_ENVIRONMENT: >-
91+
UDUNITS2_PREFIX=$(pwd -P)/dist/extern
92+
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
93+
CIBW_TEST_REQUIRES: hypothesis pytest
94+
CIBW_TEST_COMMAND: pytest {package}/tests
95+
96+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
97+
with:
98+
name: gimli.units-${{ env.GIMLI_UNITS_VERSION }}-${{ matrix.python }}-${{ matrix.libc }}_riscv64
99+
path: ./wheelhouse/*.whl
100+
if-no-files-found: error
101+
102+
publish:
103+
name: Publish gimli.units ${{ matrix.version }}
104+
needs: [setup, build_wheels]
105+
if: needs.setup.outputs.versions != '[]'
106+
strategy:
107+
fail-fast: false
108+
matrix:
109+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
110+
permissions:
111+
contents: write
112+
pull-requests: write
113+
uses: $/.github/workflows/_publish-wheel.yml
114+
secrets:
115+
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
116+
with:
117+
artifact-pattern: gimli.units-${{ matrix.version }}-*riscv64

‎docs/packages/gimli.units.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package-name: gimli.units
2+
source-code: https://github.com/mcflugen/gimli
3+
license: MIT
4+
versions:
5+
- version: 0.4.1
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
From: Ludovic Henry <git@ludovic.dev>
2+
Date: Thu, 15 Oct 2026 00:00:00 +0000
3+
Subject: [PATCH] pyproject: widen license-files to cover vendored expat/udunits2
4+
5+
Every platform's wheel (not just riscv64) statically links expat 2.6.0 and
6+
UDUNITS-2 2.2.28 from the vendored extern/ sources, but license-files names
7+
only gimli.units' own LICENSE.md, so neither dependency's notice travels
8+
with the binary even though both require it.
9+
10+
Naming the two vendored notices alongside LICENSE.md lets the wheel build
11+
stage them and have them land in .dist-info/licenses/.
12+
13+
Upstream-Status: To upstream [affects every platform's wheel, not a riscv64-only build detail]
14+
---
15+
pyproject.toml | 2 +-
16+
1 file changed, 1 insertion(+), 1 deletion(-)
17+
18+
diff --git a/pyproject.toml b/pyproject.toml
19+
index 1111111..2222222 100644
20+
--- a/pyproject.toml
21+
+++ b/pyproject.toml
22+
@@ -4,7 +4,7 @@
23+
requires-python = ">=3.11"
24+
description = "An object-oriented Python interface to udunits"
25+
license = "MIT"
26+
-license-files = ["LICENSE.md"]
27+
+license-files = ["LICENSE.md", "extern/expat-2.6.0/COPYING", "extern/udunits-2.2.28/COPYRIGHT"]
28+
keywords = [
29+
"earth science",
30+
"model coupling",

0 commit comments

Comments
 (0)