Skip to content

Commit dca5211

Browse files
committed
pagefind-bin: add build-pagefind-bin.yml for riscv64 wheels
1 parent 6179c94 commit dca5211

1 file changed

Lines changed: 254 additions & 0 deletions

File tree

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# pagefind-bin has no sdist and ships only x86_64/aarch64 wheels, packaged by
5+
# pagefind/pagefind's own wrappers/python/scripts/build/binary_only_wheel.py
6+
# from binaries built by .github/workflows/release.yml (no riscv64 target,
7+
# and no riscv64 musl toolchain exists to match its musl builds either - see
8+
# build-ripgrep.yml). This workflow reproduces that pipeline for riscv64: an
9+
# arch-independent job builds the WASM/JS/UI assets release.yml's own "Build
10+
# WASM"/"Build Coupled JS"/"Build UI" steps produce (gotcha 4), then the
11+
# riscv64 job builds the `pagefind` binary from source and repackages it
12+
# using the checkout's own binary_only_wheel.py - not maturin bindings=bin
13+
# (build-ripgrep.yml/build-just-bin.yml), since the `pagefind` API package's
14+
# `from pagefind_bin import get_executable` depends on pagefind_bin's actual
15+
# wheel layout (binary at pagefind_bin/pagefind), which maturin's
16+
# bindings=bin/.data/scripts layout does not produce.
17+
name: Build pagefind-bin wheels (riscv64)
18+
19+
on:
20+
workflow_dispatch:
21+
inputs:
22+
version:
23+
description: 'pagefind-bin version to build (git tag of pagefind/pagefind without the leading v, e.g. 1.5.2)'
24+
required: true
25+
default: '1.5.2'
26+
pull_request:
27+
paths:
28+
- '.github/workflows/build-pagefind-bin.yml'
29+
30+
concurrency:
31+
group: ${{ github.workflow }}-${{ inputs.version || '1.5.2' }}-${{ github.head_ref || github.run_id }}
32+
cancel-in-progress: true
33+
34+
permissions:
35+
contents: read
36+
37+
env:
38+
# `inputs.version` is empty on pull_request events; default to 1.5.2 there.
39+
PAGEFIND_VERSION: ${{ inputs.version || '1.5.2' }}
40+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
41+
42+
jobs:
43+
setup:
44+
uses: $/.github/workflows/_setup.yml
45+
46+
build_web_assets:
47+
needs: [setup]
48+
name: Build pagefind ${{ inputs.version || '1.5.2' }} web assets
49+
runs-on: ubuntu-latest
50+
timeout-minutes: 60
51+
steps:
52+
- name: Checkout pagefind v${{ env.PAGEFIND_VERSION }}
53+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
54+
with:
55+
repository: pagefind/pagefind
56+
ref: v${{ env.PAGEFIND_VERSION }}
57+
persist-credentials: false
58+
59+
# release.yml's own "Prepare Crates" step, minus the git commit (only
60+
# needed there for `cargo publish`, which this workflow never runs) -
61+
# the built JS/WASM asset filenames embed this version, and
62+
# pagefind/Cargo.toml's CARGO_PKG_VERSION must match it for the
63+
# `include_bytes!` paths in pagefind/src/output/mod.rs to resolve.
64+
- name: Set crate/package versions
65+
run: node ./.backstage/version.cjs
66+
env:
67+
GIT_VERSION: ${{ env.PAGEFIND_VERSION }}
68+
69+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
70+
with:
71+
node-version: 24
72+
73+
- name: Build Coupled JS
74+
working-directory: pagefind_web_js
75+
run: npm i && npm run build-coupled
76+
77+
- name: Install Rust
78+
run: rustup toolchain install nightly --component rust-src --target wasm32-unknown-unknown
79+
80+
- name: Install wasm-pack
81+
uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa # v0.4.0
82+
with:
83+
version: v0.14.0
84+
85+
- name: Build WASM
86+
working-directory: pagefind_web
87+
run: ./local_build.sh
88+
env:
89+
GIT_VERSION: ${{ env.PAGEFIND_VERSION }}
90+
91+
- name: Build UI
92+
working-directory: pagefind_ui/default
93+
run: npm i && npm run build
94+
95+
- name: Build Modular UI
96+
working-directory: pagefind_ui/modular
97+
run: npm i && npm run build
98+
99+
- name: Build Component UI
100+
working-directory: pagefind_ui/component
101+
run: npm i && npm run build
102+
103+
# pagefind/src/playground.rs include_str!s this unconditionally, even
104+
# though the playground is a dev-only debugging UI unrelated to indexing.
105+
- name: Build Playground
106+
working-directory: pagefind_playground
107+
run: npm i && npm run build
108+
109+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
110+
with:
111+
name: pagefind-bin-${{ env.PAGEFIND_VERSION }}-vendor
112+
path: pagefind/vendor
113+
if-no-files-found: error
114+
115+
build_wheel:
116+
needs: [setup, build_web_assets]
117+
name: Build pagefind-bin ${{ inputs.version || '1.5.2' }} manylinux_riscv64
118+
runs-on: ubuntu-24.04-riscv
119+
timeout-minutes: 360
120+
steps:
121+
- name: Checkout pagefind v${{ env.PAGEFIND_VERSION }}
122+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
123+
with:
124+
repository: pagefind/pagefind
125+
ref: v${{ env.PAGEFIND_VERSION }}
126+
persist-credentials: false
127+
128+
- name: Download web assets
129+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
130+
with:
131+
name: pagefind-bin-${{ env.PAGEFIND_VERSION }}-vendor
132+
path: pagefind/vendor
133+
134+
- name: Set pagefind crate version
135+
run: sed -i "s/^version = \"0.0.0\"/version = \"${PAGEFIND_VERSION}\"/" pagefind/Cargo.toml
136+
137+
# Written to $RUNNER_TEMP and bind-mounted rather than checked in (gotcha
138+
# 7 / CLAUDE.md): installs rustup inside the container (gotcha 10), builds
139+
# the CLI natively for the container's own riscv64 glibc, then calls this
140+
# checkout's own wrappers/python/scripts/build/binary_only_wheel.py to
141+
# repackage it exactly as release.yml's "Prepare Python Packages" job
142+
# does for every other platform.
143+
- name: Write in-container build script
144+
run: |
145+
cat > "$RUNNER_TEMP/build.sh" <<'SCRIPT'
146+
set -euxo pipefail
147+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
148+
source "$HOME/.cargo/env"
149+
rustup target add riscv64gc-unknown-linux-gnu
150+
(cd pagefind && cargo build --release --target riscv64gc-unknown-linux-gnu)
151+
pybin=/opt/python/cp312-cp312/bin
152+
"$pybin/pip" install -q wheel
153+
mkdir -p dist
154+
PYTHONPATH=wrappers/python "$pybin/python3" - <<'PY'
155+
import os
156+
from pathlib import Path
157+
158+
from scripts.build.binary_only_wheel import write_pagefind_bin_only_wheel
159+
160+
write_pagefind_bin_only_wheel(
161+
executable=Path("target/riscv64gc-unknown-linux-gnu/release/pagefind"),
162+
output_dir=Path("dist"),
163+
version=os.environ["PAGEFIND_VERSION"],
164+
platform="manylinux_2_39_riscv64",
165+
)
166+
PY
167+
SCRIPT
168+
169+
- name: Build wheel
170+
run: |
171+
docker run --rm \
172+
-v "$(pwd)":/workspace \
173+
-v "$RUNNER_TEMP/build.sh":/build.sh \
174+
-w /workspace \
175+
-e PAGEFIND_VERSION \
176+
"${MANYLINUX_RISCV64_IMAGE}" \
177+
bash /build.sh
178+
179+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
180+
with:
181+
name: pagefind-bin-${{ env.PAGEFIND_VERSION }}-manylinux_riscv64
182+
path: dist/*.whl
183+
if-no-files-found: error
184+
185+
test_wheel:
186+
name: Test pagefind-bin ${{ inputs.version || '1.5.2' }} on Python ${{ matrix.python-version }}
187+
needs: [setup, build_wheel]
188+
runs-on: ubuntu-24.04-riscv
189+
timeout-minutes: 30
190+
env:
191+
# Without this uv would reuse the runner image's system CPython for 3.12
192+
# and download a standalone build for the others.
193+
UV_PYTHON_PREFERENCE: only-managed
194+
strategy:
195+
fail-fast: false
196+
matrix:
197+
# This repo's default interpreter matrix (gotcha in workflow-anatomy.md);
198+
# the wheel is interpreter-agnostic (py3-none), so every interpreter --
199+
# including free-threaded -- exercises the same binary.
200+
python-version: ['3.12', '3.13', '3.14', '3.14t']
201+
202+
steps:
203+
- name: Download wheel
204+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
205+
with:
206+
name: pagefind-bin-${{ env.PAGEFIND_VERSION }}-manylinux_riscv64
207+
208+
- name: Install Python
209+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
210+
with:
211+
python-version: ${{ matrix.python-version }}
212+
activate-environment: true
213+
enable-cache: false
214+
215+
- name: Install wheel
216+
run: uv pip install --reinstall --no-index --find-links . pagefind_bin
217+
218+
- name: Test wheel
219+
run: |
220+
set -euo pipefail
221+
python -m pagefind_bin --version
222+
python -c "from pagefind_bin import get_executable; p = get_executable(); print(p); assert p.is_file()"
223+
224+
bin=$(python -c "from pagefind_bin import get_executable; print(get_executable())")
225+
"$bin" --version
226+
"$bin" --help >/dev/null
227+
228+
work=$(mktemp -d)
229+
mkdir -p "$work/public"
230+
cat > "$work/public/index.html" <<'HTML'
231+
<!doctype html>
232+
<html lang="en">
233+
<body>
234+
<main>
235+
<h1>Hello Pagefind</h1>
236+
<p>The quick brown fox jumps over the lazy dog.</p>
237+
</main>
238+
</body>
239+
</html>
240+
HTML
241+
242+
"$bin" --site "$work/public"
243+
[ -f "$work/public/pagefind/pagefind.js" ]
244+
[ -f "$work/public/pagefind/pagefind-entry.json" ]
245+
246+
publish:
247+
name: Publish pagefind-bin ${{ inputs.version || '1.5.2' }}
248+
needs: [setup, build_wheel, test_wheel]
249+
permissions:
250+
contents: write
251+
pull-requests: write
252+
uses: $/.github/workflows/_publish-wheel.yml
253+
with:
254+
artifact-pattern: pagefind-bin-${{ inputs.version || '1.5.2' }}-manylinux_riscv64

0 commit comments

Comments
 (0)