|
| 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