Files
ferro-ta/.github/workflows/ci-python.yml
Pratik Bhadane 0ee5f246ed ci: add RUSTFLAGS environment variable to CI workflows
- Introduced RUSTFLAGS environment variable in Python, Rust, and WASM CI workflows to override target-cpu settings from .cargo/config.toml, ensuring consistent build configurations across different environments.
2026-04-02 17:05:14 +05:30

175 lines
6.4 KiB
YAML

name: CI Python
on:
workflow_call:
permissions:
contents: read
jobs:
# -------------------------------------------------------------------------
# Lint — no Rust, no wheel build, very fast
# -------------------------------------------------------------------------
lint:
name: Lint (ruff)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- run: pip install uv
- run: uv run --with ruff ruff check python/ tests/
- run: uv run --with ruff ruff format --check python/ tests/
# -------------------------------------------------------------------------
# Type checking — needs wheel; build once with cache
# -------------------------------------------------------------------------
typecheck:
name: Type checking (mypy + pyright)
runs-on: ubuntu-latest
env:
RUSTFLAGS: "" # override target-cpu=native from .cargo/config.toml
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- uses: Swatinem/rust-cache@v2
- run: pip install maturin numpy
- run: maturin build --release --out dist && pip install dist/*.whl
- run: pip install uv
- run: uv run --with mypy --with numpy python -m mypy python/ferro_ta --ignore-missing-imports --no-error-summary
- run: uv run --with pyright python -m pyright python/ferro_ta
# -------------------------------------------------------------------------
# Build wheel artifact (once per run, reused by all test matrix entries)
# -------------------------------------------------------------------------
build-wheel:
name: Build wheel (ubuntu / Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
env:
RUSTFLAGS: "" # override target-cpu=native from .cargo/config.toml
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: "wheel-${{ matrix.python-version }}"
- run: pip install maturin numpy
- run: maturin build --release --out dist
- uses: actions/upload-artifact@v7
with:
name: wheel-${{ matrix.python-version }}
path: dist/*.whl
# -------------------------------------------------------------------------
# Test matrix — downloads pre-built wheel, no Rust compilation
# -------------------------------------------------------------------------
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
needs: build-wheel
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: actions/download-artifact@v8
with:
name: wheel-${{ matrix.python-version }}
path: dist
- name: Install wheel + test deps
run: |
pip install dist/*.whl
pip install pytest pytest-cov pandas polars hypothesis pyyaml mcp scipy
- name: Run tests with coverage
run: pytest tests/unit/ tests/integration/ -v --cov=ferro_ta --cov-report=xml --cov-report=term-missing --cov-fail-under=65
- name: Check API manifest is current
if: matrix.python-version == '3.12'
run: python scripts/check_api_manifest.py
- uses: actions/upload-artifact@v7
if: matrix.python-version == '3.12'
with:
name: coverage-python-${{ matrix.python-version }}
path: coverage.xml
# -------------------------------------------------------------------------
# Benchmark vs TA-Lib (downloads wheel from build-wheel job)
# -------------------------------------------------------------------------
benchmark-vs-talib:
name: Benchmark vs TA-Lib
runs-on: ubuntu-latest
needs: build-wheel
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: actions/download-artifact@v8
with:
name: wheel-3.12
path: dist
- name: Install TA-Lib C library
run: |
sudo apt-get update
sudo apt-get install -y build-essential curl
curl -sL https://sourceforge.net/projects/ta-lib/files/ta-lib/0.4.0/ta-lib-0.4.0-src.tar.gz/download -o ta-lib-0.4.0-src.tar.gz
tar -xzf ta-lib-0.4.0-src.tar.gz
cd ta-lib && ./configure --prefix=/usr && make && sudo make install && sudo ldconfig
- run: pip install dist/*.whl numpy ta-lib
- run: python benchmarks/bench_vs_talib.py --sizes 10000 100000 --json benchmark_vs_talib.json
- run: python3 benchmarks/check_vs_talib_regression.py --input benchmark_vs_talib.json
- uses: actions/upload-artifact@v7
with:
name: benchmark-vs-talib
path: benchmark_vs_talib.json
# -------------------------------------------------------------------------
# Performance smoke (downloads wheel from build-wheel job)
# -------------------------------------------------------------------------
perf-smoke:
name: Performance smoke and contracts
runs-on: ubuntu-latest
needs: build-wheel
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: actions/download-artifact@v8
with:
name: wheel-3.12
path: dist
- run: pip install dist/*.whl numpy pytest
- run: |
python benchmarks/run_perf_contract.py \
--output-dir perf-contract \
--skip-talib \
--skip-simd \
--batch-samples 20000 \
--batch-series 32 \
--streaming-bars 20000 \
--price-bars 20000 \
--iv-bars 50000
- run: python benchmarks/check_hotspot_regression.py --input perf-contract/runtime_hotspots.json
- uses: actions/upload-artifact@v7
with:
name: perf-contract
path: perf-contract/