4caaa1db97bc1b9ca865f982eb176babf4c7ae59
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
91e05e3c26 |
C ABI hub crate (bindings/c) foundation (#222)
## What
Introduces `wickra-c` — a `cdylib` + `staticlib` that exposes the Rust core over a **C ABI**. This is the hub every C-capable language (C, C++, Go, C#, Java, R) links against, instead of re-wiring each indicator natively. The native Python/Node/WASM bindings are untouched; this is purely additive, for ecosystems without first-class Rust tooling.
## Scope (foundation slice)
This PR deliberately validates the **whole pipeline end to end with one indicator (SMA)** before scaling to all 514, so the CI / cross-OS / header-drift mechanics are proven green first.
- Opaque `*mut T` handles; `wickra_<ind>_{new,update,batch,reset,free}`.
- NaN sentinel for warmup / NULL handles; caller-owned batch buffers; every function NULL-safe.
- cbindgen generates and commits `bindings/c/include/wickra.h` with opaque handle typedefs.
- A C smoke example (`examples/c/`) links the header + compiled library and runs (CMake + ctest).
- A `c-abi` CI job builds the library and runs the smoke test on **Linux, macOS and Windows**, plus a header drift check on Linux.
## Notes
- The per-indicator FFI blocks are plain `#[no_mangle]` functions, **not** a macro: cbindgen cannot see macro-generated functions on stable Rust (macro expansion needs nightly), so the blocks are written literally and will be generated mechanically by the ScriptHelpers `capi` wrapper in a follow-up (same model as the committed-but-generated Node `index.js`).
- `bindings/c` cannot inherit the workspace `forbid(unsafe_code)` lint (the C boundary needs raw pointers), so it mirrors every workspace lint and only relaxes `unsafe_code`. The Rust core stays `unsafe`-forbidden.
## Follow-ups (separate PRs)
- ScriptHelpers `capi` generator + wire the scalar family (~235).
- Hand-written blocks for multi-output / custom-input / bars (~279).
- Docs consistency wave (README / docs / webpage: Python·Node·WASM·Rust → +C).
- Release wiring (native-lib matrix + header/lib GH-release assets) — gated.
|
||
|
|
5b23b36261 |
ci: pin CI dependency installs by hash (Scorecard PinnedDependencies) (#114)
* ci: use npm ci instead of npm install for reproducible installs Pins the node binding dependency install to the committed package-lock.json integrity hashes (OpenSSF Scorecard PinnedDependencies). npm ci installs strictly from the lockfile; npm install could resolve newer patch versions. Covers ci.yml and both release.yml node steps. * ci: hash-pin Python dev tooling in ci.yml (Scorecard #19) Replaces the unpinned 'pip install maturin pytest numpy hypothesis' with a hash-locked '--require-hashes -r' install (OpenSSF Scorecard PinnedDependencies). Two lock files are needed because numpy publishes no single release with wheels for both cp39 and cp313 (<=2.0.2 has cp39 only, >=2.1 drops cp39): ci-dev-py39.txt numpy 2.0.2 (Python 3.9, + tomli/exceptiongroup) ci-dev-py3.txt numpy 2.4.6 (Python 3.10+) The step selects the file by matrix.python-version under shell: bash. Both are generated from ci-dev.in via uv (scripts/update-lockfiles.sh, added next). * ci: hash-pin Python deps in bench.yml (Scorecard #16) Replaces the unpinned 'pip install maturin numpy pandas talipp finta' with a hash-locked '--require-hashes -r .github/requirements/bench.txt' install. bench.yml runs on a single Python version (3.11), so one lock file (generated from bench.in via uv) is sufficient. * build: add scripts/update-lockfiles.sh to regenerate all lockfiles One command refreshes every committed lockfile across languages: Cargo.lock and fuzz/Cargo.lock (cargo update), the Node binding package-lock.json, and the hash-pinned Python requirements under .github/requirements/ (uv pip compile --generate-hashes). Uses uv for the Python locks so a target Python version's hashed transitive closure can be resolved without that interpreter installed (needed for the numpy cp39/cp313 split); bootstraps uv if absent. .gitattributes pins *.sh to LF so the script stays runnable on Linux/macOS. * ci: split ci-dev requirements per Python version + Dependabot rehash Splits the single ci-dev.in into ci-dev-py39.in (numpy <2.1, the last series with cp39 wheels) and ci-dev-py3.in (3.10+), giving a 1:1 .in->.txt layout. The cap keeps Python 3.9 permanently installable and stops Dependabot from proposing 3.9-breaking numpy bumps. Adds a Dependabot pip entry on /.github/requirements so the hash-locked tooling is kept current automatically; the canonical manual refresh stays scripts/update-lockfiles.sh. Only the '# via -r' provenance lines in the .txt change; no package versions or hashes move. * ci: cache pip and npm downloads in the PR-loop jobs Adds setup-python cache: pip (ci.yml python matrix + bench.yml, keyed on the hash-locked requirements) and setup-node cache: npm (ci.yml node job, keyed on bindings/node/package-lock.json), on both the primary and retry setup steps. Scoped to jobs that actually install dependencies; the examples-smoke and clippy-bindings jobs install nothing and are left uncached. release.yml is intentionally left out: it runs only on tag push (not the PR loop) and is the publish-critical path, so no caching is added there. * docs: document hash-pinned requirements and update-lockfiles.sh Updates the lockfile-policy table: the bindings/python row no longer claims CI installs tooling unpinned, and a new .github/requirements row documents the hash-locked CI/bench tooling and the per-Python-version ci-dev split. Adds a paragraph pointing contributors at scripts/update-lockfiles.sh (uv-based, self-bootstrapping) as the canonical lockfile refresh. * docs: changelog entry for hash-pinned CI dependency installs |