workflows: add build-apache-tvm-ffi.yml for riscv64 manywheel builds #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: 2026 The RISE Project | |
| # SPDX-License-Identifier: MIT | |
| --- | |
| # This workflow is based on upstream's own wheel build/publish setup: | |
| # https://github.com/apache/tvm-ffi/blob/v0.1.12/.github/workflows/publish_wheel.yml | |
| # https://github.com/apache/tvm-ffi/blob/v0.1.12/.github/actions/build-wheel-for-publish/action.yml | |
| name: Build apache-tvm-ffi wheels (riscv64) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'apache-tvm-ffi version to build (git tag without leading v, e.g. 0.1.12)' | |
| required: true | |
| default: '0.1.12' | |
| pull_request: | |
| paths: | |
| - '.github/workflows/build-apache-tvm-ffi.yml' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.version || '0.1.12' }}-${{ 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.1.12 there. | |
| TVM_FFI_VERSION: ${{ inputs.version || '0.1.12' }} | |
| UV_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ | |
| UV_INDEX_STRATEGY: unsafe-best-match | |
| UV_ONLY_BINARY: ':all:' | |
| MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 | |
| jobs: | |
| build_sdist: | |
| # The sdist is architecture-independent: it just packages the source tree, | |
| # the vendored submodules (dlpack, libbacktrace) and a setuptools-scm-derived | |
| # _version.py. Build it once on x86 instead of burning a scarce riscv runner | |
| # (see CLAUDE.md gotcha 4). The resulting sdist is self-contained, so the | |
| # riscv wheel job below needs neither git history nor submodules. | |
| name: Build apache-tvm-ffi ${{ inputs.version || '0.1.12' }} sdist | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| sdist_name: ${{ steps.sdist.outputs.sdist_name }} | |
| steps: | |
| - name: Checkout tvm-ffi v${{ env.TVM_FFI_VERSION }} | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| repository: apache/tvm-ffi | |
| ref: v${{ env.TVM_FFI_VERSION }} | |
| # submodules must be present so pyproject's sdist.include /3rdparty/** | |
| # globs actually bundle dlpack + libbacktrace; setuptools-scm needs the | |
| # full history + tags to derive the version from the checked-out tag. | |
| submodules: recursive | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| persist-credentials: false | |
| - name: Install Python | |
| uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 | |
| with: | |
| python-version: '3.12' | |
| activate-environment: true | |
| enable-cache: false | |
| - name: Build sdist | |
| id: sdist | |
| run: | | |
| uv pip install build twine | |
| python -m build --sdist | |
| twine check dist/* | |
| sdists=(dist/*.tar.gz) | |
| echo "sdist_name=$(basename "${sdists[0]}")" >> "$GITHUB_OUTPUT" | |
| - name: Upload sdist artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-sdist | |
| path: dist/*.tar.gz | |
| if-no-files-found: error | |
| build_wheels: | |
| needs: build_sdist | |
| name: Build apache-tvm-ffi ${{ inputs.version || '0.1.12' }} ${{ matrix.python }}-manylinux_riscv64 | |
| runs-on: ubuntu-24.04-riscv | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Wheels are abi3 (pyproject sets wheel.py-api = "cp312"), so the single | |
| # cp312 build is loadable on 3.12/3.13/3.14; only the free-threaded | |
| # cp314t build needs its own wheel. This is upstream's cibuildwheel | |
| # `build` list (cp38..cp312 + cp314t) collapsed to the two that differ. | |
| python: [cp312, cp314t] | |
| steps: | |
| - name: Download sdist | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-sdist | |
| path: dist/ | |
| - name: Build wheels | |
| uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 | |
| with: | |
| # cibuildwheel accepts an sdist tarball directly: it extracts it and | |
| # builds from the self-contained tree (no submodules/git needed here). | |
| package-dir: dist/${{ needs.build_sdist.outputs.sdist_name }} | |
| env: | |
| CIBW_BUILD: ${{ matrix.python }}-* | |
| # pyproject pins [tool.cibuildwheel.linux] archs to x86_64+aarch64; | |
| # override so this native riscv runner builds the riscv64 wheel. | |
| CIBW_ARCHS: riscv64 | |
| CIBW_SKIP: '*-musllinux_*' | |
| CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} | |
| # The build frontend (build[uv]), test-command | |
| # (pytest {package}/tests/python) and test-groups (["test"] pulls in | |
| # torch/numpy/ml_dtypes/pytest/ninja) are all inherited from the sdist's | |
| # pyproject.toml, so we build and test exactly the way upstream does. | |
| # | |
| # CIBW_ENVIRONMENT applies to BOTH the build and test phases. We only | |
| # point pip/uv at our registry here (needed so test deps resolve, and | |
| # harmless at build time). We deliberately do NOT set ONLY_BINARY here: | |
| # the build backend needs cython>=3.0, which has no riscv64 wheel on | |
| # any index and must be compiled from its sdist inside the container. | |
| CIBW_ENVIRONMENT: >- | |
| PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | |
| UV_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | |
| UV_INDEX_STRATEGY=unsafe-best-match | |
| # Test phase only: force wheels-only so a missing riscv64 wheel for a | |
| # heavy test dep (torch/numpy/ml_dtypes) fails fast instead of silently | |
| # kicking off a multi-hour source build under the runner. GPU-only tests | |
| # self-skip via torch.cuda.is_available(). | |
| CIBW_TEST_ENVIRONMENT: >- | |
| PIP_ONLY_BINARY=:all: | |
| UV_ONLY_BINARY=:all: | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-${{ matrix.python }}-manylinux_riscv64 | |
| path: ./wheelhouse/*.whl | |
| if-no-files-found: error | |
| publish: | |
| name: Publish apache-tvm-ffi ${{ inputs.version || '0.1.12' }} to GitLab | |
| needs: [build_wheels] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Publish wheels and open docs PR | |
| uses: riseproject-dev/python-wheels/actions/publish-wheels@main | |
| with: | |
| artifact-pattern: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-*-manylinux_riscv64 | |
| gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }} | |
| gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }} | |
| gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }} | |
| gh-token: ${{ secrets.GITHUB_TOKEN }} |