71b6343e92
Refresh the benchmark and performance surface across the repo. This updates the benchmark wrappers and helper scripts, regenerates the checked-in benchmark and perf-contract artifacts, and folds in the related roadmap, compatibility, and example notebook changes that belong with this performance-focused pass. Harden the Python CI and local pre-push flow so the same checks pass reliably in both places. The workflow and pre-push script now use module-safe uv typecheck invocations, the Python test environment installs the optional MCP dependency needed by the MCP server tests, and one-off root benchmark outputs are ignored to keep the repo clean. Align local tooling with the current project configuration by updating the Ruff pre-commit hook, tightening the API typing and MCP server helpers, and refreshing the lockfile to pick up the audited PyJWT fix while preserving the rest of the staged source changes.
173 lines
4.9 KiB
YAML
173 lines
4.9 KiB
YAML
name: CI Python
|
|
|
|
on:
|
|
workflow_call:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
lint:
|
|
name: Lint (ruff)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Python 3.12
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install uv
|
|
run: pip install uv
|
|
|
|
- name: Run ruff check via uv
|
|
run: uv run --with ruff ruff check python/ tests/
|
|
- name: Run ruff format check via uv
|
|
run: uv run --with ruff ruff format --check python/ tests/
|
|
|
|
typecheck:
|
|
name: Type checking (mypy + pyright)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Python 3.12
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install uv
|
|
run: pip install uv
|
|
|
|
- name: Run mypy on ferro_ta via uv
|
|
run: uv run --with mypy --with numpy python -m mypy python/ferro_ta --ignore-missing-imports --no-error-summary
|
|
|
|
- name: Run pyright on ferro_ta via uv
|
|
run: uv run --with pyright python -m pyright python/ferro_ta
|
|
|
|
test:
|
|
name: Test (ubuntu-latest / Python ${{ matrix.python-version }})
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Python ${{ matrix.python-version }}
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
|
|
- name: Install maturin and test dependencies
|
|
run: |
|
|
pip install maturin numpy pytest pytest-cov pandas polars hypothesis pyyaml mcp
|
|
|
|
- name: Build and install ferro_ta (dev mode)
|
|
run: |
|
|
maturin build --release --out dist
|
|
pip install dist/*.whl
|
|
|
|
- name: Run unit 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
|
|
|
|
- name: Upload coverage report
|
|
uses: actions/upload-artifact@v7
|
|
if: matrix.python-version == '3.12'
|
|
with:
|
|
name: coverage-python-${{ matrix.python-version }}
|
|
path: coverage.xml
|
|
|
|
benchmark-vs-talib:
|
|
name: Benchmark vs TA-Lib
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Python 3.12
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install TA-Lib C library (Ubuntu)
|
|
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
|
|
|
|
- name: Install maturin and ta-lib Python package
|
|
run: |
|
|
pip install maturin numpy
|
|
pip install ta-lib
|
|
|
|
- name: Build and install ferro_ta
|
|
run: |
|
|
maturin build --release --out dist
|
|
pip install dist/*.whl
|
|
|
|
- name: Run benchmark comparison
|
|
run: |
|
|
python benchmarks/bench_vs_talib.py --sizes 10000 100000 --json benchmark_vs_talib.json
|
|
|
|
- name: Enforce benchmark regression policy
|
|
run: python3 benchmarks/check_vs_talib_regression.py --input benchmark_vs_talib.json
|
|
|
|
- name: Upload benchmark results
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: benchmark-vs-talib
|
|
path: benchmark_vs_talib.json
|
|
|
|
perf-smoke:
|
|
name: Performance smoke and contracts
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Python 3.12
|
|
uses: actions/setup-python@v6
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install maturin and perf dependencies
|
|
run: |
|
|
pip install maturin numpy pytest
|
|
|
|
- name: Build and install ferro_ta
|
|
run: |
|
|
maturin build --release --out dist
|
|
pip install dist/*.whl
|
|
|
|
- name: Generate reproducible perf artifacts
|
|
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
|
|
|
|
- name: Enforce hotspot regression policy
|
|
run: python benchmarks/check_hotspot_regression.py --input perf-contract/runtime_hotspots.json
|
|
|
|
- name: Upload perf artifacts
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: perf-contract
|
|
path: perf-contract/
|