Skip to content

Commit bf4fc54

Browse files
authored
pyvrl: add build-pyvrl.yml for riscv64 wheels (#2176)
* **Package**: `pyvrl` * **Version**: `0.0.2` * **Source**: https://github.com/crowdalert/pyvrl * **Docs**: https://github.com/crowdalert/pyvrl Compiles a pyo3/maturin extension wrapping Vector's `vrl` crate - the Vector Remap Language compiler and stdlib - into a per-interpreter wheel. Upstream publishes no riscv64 wheel. Mirrors [upstream's `ci.yaml`](https://github.com/crowdalert/pyvrl/blob/v0.0.2/.github/workflows/ci.yaml) `linux` job. **Differs from upstream** - musllinux dropped - rustup.rs ships no riscv64 musl toolchain. **Matrix**: `cp312` only - pyo3 0.20 supports nothing newer, and its `PYO3_USE_ABI3_FORWARD_COMPATIBILITY` escape hatch turns on `Py_LIMITED_API`, which cfg-removes the chrono conversions pyvrl needs for VRL timestamp values. Upstream's own wheels stop at cp312 for the same reason. **Testing** - Upstream's CI has no test step; exercises the documented `Transform`/`remap` API instead - the README example plus JSON, timestamp, unicode and error paths. **License**: OK
1 parent 7e22251 commit bf4fc54

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

‎.github/workflows/build-pyvrl.yml‎

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# This workflow is based on: https://github.com/crowdalert/pyvrl/blob/v0.0.2/.github/workflows/ci.yaml
5+
name: Build pyvrl 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/pyvrl.yaml not released yet'
12+
required: false
13+
default: ''
14+
pull_request:
15+
branches: [main]
16+
paths:
17+
- '.github/workflows/build-pyvrl.yml'
18+
- 'docs/packages/pyvrl.yaml'
19+
push:
20+
branches: [main]
21+
paths:
22+
- '.github/workflows/build-pyvrl.yml'
23+
- 'docs/packages/pyvrl.yaml'
24+
25+
concurrency:
26+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
27+
cancel-in-progress: true
28+
29+
permissions:
30+
contents: read # to fetch code (actions/checkout)
31+
32+
env:
33+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
34+
35+
jobs:
36+
setup:
37+
uses: $/.github/workflows/_setup.yml
38+
with:
39+
package: pyvrl
40+
version: ${{ inputs.version }}
41+
42+
build_wheels:
43+
needs: [setup]
44+
if: needs.setup.outputs.versions != '[]'
45+
name: Build pyvrl ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64
46+
runs-on: ubuntu-24.04-riscv
47+
timeout-minutes: 1440
48+
strategy:
49+
fail-fast: false
50+
matrix:
51+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
52+
# cp312 is pyo3 0.20's ceiling, which is also where upstream's own
53+
# wheels stop. PYO3_USE_ABI3_FORWARD_COMPATIBILITY would lift it, but
54+
# it turns on Py_LIMITED_API, and pyo3 0.20 cfg-removes the chrono
55+
# conversions this crate needs under it.
56+
python: ["cp312"]
57+
58+
env:
59+
PYVRL_VERSION: ${{ matrix.version }}
60+
61+
steps:
62+
- name: Checkout pyvrl ${{ env.PYVRL_VERSION }}
63+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
64+
with:
65+
repository: crowdalert/pyvrl
66+
ref: v${{ env.PYVRL_VERSION }}
67+
persist-credentials: false
68+
69+
- name: Build wheels
70+
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
71+
with:
72+
output-dir: wheelhouse/
73+
# musllinux is dropped: rustup.rs ships no riscv64 musl toolchain.
74+
only: ${{ matrix.python }}-manylinux_riscv64
75+
env:
76+
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
77+
# pyvrl ships no [tool.cibuildwheel], so the Rust toolchain its
78+
# maturin backend needs is installed in-container here.
79+
CIBW_BEFORE_ALL_LINUX: >-
80+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
81+
CIBW_ENVIRONMENT_LINUX: >-
82+
PATH="$PATH:$HOME/.cargo/bin"
83+
CIBW_TEST_COMMAND: |
84+
python3 - <<'PYEOF'
85+
import datetime
86+
from pyvrl import Transform
87+
program = '''
88+
.y = "bar"
89+
.x = upcase!(.x)
90+
.n = to_int!(.n) + 1
91+
.list = push!(.list, "z")
92+
.
93+
'''
94+
transform = Transform(program)
95+
assert transform.source == program
96+
out = transform.remap({"x": "foo", "n": 41, "list": ["a"]})
97+
assert out == {"x": "FOO", "y": "bar", "n": 42, "list": ["a", "z"]}, out
98+
unicode = Transform('.s = upcase!(.s)\n.')
99+
assert unicode.remap({"s": "caf\N{LATIN SMALL LETTER E WITH ACUTE} \N{EARTH GLOBE AMERICAS}"}) == {"s": "CAF\N{LATIN CAPITAL LETTER E WITH ACUTE} \N{EARTH GLOBE AMERICAS}"}
100+
parsed = Transform('. = parse_json!(.raw)').remap({"raw": '{"a": [1, 2.5, true, null]}'})
101+
assert parsed == {"a": [1, 2.5, True, None]}, parsed
102+
stamp = Transform('. = {"t": parse_timestamp!("2024-05-06T07:08:09Z", "%+")}').remap({})
103+
assert stamp == {"t": datetime.datetime(2024, 5, 6, 7, 8, 9, tzinfo=datetime.timezone.utc)}, stamp
104+
try:
105+
Transform(".x = no_such_function!(.x)")
106+
except ValueError:
107+
pass
108+
else:
109+
raise AssertionError("expected a compile error")
110+
try:
111+
Transform("abort").remap({})
112+
except ValueError:
113+
pass
114+
else:
115+
raise AssertionError("expected a runtime error")
116+
print("pyvrl OK")
117+
PYEOF
118+
119+
- name: Check the extension made it into the wheel
120+
run: |
121+
python3 - wheelhouse/*.whl <<'EOF'
122+
import sys, zipfile
123+
for whl in sys.argv[1:]:
124+
names = zipfile.ZipFile(whl).namelist()
125+
assert any(n.startswith("pyvrl/pyvrl.") and n.endswith(".so") for n in names), names
126+
assert any("licen" in n and n.endswith("LICENSE") for n in names), names
127+
print(whl, "ok")
128+
EOF
129+
130+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
131+
with:
132+
name: pyvrl-${{ env.PYVRL_VERSION }}-${{ matrix.python }}-manylinux_riscv64
133+
path: wheelhouse/*.whl
134+
if-no-files-found: error
135+
136+
publish:
137+
name: Publish pyvrl ${{ matrix.version }}
138+
needs: [setup, build_wheels]
139+
if: needs.setup.outputs.versions != '[]'
140+
strategy:
141+
fail-fast: false
142+
matrix:
143+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
144+
permissions:
145+
contents: write
146+
pull-requests: write
147+
uses: $/.github/workflows/_publish-wheel.yml
148+
secrets:
149+
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
150+
with:
151+
artifact-pattern: pyvrl-${{ matrix.version }}-*-manylinux_riscv64

‎docs/packages/pyvrl.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package-name: pyVRL
2+
source-code: https://github.com/crowdalert/pyvrl
3+
license: MIT
4+
versions:
5+
- version: 0.0.2

0 commit comments

Comments
 (0)