Skip to content
Open
Show file tree
Hide file tree
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
252 changes: 252 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
test:
name: Test ${{ matrix.os }} (${{ matrix.arch }}) - XGBoost ${{ matrix.xgboost_version }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
# macOS ARM64 (M1/M2/M3) - Test multiple versions
- os: macos
arch: arm64
runner: macos-14
xgboost_version: "3.1.1"
- os: macos
arch: arm64
runner: macos-14
xgboost_version: "3.0.5"
- os: macos
arch: arm64
runner: macos-14
xgboost_version: "2.1.4"

# macOS x86_64 (Intel)
- os: macos
arch: x86_64
runner: macos-15-intel
xgboost_version: "3.1.1"

# Linux x86_64 - Test multiple versions including thread-safety boundary
- os: linux
arch: x86_64
runner: ubuntu-latest
xgboost_version: "3.1.1"
- os: linux
arch: x86_64
runner: ubuntu-latest
xgboost_version: "1.7.6"
- os: linux
arch: x86_64
runner: ubuntu-latest
xgboost_version: "1.4.2" # First thread-safe version

# Linux ARM64
- os: linux
arch: arm64
runner: ubuntu-latest
xgboost_version: "3.1.1"

# Windows x86_64 - Disabled: Python wheels don't include import libraries (.lib)
# needed for MSVC linking. Enable when we add Windows-specific build support.
# - os: windows
# arch: x86_64
# runner: windows-latest
# xgboost_version: "3.1.1"

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-${{ matrix.arch }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-cargo-registry-

- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-${{ matrix.arch }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-cargo-index-

- name: Cache cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-${{ matrix.arch }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-cargo-build-target-

- name: Install system dependencies (Linux)
if: matrix.os == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev

- name: Install system dependencies (macOS)
if: matrix.os == 'macos'
run: |
brew install libomp

- name: Check build (no features)
env:
XGBOOST_VERSION: ${{ matrix.xgboost_version }}
run: cargo check --verbose

- name: Build (no features)
env:
XGBOOST_VERSION: ${{ matrix.xgboost_version }}
run: cargo build --verbose

- name: Run tests (no features)
env:
XGBOOST_VERSION: ${{ matrix.xgboost_version }}
run: cargo test --verbose

- name: Build examples
env:
XGBOOST_VERSION: ${{ matrix.xgboost_version }}
run: |
cargo build --example basic_usage --verbose
cargo build --example advanced_usage --verbose

- name: Verify library architecture (macOS)
if: matrix.os == 'macos'
run: |
echo "Checking library architecture..."
file target/debug/libxgboost.dylib
lipo -info target/debug/libxgboost.dylib || otool -L target/debug/libxgboost.dylib

- name: Verify library architecture (Linux)
if: matrix.os == 'linux'
run: |
echo "Checking library architecture..."
file target/debug/libxgboost.so
readelf -h target/debug/libxgboost.so | grep Machine

- name: Verify library exists (Windows)
if: matrix.os == 'windows'
run: |
echo "Checking library exists..."
Get-Item target/debug/xgboost.dll

- name: Verify thread safety detection
env:
XGBOOST_VERSION: ${{ matrix.xgboost_version }}
run: |
echo "XGBoost version: ${{ matrix.xgboost_version }}"
cargo build --verbose 2>&1 | grep "thread-safe" || echo "No thread-safe message found"

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev

- name: Run clippy (no features)
run: cargo clippy -- -D warnings

fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Check formatting
run: cargo fmt -- --check

# Test checksum verification
security-checksums:
name: Verify SHA256 checksums
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev

- name: Test checksum verification for XGBoost 3.1.1
env:
XGBOOST_VERSION: "3.1.1"
run: |
cargo check --verbose 2>&1 | tee build.log
grep "✓ Verified SHA256" build.log
echo "Checksum verification working for 3.1.1"

- name: Test checksum verification for XGBoost 2.1.4
env:
XGBOOST_VERSION: "2.1.4"
run: |
cargo clean
cargo check --verbose 2>&1 | tee build.log
grep "✓ Verified SHA256" build.log
echo "Checksum verification working for 2.1.4"

# Test caching behavior
caching-test:
name: Test wheel caching
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev

- name: First build (should download)
env:
XGBOOST_VERSION: "3.1.1"
run: |
cargo check --verbose 2>&1 | tee build1.log
grep "Downloading XGBoost wheel" build1.log || true

- name: Second build (should use cache)
env:
XGBOOST_VERSION: "3.1.1"
run: |
touch src/lib.rs
cargo check --verbose 2>&1 | tee build2.log
grep "Using cached XGBoost library" build2.log
echo "Caching is working correctly"
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ categories = ["science"]
readme = "README.md"
rust-version = "1.70"

[dependencies]
polars = { version = "0.45", optional = true, default-features = false, features = ["dtype-full"] }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify the Polars version for currency and security advisories.

Ensure that version 0.45 is current and has no known vulnerabilities.


🌐 Web query:

What is the latest version of the Polars Rust crate and are there any security advisories for version 0.45?

💡 Result:

Latest Polars (Rust) release: 0.52.0 (crate documentation / release metadata). [1]

Security advisories for 0.45:

  • There is no RustSec/GitHub advisory that lists polars itself (v0.45) as directly vulnerable. However, Polars v0.45 may pull transitive dependencies that have RustSec advisories (examples include fast-float RUSTSEC-2024-0379 and array-init-cursor RUSTSEC-2025-0019). You should check your dependency tree (cargo tree) and RustSec/GitHub Advisory DB for fixes or patched versions. [2][3]

Sources:

  1. Polars crate docs/release metadata (shows v0.52.0). [1]
  2. RustSec / advisory reporting for fast-float (RUSTSEC-2024-0379) — affects projects that depend on fast-float, including Polars. [2]
  3. RustSec advisory reporting for array-init-cursor (RUSTSEC-2025-0019) — reported transitive issue referenced by Polars. [3]

If you want, I can (a) confirm exactly which advisories affect your project by analyzing your Cargo.lock/Cargo.toml, or (b) fetch the latest crates.io release page and RustSec entries now.


I'll verify whether the transitive vulnerabilities actually affect this project's dependency tree.

[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Check if Cargo.lock exists and search for vulnerable dependencies
if [ -f "Cargo.lock" ]; then
  echo "=== Checking Cargo.lock for transitive dependencies ==="
  grep -A 2 "name = \"fast-float\"" Cargo.lock || echo "fast-float not found in Cargo.lock"
  echo ""
  grep -A 2 "name = \"array-init-cursor\"" Cargo.lock || echo "array-init-cursor not found in Cargo.lock"
else
  echo "Cargo.lock not found"
fi

# Also check Cargo.toml for polars dependency details
echo ""
echo "=== Polars dependency in Cargo.toml ==="
grep -A 2 "polars" Cargo.toml | head -20

Length of output: 223


Upgrade Polars to version 0.52.0.

Version 0.45 is outdated; the latest Polars release is 0.52.0. Additionally, Polars v0.45 may pull transitive dependencies with known vulnerabilities, including fast-float (RUSTSEC-2024-0379) and array-init-cursor (RUSTSEC-2025-0019). Update Cargo.toml to use version = "0.52.0" to address currency and reduce transitive security risk.

🤖 Prompt for AI Agents
In Cargo.toml around line 13, the polars dependency is pinned to version "0.45";
update the version to "0.52.0" by changing the version string to version =
"0.52.0" while keeping the existing optional, default-features, and features
settings intact, then run cargo update -p polars (or cargo update) and
rebuild/tests to ensure compatibility and resolve any required downstream
adjustments.


[dev-dependencies]
criterion = "0.5"

[build-dependencies]
bindgen = "0.72.0"
ureq = "2.0"
Expand All @@ -18,6 +24,7 @@ sha2 = "0.10"
[features]
default = []
gpu = []
polars = ["dep:polars"]

[[example]]
name = "basic_usage"
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Rust bindings for XGBoost, a gradient boosting library for machine learning.
## Features

- **Automatic Binary Download**: Downloads XGBoost binaries at build time from PyPI wheels
- **Cross-Platform**: Supports Linux (x86_64, aarch64), macOS (x86_64, arm64), and Windows (x86_64)
- **Cross-Platform**: Supports Linux (x86_64, aarch64) and macOS (x86_64, arm64)
- **Version Control**: Specify XGBoost version via `XGBOOST_VERSION` environment variable
- **Version-Aware Thread Safety**: Automatically enables `Send + Sync` for XGBoost ≥ 1.4
- **Easy to Use**: Simple, safe Rust API wrapping the XGBoost C API
Expand Down Expand Up @@ -33,6 +33,11 @@ xgboost-rust = "0.1.0"
**Linux**:
- Optional: `patchelf` (for setting SONAME, but not required)

**Windows**:
- ⚠️ **Not currently supported via automatic download**
- Python wheels don't include import libraries (`.lib`) needed for MSVC linking
- Alternative: Build XGBoost from source or use WSL/MinGW

## Usage

### Basic Example
Expand Down
Loading