Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/workflows/build-pyiceberg-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on: https://github.com/apache/iceberg-rust/blob/v0.10.1/.github/workflows/release_python.yml
name: Build pyiceberg-core wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'pyiceberg-core version to build (git tag without leading v, e.g. 0.10.1)'
required: true
default: '0.10.1'
pull_request:
paths:
- '.github/workflows/build-pyiceberg-core.yml'

concurrency:
group: ${{ github.workflow }}-${{ inputs.version || '0.10.1' }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

env:
# `inputs.version` is empty on pull_request events; default to 0.10.1 there.
PYICEBERG_CORE_VERSION: ${{ inputs.version || '0.10.1' }}
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64

jobs:
setup:
uses: $/.github/workflows/_setup.yml

build_wheels:
needs: [setup]
name: Build pyiceberg-core ${{ inputs.version || '0.10.1' }} cp310-abi3-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 360

steps:
# Checked out at the workspace root: bindings/python is a member of the
# iceberg-rust Cargo workspace and builds against its sibling crates.
- name: Checkout iceberg-rust v${{ env.PYICEBERG_CORE_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: apache/iceberg-rust
ref: v${{ env.PYICEBERG_CORE_VERSION }}
persist-credentials: false

- name: Build wheel
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
with:
package-dir: bindings/python
output-dir: wheelhouse/
# pyo3 carries abi3-py310 unconditionally, so upstream ships one
# cp310-abi3 wheel (their own release job builds it on python3.12,
# not the abi3 floor); pypi.riseproject.dev also has no riscv64
# pyarrow/pyiceberg/fastavro wheel below cp312, so cp312 is where we
# build and test too (build-deltalake.yml takes the same wheel-once
# approach for the same reasons).
only: cp312-manylinux_riscv64
env:
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
# iceberg-rust ships no [tool.cibuildwheel]; the Rust toolchain its
# maturin backend needs is installed in-container here. musllinux is
# dropped - rustup.rs ships no riscv64 musl toolchain.
CIBW_BEFORE_ALL_LINUX: >-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# The checkout's rust-toolchain.toml pins a nightly for clippy/rustfmt
# only (its own comment: "will not affect downstream users") but that
# file ships in the git tree, not the sdist pip builds from, so it
# overrides the stable toolchain above unless RUSTUP_TOOLCHAIN forces it.
CIBW_ENVIRONMENT_LINUX: PATH="$PATH:$HOME/.cargo/bin" RUSTUP_TOOLCHAIN=stable
# conftest.py imports pyiceberg at module level for every test file.
CIBW_TEST_REQUIRES: pytest pyarrow>=17 pyiceberg>=0.11
# test-sources resolves against the checkout root, not package-dir.
CIBW_TEST_SOURCES: bindings/python/tests bindings/python/pyproject.toml
CIBW_TEST_ENVIRONMENT_LINUX: >-
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
PIP_ONLY_BINARY=pyarrow,pyiceberg
# test_datafusion_table_provider.py and test_huggingface_and_cdc.py both
# `import datafusion` unconditionally, which has no riscv64 wheel anywhere.
# test_manifest.py imports pyiceberg.io.pyarrow, which unconditionally
# imports pyarrow._s3fs; build-pyarrow.yml ships ARROW_S3=OFF for riscv64,
# so that module can't be imported here either. Verified against the real
# riscv64 wheel: only test_transform.py collects and runs (11 passed).
CIBW_TEST_COMMAND: >-
cd bindings/python &&
python -c "import pyiceberg_core.pyiceberg_core_rust as m;
assert m.__file__.endswith('.so'), m.__file__" &&
python -m pytest tests/test_transform.py -v

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pyiceberg-core-${{ env.PYICEBERG_CORE_VERSION }}-cp310-abi3-manylinux_riscv64
path: wheelhouse/*.whl
if-no-files-found: error

publish:
name: Publish pyiceberg-core ${{ inputs.version || '0.10.1' }}
needs: [setup, build_wheels]
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
with:
artifact-pattern: pyiceberg-core-${{ inputs.version || '0.10.1' }}-*-manylinux_riscv64