ci: publish wheels as immutable GitHub releases #14
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 | |
| --- | |
| # Based on upstream's macOS wheel job, the only one that drives cibuildwheel and | |
| # builds libxgboost from source: | |
| # https://github.com/dmlc/xgboost/blob/v3.4.1/ops/pipeline/build-python-wheels-macos.sh | |
| # The test invocation is upstream's `cpu-arm64` suite: | |
| # https://github.com/dmlc/xgboost/blob/v3.4.1/ops/pipeline/test-python-wheel.sh | |
| name: Build xgboost wheels (riscv64) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'xgboost version to build (git tag without leading v, e.g. 3.4.1)' | |
| required: true | |
| default: '3.4.1' | |
| pull_request: | |
| paths: | |
| - '.github/workflows/build-xgboost.yml' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.version || '3.4.1' }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read # to fetch code (actions/checkout) | |
| env: | |
| XGBOOST_VERSION: ${{ inputs.version || '3.4.1' }} | |
| # Pinned explicitly so the gpl_sources job pulls the same image the wheel's | |
| # vendored libgomp came from. | |
| MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 | |
| jobs: | |
| setup: | |
| uses: $/.github/workflows/_setup.yml | |
| build_wheels: | |
| needs: [setup] | |
| name: Build xgboost ${{ inputs.version || '3.4.1' }} py3-none-manylinux_riscv64 | |
| runs-on: ubuntu-24.04-riscv | |
| timeout-minutes: 1440 | |
| steps: | |
| - name: Checkout xgboost v${{ env.XGBOOST_VERSION }} | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| repository: dmlc/xgboost | |
| ref: v${{ env.XGBOOST_VERSION }} | |
| submodules: true | |
| persist-credentials: false | |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| with: | |
| python-version: '3.12' | |
| activate-environment: true | |
| enable-cache: false | |
| # The committed pyproject.toml is the CUDA variant and pulls in | |
| # nvidia-nccl-cu13 on Linux, which does not exist for riscv64. Regenerate | |
| # it without that dependency, as upstream already does for every platform | |
| # it ships a non-CUDA `xgboost` wheel for. | |
| - name: Select the NCCL-free xgboost variant | |
| run: | | |
| uv pip install packaging | |
| python ops/script/pypi_variants.py --use-suffix=na --require-nccl-dep=na | |
| - name: Build wheel | |
| uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 | |
| with: | |
| package-dir: python-package | |
| output-dir: wheelhouse/ | |
| # wheel.py-api = "py3", so one build serves every interpreter. | |
| only: cp312-manylinux_riscv64 | |
| env: | |
| CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} | |
| CIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | |
| # Every scientific dependency resolves to our registry's riscv64 wheels | |
| # rather than to a newer sdist on public PyPI. scikit-learn is in the | |
| # list now that we publish it; without it pip compiled it in-container, | |
| # which the whole suite needs because xgboost.testing importorskips | |
| # sklearn.datasets at module level. | |
| CIBW_TEST_ENVIRONMENT: PIP_ONLY_BINARY=numpy,scipy,pandas,scikit-learn | |
| CIBW_TEST_REQUIRES: pytest hypothesis joblib pandas scikit-learn | |
| CIBW_TEST_SOURCES: tests/pytest.ini tests/python demo/data | |
| CIBW_TEST_COMMAND: >- | |
| pytest -v -s -rxXs --durations=0 | |
| tests/python/test_basic.py tests/python/test_basic_models.py | |
| tests/python/test_model_compatibility.py | |
| # Mirrors the libgomp check in ops/pipeline/build-python-wheels-cpu.sh. | |
| - name: Check the wheel carries libxgboost and a vendored libgomp | |
| run: | | |
| python3 - wheelhouse/*.whl <<'EOF' | |
| import sys, zipfile | |
| names = zipfile.ZipFile(sys.argv[1]).namelist() | |
| for want in ("xgboost/lib/libxgboost.so", "libgomp"): | |
| if not any(want in n for n in names): | |
| raise SystemExit(f"error: {want} missing from {sys.argv[1]}") | |
| print("\n".join(n for n in names if ".so" in n)) | |
| EOF | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: xgboost-${{ env.XGBOOST_VERSION }}-py3-none-manylinux_riscv64 | |
| path: wheelhouse/*.whl | |
| if-no-files-found: error | |
| gpl_sources: | |
| needs: [setup] | |
| name: Collect GPL sources (gcc) for xgboost ${{ inputs.version || '3.4.1' }} | |
| runs-on: ubuntu-24.04-riscv | |
| steps: | |
| # auditwheel vendors the image's libgomp.so.1 into the wheel. | |
| - name: Collect gcc source RPM from manylinux_riscv64 | |
| uses: riseproject-dev/python-wheels/actions/collect-gpl-sources@main | |
| with: | |
| image: ${{ env.MANYLINUX_RISCV64_IMAGE }} | |
| packages: gcc | |
| output: gpl-sources.tar | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: xgboost-${{ env.XGBOOST_VERSION }}-gpl-sources | |
| path: gpl-sources.tar | |
| if-no-files-found: error | |
| publish: | |
| name: Publish xgboost ${{ inputs.version || '3.4.1' }} | |
| needs: [setup, build_wheels, gpl_sources] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| uses: $/.github/workflows/_publish_wheel.yml | |
| with: | |
| artifact-pattern: xgboost-${{ inputs.version || '3.4.1' }}-*-manylinux_riscv64 | |
| gpl-sources-artifact: xgboost-${{ inputs.version || '3.4.1' }}-gpl-sources | |
| gpl-sources-description: gcc |