06c536bcb7
- Updated Python CI to streamline linting, type checking, and testing processes, including the addition of a wheel build job. - Refactored Rust CI to utilize pre-built actions for cargo-deny and cargo-audit, improving dependency checks. - Optimized WASM CI by consolidating build and test steps, and ensuring proper artifact uploads for both Node.js and web packages. - Added token authentication for GitHub actions in the release workflow to enhance security.
171 lines
6.2 KiB
YAML
171 lines
6.2 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
|
|
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
|
|
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/
|