name: CI on: push: branches: [main] pull_request: branches: [main] env: CARGO_TERM_COLOR: always RUSTFLAGS: "-D warnings" jobs: rust: name: Rust ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 with: components: rustfmt, clippy - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Format check run: cargo fmt --all -- --check - name: Clippy (workspace, all targets) run: cargo clippy -p wickra-core -p wickra -p wickra-data -p wickra-wasm --all-targets -- -D warnings - name: Build run: cargo build -p wickra-core -p wickra -p wickra-data --verbose - name: Tests (default features) run: cargo test -p wickra-core -p wickra -p wickra-data --verbose - name: Tests (live-binance feature) run: cargo test -p wickra-data --features live-binance --verbose - name: Compile benches (smoke) run: cargo build -p wickra --benches --verbose - name: Compile examples run: | cargo build -p wickra --example backtest cargo build -p wickra-data --example live_binance --features live-binance # Verify the crates still build and test on their declared minimum supported # Rust version. The workspace pins rust-version = "1.75"; bindings/node needs # 1.77 because napi-build emits `cargo::` directives. Without this job an # accidental use of a newer API would only surface for downstream users. msrv: name: ${{ matrix.name }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - name: MSRV workspace (Rust 1.75) toolchain: "1.75" packages: "-p wickra-core -p wickra -p wickra-data" - name: MSRV node binding (Rust 1.77) toolchain: "1.77" packages: "-p wickra-node" steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust ${{ matrix.toolchain }} uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 with: toolchain: ${{ matrix.toolchain }} - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Build on MSRV run: cargo build ${{ matrix.packages }} --verbose - name: Test on MSRV run: cargo test ${{ matrix.packages }} --verbose # Code coverage for the pure-Rust crates, uploaded to Codecov. coverage: name: Coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 with: components: llvm-tools-preview - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Install cargo-llvm-cov uses: taiki-e/install-action@e0eafa9a0d485c37f97c0f7beb930a58a2facbac # v2.79.4 with: tool: cargo-llvm-cov - name: Generate coverage (lcov) run: > cargo llvm-cov -p wickra-core -p wickra -p wickra-data --features wickra-data/live-binance --lcov --output-path lcov.info - name: Upload to Codecov uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5.5.4 with: files: lcov.info fail_ci_if_error: false env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # Supply-chain audit: security advisories, license policy, banned crates, # and source restrictions. Configured by deny.toml at the repo root. supply-chain: name: Supply-chain (cargo-deny) runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: cargo-deny uses: EmbarkStudios/cargo-deny-action@a531616d8ce3b9177443e48a1159bc945a099823 # v2.0.19 with: command: check python: name: Python ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.9", "3.11", "3.12"] steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: ${{ matrix.python-version }} - name: Install Python dev dependencies run: | python -m pip install --upgrade pip python -m pip install maturin pytest numpy hypothesis - name: Build wheel working-directory: bindings/python run: maturin build --release --out dist - name: Install wheel shell: bash working-directory: bindings/python run: python -m pip install --find-links dist --force-reinstall wickra - name: Run Python tests working-directory: bindings/python run: pytest -v wasm: name: WASM build runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust toolchain (with wasm target) uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 with: targets: wasm32-unknown-unknown - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Install wasm-pack uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa # v0.4.0 - name: Build WASM package run: wasm-pack build bindings/wasm --target web --release --features panic-hook - name: Run WASM tests run: wasm-pack test --node bindings/wasm - name: Verify generated artefacts run: | test -f bindings/wasm/pkg/wickra_wasm.js test -f bindings/wasm/pkg/wickra_wasm_bg.wasm test -f bindings/wasm/pkg/wickra_wasm.d.ts node: name: Node ${{ matrix.node-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] node-version: ["18", "20"] steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 - name: Cache cargo uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Set up Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: ${{ matrix.node-version }} - name: Install Node dependencies working-directory: bindings/node run: npm install - name: Build native module working-directory: bindings/node # --platform puts the target triple into the filename so the loader's # `wickra..node` lookup finds the freshly built binary instead # of falling back to the per-platform npm subpackage (which doesn't # exist yet for win32-x64-msvc). run: npx napi build --platform --release - name: Run Node tests working-directory: bindings/node run: node --test __tests__/ cross-library-bench: name: Cross-library benchmark report runs-on: ubuntu-latest needs: [python] steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27 - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Set up Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.11" - name: Install Python deps + peer libs run: | python -m pip install --upgrade pip python -m pip install maturin numpy pandas talipp finta - name: Build Wickra wheel working-directory: bindings/python run: maturin build --release --out dist - name: Install Wickra wheel working-directory: bindings/python run: python -m pip install --find-links dist --force-reinstall wickra - name: Run cross-library benchmark working-directory: bindings/python run: | python -m benchmarks.compare_libraries --size 20000 --iterations 10 \ --streaming-window 5000 --streaming-iterations 2 \ | tee benchmark.txt - name: Upload report uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: cross-library-bench path: bindings/python/benchmark.txt