Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d04ab8227 | |||
| 7d4ca8c572 | |||
| d31e127ae2 | |||
| ffc80754d8 | |||
| f2b92f89ee | |||
| 350230cd07 | |||
| 71df1798b8 | |||
| 6a86660e30 | |||
| 45c11da4fc | |||
| 2ae8976292 | |||
| 06b05e6c3e | |||
| 4ec10826be | |||
| 13b2ee5231 | |||
| 025d453293 | |||
| c6972dd476 | |||
| 04b10cf915 | |||
| 9368c6655a | |||
| 063a1b5192 | |||
| fdb4c1e86b | |||
| 57e52c67b9 | |||
| 96cd9b3f02 | |||
| 98bb57c868 | |||
| be05eb26d5 | |||
| af59e6eec0 | |||
| 96ae63799d | |||
| d5f5e14dda | |||
| 7e5d394f2a | |||
| ff268500ef | |||
| 929fc17127 |
@@ -23,7 +23,7 @@ runs:
|
|||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
- id: first
|
- id: first
|
||||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27
|
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # zizmor: ignore[impostor-commit] pinned to the stable-tag SHA (2026-03-27); tag-pinned, not a branch commit
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ inputs.toolchain }}
|
toolchain: ${{ inputs.toolchain }}
|
||||||
@@ -39,7 +39,7 @@ runs:
|
|||||||
|
|
||||||
- name: Retry the Rust toolchain install
|
- name: Retry the Rust toolchain install
|
||||||
if: steps.first.outcome == 'failure'
|
if: steps.first.outcome == 'failure'
|
||||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27
|
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # zizmor: ignore[impostor-commit] pinned to the stable-tag SHA (2026-03-27); tag-pinned, not a branch commit
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ inputs.toolchain }}
|
toolchain: ${{ inputs.toolchain }}
|
||||||
components: ${{ inputs.components }}
|
components: ${{ inputs.components }}
|
||||||
|
|||||||
@@ -10,9 +10,22 @@ updates:
|
|||||||
default-days: 7
|
default-days: 7
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "deps(cargo)"
|
prefix: "deps(cargo)"
|
||||||
|
# ureq is intentionally pinned to 2.x. ureq 3 unconditionally pulls
|
||||||
|
# webpki-root-certs (CDLA-Permissive-2.0); the native-tls / OS-trust-store
|
||||||
|
# setup in wickra-data deliberately avoids that licence. Block the major
|
||||||
|
# bump (2.x patch/minor still flow through).
|
||||||
|
ignore:
|
||||||
|
- dependency-name: "ureq"
|
||||||
|
update-types: ["version-update:semver-major"]
|
||||||
groups:
|
groups:
|
||||||
|
# napi-rs (napi / napi-derive / napi-build) is a coordinated major
|
||||||
|
# migration that must move with @napi-rs/cli on the npm side — keep it in
|
||||||
|
# its own PR rather than bundled with unrelated crate bumps.
|
||||||
|
napi:
|
||||||
|
patterns: ["napi", "napi-derive", "napi-build"]
|
||||||
cargo:
|
cargo:
|
||||||
patterns: ["*"]
|
patterns: ["*"]
|
||||||
|
exclude-patterns: ["napi", "napi-derive", "napi-build"]
|
||||||
|
|
||||||
# Node binding npm dependencies.
|
# Node binding npm dependencies.
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
name: Cross-library benchmark report
|
name: Cross-library benchmark report
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
id: setup_python
|
id: setup_python
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
cache: pip
|
cache: pip
|
||||||
@@ -76,7 +76,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Python (retry)
|
- name: Set up Python (retry)
|
||||||
if: steps.setup_python.outcome == 'failure'
|
if: steps.setup_python.outcome == 'failure'
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
cache: pip
|
cache: pip
|
||||||
@@ -122,7 +122,7 @@ jobs:
|
|||||||
name: Rust cross-library benchmark report
|
name: Rust cross-library benchmark report
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|||||||
+145
-56
@@ -34,13 +34,13 @@ jobs:
|
|||||||
rust:
|
rust:
|
||||||
name: Rust ${{ matrix.os }}
|
name: Rust ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -105,9 +105,9 @@ jobs:
|
|||||||
examples-smoke:
|
examples-smoke:
|
||||||
name: Examples (syntax smoke)
|
name: Examples (syntax smoke)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
id: setup_python
|
id: setup_python
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Python (retry)
|
- name: Set up Python (retry)
|
||||||
if: steps.setup_python.outcome == 'failure'
|
if: steps.setup_python.outcome == 'failure'
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -195,9 +195,9 @@ jobs:
|
|||||||
clippy-bindings:
|
clippy-bindings:
|
||||||
name: Clippy bindings
|
name: Clippy bindings
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
id: setup_python
|
id: setup_python
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Python (retry)
|
- name: Set up Python (retry)
|
||||||
if: steps.setup_python.outcome == 'failure'
|
if: steps.setup_python.outcome == 'failure'
|
||||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ jobs:
|
|||||||
msrv:
|
msrv:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -291,7 +291,7 @@ jobs:
|
|||||||
toolchain: "1.88"
|
toolchain: "1.88"
|
||||||
packages: "-p wickra-node"
|
packages: "-p wickra-node"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -328,9 +328,9 @@ jobs:
|
|||||||
coverage:
|
coverage:
|
||||||
name: Coverage
|
name: Coverage
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ jobs:
|
|||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
|
|
||||||
- name: Install cargo-llvm-cov
|
- name: Install cargo-llvm-cov
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: cargo-llvm-cov
|
tool: cargo-llvm-cov
|
||||||
@@ -358,7 +358,7 @@ jobs:
|
|||||||
--lcov --output-path lcov.info
|
--lcov --output-path lcov.info
|
||||||
|
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||||
with:
|
with:
|
||||||
files: lcov.info
|
files: lcov.info
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
@@ -370,9 +370,9 @@ jobs:
|
|||||||
supply-chain:
|
supply-chain:
|
||||||
name: Supply-chain (cargo-deny)
|
name: Supply-chain (cargo-deny)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -389,9 +389,9 @@ jobs:
|
|||||||
fuzz-smoke:
|
fuzz-smoke:
|
||||||
name: Fuzz (smoke)
|
name: Fuzz (smoke)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -415,7 +415,7 @@ jobs:
|
|||||||
# attributes the modern nightly compiler rejects, so the install
|
# attributes the modern nightly compiler rejects, so the install
|
||||||
# never gets off the ground. The prebuilt binary avoids the entire
|
# never gets off the ground. The prebuilt binary avoids the entire
|
||||||
# transitive-dep compile.
|
# transitive-dep compile.
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: cargo-fuzz
|
tool: cargo-fuzz
|
||||||
@@ -443,14 +443,14 @@ jobs:
|
|||||||
python:
|
python:
|
||||||
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
python-version: ["3.9", "3.11", "3.12", "3.13"]
|
python-version: ["3.9", "3.11", "3.12", "3.13"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -470,7 +470,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
id: setup_python
|
id: setup_python
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache: pip
|
cache: pip
|
||||||
@@ -485,7 +485,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Python (retry)
|
- name: Set up Python (retry)
|
||||||
if: steps.setup_python.outcome == 'failure'
|
if: steps.setup_python.outcome == 'failure'
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache: pip
|
cache: pip
|
||||||
@@ -525,9 +525,9 @@ jobs:
|
|||||||
wasm:
|
wasm:
|
||||||
name: WASM build
|
name: WASM build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -549,7 +549,7 @@ jobs:
|
|||||||
# same taiki-e prebuilt-binary installer we already use for
|
# same taiki-e prebuilt-binary installer we already use for
|
||||||
# cargo-llvm-cov and cargo-fuzz; it tracks the latest wasm-pack
|
# cargo-llvm-cov and cargo-fuzz; it tracks the latest wasm-pack
|
||||||
# release, which has `--features` as a top-level flag (since 0.12).
|
# release, which has `--features` as a top-level flag (since 0.12).
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
@@ -575,14 +575,14 @@ jobs:
|
|||||||
node:
|
node:
|
||||||
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
|
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
node-version: ["22", "24"]
|
node-version: ["22", "24"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -622,9 +622,17 @@ jobs:
|
|||||||
cache: npm
|
cache: npm
|
||||||
cache-dependency-path: bindings/node/package-lock.json
|
cache-dependency-path: bindings/node/package-lock.json
|
||||||
|
|
||||||
|
# npm's own fetch-retry (npm_config_fetch_retries) rides out per-request
|
||||||
|
# blips; wrap the whole `npm ci` once more so a longer registry hiccup
|
||||||
|
# retries the install instead of failing the job.
|
||||||
- name: Install Node dependencies
|
- name: Install Node dependencies
|
||||||
working-directory: bindings/node
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
run: npm ci
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
command: cd bindings/node && npm ci
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Build native module
|
- name: Build native module
|
||||||
working-directory: bindings/node
|
working-directory: bindings/node
|
||||||
@@ -649,13 +657,13 @@ jobs:
|
|||||||
c-abi:
|
c-abi:
|
||||||
name: C ABI on ${{ matrix.os }}
|
name: C ABI on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -668,7 +676,7 @@ jobs:
|
|||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
|
|
||||||
- name: Install cbindgen
|
- name: Install cbindgen
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: cbindgen
|
tool: cbindgen
|
||||||
@@ -705,13 +713,13 @@ jobs:
|
|||||||
csharp:
|
csharp:
|
||||||
name: C# on ${{ matrix.os }}
|
name: C# on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -723,6 +731,19 @@ jobs:
|
|||||||
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
|
|
||||||
|
# Cache the restored NuGet packages so dotnet test/build resolve from the
|
||||||
|
# local store instead of hitting nuget.org every run. No packages.lock.json
|
||||||
|
# exists, so key on the project files; never block the job on a slow restore.
|
||||||
|
- name: Cache NuGet packages
|
||||||
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||||
|
continue-on-error: true
|
||||||
|
timeout-minutes: 6
|
||||||
|
with:
|
||||||
|
path: ~/.nuget/packages
|
||||||
|
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-nuget-
|
||||||
|
|
||||||
# The binding links against the C ABI hub at runtime; build it first so the
|
# The binding links against the C ABI hub at runtime; build it first so the
|
||||||
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
|
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
|
||||||
# preinstalled on the GitHub runners, so no setup-dotnet step is needed.
|
# preinstalled on the GitHub runners, so no setup-dotnet step is needed.
|
||||||
@@ -732,8 +753,17 @@ jobs:
|
|||||||
- name: .NET info
|
- name: .NET info
|
||||||
run: dotnet --info
|
run: dotnet --info
|
||||||
|
|
||||||
|
# dotnet test restores from nuget.org first; retry so a transient restore
|
||||||
|
# blip retries instead of failing the job (the cached packages above make
|
||||||
|
# the retry cheap).
|
||||||
- name: Test the C# binding
|
- name: Test the C# binding
|
||||||
run: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
|
with:
|
||||||
|
timeout_minutes: 15
|
||||||
|
max_attempts: 2
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
command: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Build the C# examples
|
- name: Build the C# examples
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -756,13 +786,13 @@ jobs:
|
|||||||
go:
|
go:
|
||||||
name: Go on ${{ matrix.os }}
|
name: Go on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -772,7 +802,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
id: setup-go
|
id: setup-go
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
||||||
with:
|
with:
|
||||||
go-version: "stable"
|
go-version: "stable"
|
||||||
cache: false
|
cache: false
|
||||||
@@ -786,7 +816,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Go (retry)
|
- name: Set up Go (retry)
|
||||||
if: steps.setup-go.outcome == 'failure'
|
if: steps.setup-go.outcome == 'failure'
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
||||||
with:
|
with:
|
||||||
go-version: "stable"
|
go-version: "stable"
|
||||||
cache: false
|
cache: false
|
||||||
@@ -879,7 +909,7 @@ jobs:
|
|||||||
r:
|
r:
|
||||||
name: R on ${{ matrix.os }}
|
name: R on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -888,7 +918,7 @@ jobs:
|
|||||||
WICKRA_INCLUDE_DIR: ${{ github.workspace }}/bindings/c/include
|
WICKRA_INCLUDE_DIR: ${{ github.workspace }}/bindings/c/include
|
||||||
WICKRA_LIB_DIR: ${{ github.workspace }}/target/release
|
WICKRA_LIB_DIR: ${{ github.workspace }}/target/release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -907,15 +937,22 @@ jobs:
|
|||||||
run: cargo build -p wickra-c --release
|
run: cargo build -p wickra-c --release
|
||||||
|
|
||||||
- name: Set up R
|
- name: Set up R
|
||||||
uses: r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2
|
uses: r-lib/actions/setup-r@d3c5be51b12e724e68f33216ca3c148b66d5f0b6 # v2
|
||||||
with:
|
with:
|
||||||
r-version: "release"
|
r-version: "release"
|
||||||
use-public-rspm: true
|
use-public-rspm: true
|
||||||
|
|
||||||
# Use the repos configured by setup-r (use-public-rspm) so Linux installs
|
# Install the R dependencies via setup-r-dependencies: it restores a cached
|
||||||
# binary packages — building testthat's deps from source is slow and flaky.
|
# package library (actions/cache) and pulls RSPM *binaries* instead of
|
||||||
- name: Install test dependency
|
# compiling testthat / knitr and their deps from source — the slow, flaky
|
||||||
run: Rscript -e 'install.packages("testthat")'
|
# path that previously blew past the job timeout on the ubuntu runner.
|
||||||
|
- name: Install R dependencies (cached binaries)
|
||||||
|
uses: r-lib/actions/setup-r-dependencies@d3c5be51b12e724e68f33216ca3c148b66d5f0b6 # v2
|
||||||
|
with:
|
||||||
|
working-directory: bindings/r
|
||||||
|
extra-packages: |
|
||||||
|
any::testthat
|
||||||
|
any::knitr
|
||||||
|
|
||||||
- name: Install and test the R binding
|
- name: Install and test the R binding
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -932,14 +969,39 @@ jobs:
|
|||||||
R CMD INSTALL bindings/r
|
R CMD INSTALL bindings/r
|
||||||
Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)'
|
Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)'
|
||||||
|
|
||||||
|
# Full R CMD check, gated on the documentation problems r-universe surfaces
|
||||||
|
# (undocumented exported objects, codoc mismatches) that R CMD INSTALL above
|
||||||
|
# does not catch — exactly what shipped stale to r-universe with the 0.9.3
|
||||||
|
# data layer. Ubuntu-only; these checks are platform-independent. Vignettes
|
||||||
|
# are skipped here (building them needs pandoc and the vignette is exercised
|
||||||
|
# in the next step), so the two --no-build-vignettes warnings are ignored.
|
||||||
|
- name: R CMD check (documentation & consistency, like r-universe)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export WICKRA_INCLUDE_DIR="${WICKRA_INCLUDE_DIR//\\//}"
|
||||||
|
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
|
||||||
|
R CMD build bindings/r --no-build-vignettes --no-manual
|
||||||
|
R CMD check wickra_*.tar.gz --no-manual --no-vignettes --no-tests || true
|
||||||
|
log=$(find . -maxdepth 2 -name 00check.log | head -1)
|
||||||
|
echo "::group::00check.log"; cat "$log"; echo "::endgroup::"
|
||||||
|
problems=$(grep -E '\.\.\. (WARNING|ERROR)' "$log" \
|
||||||
|
| grep -vE "checking (files in .vignettes.|package vignettes)" || true)
|
||||||
|
if [ -n "$problems" ]; then
|
||||||
|
echo "::error::R CMD check found problems (run roxygen2::roxygenise() in bindings/r if the docs are stale):"
|
||||||
|
echo "$problems"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "R CMD check: documentation and consistency clean."
|
||||||
|
|
||||||
- name: Build the vignette code
|
- name: Build the vignette code
|
||||||
shell: bash
|
shell: bash
|
||||||
# The getting-started vignette runs at R CMD check time on r-universe /
|
# The getting-started vignette runs at R CMD check time on r-universe /
|
||||||
# CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R
|
# CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R
|
||||||
# chunks here (knit, no pandoc needed) to catch a broken example before it
|
# chunks here (knit, no pandoc needed) to catch a broken example before it
|
||||||
# reaches the published build.
|
# reaches the published build.
|
||||||
|
# knitr is installed by the cached setup-r-dependencies step above.
|
||||||
run: |
|
run: |
|
||||||
Rscript -e 'install.packages("knitr", repos = Sys.getenv("RSPM", unset = "https://cloud.r-project.org"))'
|
|
||||||
Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")'
|
Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")'
|
||||||
|
|
||||||
- name: Run the offline R examples
|
- name: Run the offline R examples
|
||||||
@@ -961,13 +1023,13 @@ jobs:
|
|||||||
java:
|
java:
|
||||||
name: Java on ${{ matrix.os }}
|
name: Java on ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -990,7 +1052,7 @@ jobs:
|
|||||||
- name: Set up JDK 25
|
- name: Set up JDK 25
|
||||||
id: setup-java
|
id: setup-java
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: "25"
|
java-version: "25"
|
||||||
@@ -1005,7 +1067,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up JDK 25 (retry)
|
- name: Set up JDK 25 (retry)
|
||||||
if: steps.setup-java.outcome == 'failure'
|
if: steps.setup-java.outcome == 'failure'
|
||||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: "25"
|
java-version: "25"
|
||||||
@@ -1016,8 +1078,16 @@ jobs:
|
|||||||
|
|
||||||
# `install` runs the archetype test suite (the real FFI boundary check) and
|
# `install` runs the archetype test suite (the real FFI boundary check) and
|
||||||
# installs the binding to the local repo so the examples can resolve it.
|
# installs the binding to the local repo so the examples can resolve it.
|
||||||
|
# Maven resolves plugins/deps from the network on a cache miss; retry so a
|
||||||
|
# transient Central blip retries instead of failing the job.
|
||||||
- name: Test and install the Java binding
|
- name: Test and install the Java binding
|
||||||
run: mvn -B -f bindings/java install
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
|
with:
|
||||||
|
timeout_minutes: 20
|
||||||
|
max_attempts: 2
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
command: mvn -B -f bindings/java install
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Build the Java examples
|
- name: Build the Java examples
|
||||||
run: mvn -B -f examples/java compile
|
run: mvn -B -f examples/java compile
|
||||||
@@ -1050,7 +1120,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
manylinux: [auto, musllinux_1_2]
|
manylinux: [auto, musllinux_1_2]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -1076,3 +1146,22 @@ jobs:
|
|||||||
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly
|
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly
|
||||||
# at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
|
# at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
|
||||||
# the every-push / every-PR critical path.
|
# the every-push / every-PR critical path.
|
||||||
|
|
||||||
|
# Non-blocking external-link heads-up on PRs. The authoritative check is the
|
||||||
|
# scheduled links.yml; here it only surfaces link rot early without ever
|
||||||
|
# gating a PR — external sites flake (rate limits, transient outages, moves),
|
||||||
|
# so `continue-on-error` keeps a third-party hiccup from blocking the merge.
|
||||||
|
# Redirects are reported as warnings (lychee only fails on hard errors).
|
||||||
|
links:
|
||||||
|
name: External links (non-blocking)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
|
timeout-minutes: 10
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
|
||||||
|
with:
|
||||||
|
args: --config lychee.toml --no-progress --root-dir "${{ github.workspace }}" "*.md" "bindings/*/README.md"
|
||||||
|
fail: true
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
build-mode: none
|
build-mode: none
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
name: Link check
|
||||||
|
|
||||||
|
# External link rot is non-deterministic (third-party sites go down, rate-limit,
|
||||||
|
# or move), so the authoritative check runs on a weekly schedule and on demand
|
||||||
|
# rather than gating PRs or releases. ci.yml additionally runs a non-blocking
|
||||||
|
# lychee job on PRs for an early heads-up (continue-on-error), and release.yml is
|
||||||
|
# deliberately NOT gated on it — a transient external outage must never block an
|
||||||
|
# irreversible publish.
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 6 * * 1" # Mondays 06:00 UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
links:
|
||||||
|
name: External links (lychee)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
|
||||||
|
with:
|
||||||
|
args: --config lychee.toml --no-progress --root-dir "${{ github.workspace }}" "*.md" "bindings/*/README.md"
|
||||||
|
fail: true
|
||||||
@@ -36,6 +36,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
cargo-publish:
|
cargo-publish:
|
||||||
name: Publish to crates.io
|
name: Publish to crates.io
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# The publish jobs run with long-lived registry tokens. Binding them to a
|
# The publish jobs run with long-lived registry tokens. Binding them to a
|
||||||
# protected GitHub environment lets the org require a reviewer to approve
|
# protected GitHub environment lets the org require a reviewer to approve
|
||||||
@@ -45,7 +46,7 @@ jobs:
|
|||||||
# Settings -> Environments.
|
# Settings -> Environments.
|
||||||
environment: release
|
environment: release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: ./.github/actions/setup-rust
|
- uses: ./.github/actions/setup-rust
|
||||||
@@ -110,7 +111,7 @@ jobs:
|
|||||||
# consumers can audit the published dependency tree without
|
# consumers can audit the published dependency tree without
|
||||||
# re-resolving Cargo.lock.
|
# re-resolving Cargo.lock.
|
||||||
- name: Install cargo-cyclonedx
|
- name: Install cargo-cyclonedx
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: cargo-cyclonedx
|
tool: cargo-cyclonedx
|
||||||
@@ -139,6 +140,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
python-wheels:
|
python-wheels:
|
||||||
name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }})
|
name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }})
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -157,13 +159,13 @@ jobs:
|
|||||||
- { os: windows-11-arm, target: aarch64, manylinux: auto }
|
- { os: windows-11-arm, target: aarch64, manylinux: auto }
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
id: setup_python
|
id: setup_python
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
- name: Wait before Python retry
|
- name: Wait before Python retry
|
||||||
@@ -174,7 +176,7 @@ jobs:
|
|||||||
sleep 30
|
sleep 30
|
||||||
- name: Set up Python (retry)
|
- name: Set up Python (retry)
|
||||||
if: steps.setup_python.outcome == 'failure'
|
if: steps.setup_python.outcome == 'failure'
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
- name: Sync root README into bindings/python so it ships with the wheel
|
- name: Sync root README into bindings/python so it ships with the wheel
|
||||||
@@ -209,9 +211,10 @@ jobs:
|
|||||||
|
|
||||||
python-sdist:
|
python-sdist:
|
||||||
name: Build Python sdist
|
name: Build Python sdist
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Sync root README into bindings/python so it ships in the sdist
|
- name: Sync root README into bindings/python so it ships in the sdist
|
||||||
@@ -228,6 +231,7 @@ jobs:
|
|||||||
|
|
||||||
python-publish:
|
python-publish:
|
||||||
name: Publish to PyPI
|
name: Publish to PyPI
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: [python-wheels, python-sdist]
|
needs: [python-wheels, python-sdist]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
@@ -251,6 +255,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
node-build:
|
node-build:
|
||||||
name: Node build (${{ matrix.target }})
|
name: Node build (${{ matrix.target }})
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -263,7 +268,7 @@ jobs:
|
|||||||
- { host: windows-11-arm, target: aarch64-pc-windows-msvc }
|
- { host: windows-11-arm, target: aarch64-pc-windows-msvc }
|
||||||
runs-on: ${{ matrix.host }}
|
runs-on: ${{ matrix.host }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -296,8 +301,13 @@ jobs:
|
|||||||
timeout-minutes: 6
|
timeout-minutes: 6
|
||||||
|
|
||||||
- name: Install Node deps
|
- name: Install Node deps
|
||||||
working-directory: bindings/node
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
run: npm ci
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
command: cd bindings/node && npm ci
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Build native module
|
- name: Build native module
|
||||||
working-directory: bindings/node
|
working-directory: bindings/node
|
||||||
@@ -312,6 +322,7 @@ jobs:
|
|||||||
|
|
||||||
node-publish:
|
node-publish:
|
||||||
name: Publish to npm
|
name: Publish to npm
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: node-build
|
needs: node-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
@@ -324,7 +335,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -351,8 +362,13 @@ jobs:
|
|||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
- name: Install Node deps
|
- name: Install Node deps
|
||||||
working-directory: bindings/node
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
run: npm ci
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
command: cd bindings/node && npm ci
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Download all platform binaries
|
- name: Download all platform binaries
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
@@ -365,7 +381,8 @@ jobs:
|
|||||||
# drop the freshly built .node binary into the matching directory.
|
# drop the freshly built .node binary into the matching directory.
|
||||||
- name: Move binaries into platform package layout
|
- name: Move binaries into platform package layout
|
||||||
working-directory: bindings/node
|
working-directory: bindings/node
|
||||||
run: npx napi artifacts --dir artifacts
|
# napi-rs CLI 3 renamed `--dir` to `--output-dir` (`-d`).
|
||||||
|
run: npx napi artifacts --output-dir artifacts
|
||||||
|
|
||||||
# Publish each platform package individually. Skip versions that are
|
# Publish each platform package individually. Skip versions that are
|
||||||
# already on npm. A first-attempt 403 from npm's spam filter is
|
# already on npm. A first-attempt 403 from npm's spam filter is
|
||||||
@@ -484,6 +501,7 @@ jobs:
|
|||||||
# which requires the `id-token: write` permission set at the job level.
|
# which requires the `id-token: write` permission set at the job level.
|
||||||
wasm-publish:
|
wasm-publish:
|
||||||
name: Publish wickra-wasm to npm
|
name: Publish wickra-wasm to npm
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
# `id-token: write` lets npm publish embed a Sigstore provenance
|
# `id-token: write` lets npm publish embed a Sigstore provenance
|
||||||
@@ -493,7 +511,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -523,10 +541,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
targets: wasm32-unknown-unknown
|
targets: wasm32-unknown-unknown
|
||||||
|
|
||||||
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||||
|
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||||
|
timeout-minutes: 6
|
||||||
|
|
||||||
- name: Install wasm-pack (latest, via prebuilt binary)
|
- name: Install wasm-pack (latest, via prebuilt binary)
|
||||||
# See the matching note in ci.yml: jetli's default installs an old
|
# See the matching note in ci.yml: jetli's default installs an old
|
||||||
# 0.10.x wasm-pack whose build subcommand rejects --features.
|
# 0.10.x wasm-pack whose build subcommand rejects --features.
|
||||||
uses: taiki-e/install-action@59012be0884e296ca2da49b530610e72c49039ad # v2.81.6
|
uses: taiki-e/install-action@bffeee26d4db9be238a4ea78d8826604ebcb594d # v2.82.5
|
||||||
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
timeout-minutes: 10 # fail fast on a stuck download instead of hanging the job
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
@@ -590,6 +612,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
c-abi-build:
|
c-abi-build:
|
||||||
name: C ABI library (${{ matrix.target }})
|
name: C ABI library (${{ matrix.target }})
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -602,7 +625,7 @@ jobs:
|
|||||||
- { host: windows-11-arm, target: aarch64-pc-windows-msvc }
|
- { host: windows-11-arm, target: aarch64-pc-windows-msvc }
|
||||||
runs-on: ${{ matrix.host }}
|
runs-on: ${{ matrix.host }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -645,6 +668,7 @@ jobs:
|
|||||||
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
|
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
|
||||||
csharp-publish:
|
csharp-publish:
|
||||||
name: Publish to NuGet
|
name: Publish to NuGet
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: c-abi-build
|
needs: c-abi-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
@@ -652,7 +676,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
id-token: write # request the GitHub OIDC token for trusted publishing
|
id-token: write # request the GitHub OIDC token for trusted publishing
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -689,11 +713,18 @@ jobs:
|
|||||||
echo "staged ${RID[$target]}:"; ls -l "$dest"
|
echo "staged ${RID[$target]}:"; ls -l "$dest"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# dotnet pack restores from nuget.org first; retry so a transient restore
|
||||||
|
# blip retries instead of failing the release.
|
||||||
- name: Pack
|
- name: Pack
|
||||||
shell: bash
|
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||||
run: |
|
with:
|
||||||
version="${GITHUB_REF_NAME#v}"
|
timeout_minutes: 15
|
||||||
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
max_attempts: 2
|
||||||
|
retry_wait_seconds: 20
|
||||||
|
shell: bash
|
||||||
|
command: |
|
||||||
|
version="${GITHUB_REF_NAME#v}"
|
||||||
|
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
||||||
|
|
||||||
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
|
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
|
||||||
# 'user' is the nuget.org profile name (the package owner), not an email.
|
# 'user' is the nuget.org profile name (the package owner), not an email.
|
||||||
@@ -728,11 +759,12 @@ jobs:
|
|||||||
# match the release tag (kept in sync by the version-bump checklist).
|
# match the release tag (kept in sync by the version-bump checklist).
|
||||||
java-publish:
|
java-publish:
|
||||||
name: Publish to Maven Central
|
name: Publish to Maven Central
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: c-abi-build
|
needs: c-abi-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment: release
|
environment: release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -772,7 +804,7 @@ jobs:
|
|||||||
# setup-java writes a settings.xml with the 'central' server credentials
|
# setup-java writes a settings.xml with the 'central' server credentials
|
||||||
# (mapped from the env vars below) and imports the GPG signing key.
|
# (mapped from the env vars below) and imports the GPG signing key.
|
||||||
- name: Set up JDK 25 + Maven Central credentials + GPG
|
- name: Set up JDK 25 + Maven Central credentials + GPG
|
||||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: "25"
|
java-version: "25"
|
||||||
@@ -799,10 +831,11 @@ jobs:
|
|||||||
# derived artifact, so its bot commit is intentionally unsigned.
|
# derived artifact, so its bot commit is intentionally unsigned.
|
||||||
go-mirror:
|
go-mirror:
|
||||||
name: Mirror the Go module to wickra-go
|
name: Mirror the Go module to wickra-go
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: c-abi-build
|
needs: c-abi-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -882,6 +915,7 @@ jobs:
|
|||||||
|
|
||||||
github-release:
|
github-release:
|
||||||
name: Attach assets to the draft GitHub Release
|
name: Attach assets to the draft GitHub Release
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
|
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@@ -892,7 +926,7 @@ jobs:
|
|||||||
tag: ${{ steps.tag.outputs.tag }}
|
tag: ${{ steps.tag.outputs.tag }}
|
||||||
version: ${{ steps.tag.outputs.version }}
|
version: ${{ steps.tag.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -946,7 +980,7 @@ jobs:
|
|||||||
echo "asset-count=$(ls release-assets/ | wc -l)"
|
echo "asset-count=$(ls release-assets/ | wc -l)"
|
||||||
|
|
||||||
- name: Create / update the draft GitHub Release with assets
|
- name: Create / update the draft GitHub Release with assets
|
||||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ steps.tag.outputs.tag }}
|
tag_name: ${{ steps.tag.outputs.tag }}
|
||||||
name: Wickra ${{ steps.tag.outputs.tag }}
|
name: Wickra ${{ steps.tag.outputs.tag }}
|
||||||
@@ -1007,6 +1041,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
attestations:
|
attestations:
|
||||||
name: Attest build provenance
|
name: Attest build provenance
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: [cargo-publish, python-wheels, python-sdist, github-release]
|
needs: [cargo-publish, python-wheels, python-sdist, github-release]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# Signed SLSA build-provenance attestations for the published crates and
|
# Signed SLSA build-provenance attestations for the published crates and
|
||||||
@@ -1041,7 +1076,7 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- name: Attest build provenance
|
- name: Attest build provenance
|
||||||
id: attest
|
id: attest
|
||||||
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
|
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
|
||||||
with:
|
with:
|
||||||
subject-path: |
|
subject-path: |
|
||||||
artifacts/crates/*.crate
|
artifacts/crates/*.crate
|
||||||
@@ -1090,6 +1125,7 @@ jobs:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
publish-release:
|
publish-release:
|
||||||
name: Publish the GitHub Release
|
name: Publish the GitHub Release
|
||||||
|
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||||
needs: [github-release, attestations]
|
needs: [github-release, attestations]
|
||||||
if: always() && needs.github-release.result == 'success'
|
if: always() && needs.github-release.result == 'success'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
id-token: write # OIDC token to publish results to the OpenSSF API
|
id-token: write # OIDC token to publish results to the OpenSSF API
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
publish_results: true
|
publish_results: true
|
||||||
|
|
||||||
- name: Upload SARIF artifact
|
- name: Upload SARIF artifact
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
# Fetching the now-gone `refs/heads/<branch>` then fails the run (exit 1).
|
# Fetching the now-gone `refs/heads/<branch>` then fails the run (exit 1).
|
||||||
# The head SHA stays reachable via `refs/pull/N/head` after the branch is
|
# The head SHA stays reachable via `refs/pull/N/head` after the branch is
|
||||||
# gone, so the checkout — and the run — survives an instant merge.
|
# gone, so the checkout — and the run — survives an instant merge.
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
|
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ jobs:
|
|||||||
name: metadata audit
|
name: metadata audit
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
- name: Audit repo-metadata.toml drift
|
- name: Audit repo-metadata.toml drift
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ jobs:
|
|||||||
actions: read # online audits resolve referenced actions
|
actions: read # online audits resolve referenced actions
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Run zizmor
|
- name: Run zizmor
|
||||||
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
|
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
|
||||||
|
|||||||
+92
-1
@@ -7,6 +7,92 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.9.9] - 2026-06-28
|
||||||
|
|
||||||
|
Maintenance release. No library or binding code changes from `0.9.8`; this
|
||||||
|
re-release simply runs through the corrected release workflow (the `0.9.8` npm
|
||||||
|
publish required a hotfix to the napi-rs 3 `napi artifacts` invocation, now in
|
||||||
|
place), so the published `0.9.9` artifacts are byte-identical to `0.9.8`.
|
||||||
|
|
||||||
|
## [0.9.8] - 2026-06-28
|
||||||
|
|
||||||
|
Maintenance release. The library API and every indicator are unchanged from
|
||||||
|
`0.9.7`; this release migrates the Node.js binding's build to napi-rs 3 and
|
||||||
|
carries routine dependency and CI tooling updates.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Node binding built with napi-rs 3.** Migrate `napi` 2.16 → 3.9, `napi-derive`
|
||||||
|
2.16 → 3.5 (Rust) and `@napi-rs/cli` 2.18 → 3.7 (npm). The published API and
|
||||||
|
every computed value are unchanged — the generated TypeScript surface is
|
||||||
|
identical (626 symbols), only the code-generation format differs. napi 3's
|
||||||
|
derive macros emit `#[allow(unsafe_code)]`, so the Node crate's `unsafe_code`
|
||||||
|
lint is relaxed from the workspace `forbid` to `deny` for that crate only;
|
||||||
|
`forbid` stays in force for every other crate. The `engines.node` floor is
|
||||||
|
raised to `>= 22` (matching the CI test matrix). `ureq` is intentionally held
|
||||||
|
at 2.x — ureq 3 unconditionally pulls `webpki-root-certs` (CDLA-Permissive-2.0),
|
||||||
|
which the native-tls / OS-trust-store setup deliberately avoids.
|
||||||
|
- **Dependency and CI housekeeping.** Bump the Maven
|
||||||
|
`central-publishing-maven-plugin` and the GitHub Actions used by CI
|
||||||
|
(`actions/checkout`, `taiki-e/install-action`, `actions/setup-java`,
|
||||||
|
`softprops/action-gh-release`). No runtime code changes.
|
||||||
|
|
||||||
|
## [0.9.7] - 2026-06-21
|
||||||
|
|
||||||
|
Maintenance release. The library API and every indicator are unchanged from
|
||||||
|
`0.9.6`; this release carries an R package metadata fix and routine dependency
|
||||||
|
and CI tooling updates.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **R package: credit `kingchenc` as the package author and maintainer.** The R
|
||||||
|
`DESCRIPTION` was the only binding still listing "Wickra contributors" as the
|
||||||
|
sole `aut`/`cre` — an outlier introduced when the binding was added. It now
|
||||||
|
matches the Python, Node, and Rust core metadata, the package `.Rd` is
|
||||||
|
regenerated, and the binding `LICENSE` copyright holder is aligned with the
|
||||||
|
root `LICENSE-MIT`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Dependency and CI housekeeping.** Bump the C# test dependencies
|
||||||
|
(`Microsoft.NET.Test.Sdk`, `xunit`, `xunit.runner.visualstudio`), the GitHub
|
||||||
|
Actions used by CI (`setup-python`, `upload-artifact`, `codecov-action`,
|
||||||
|
`taiki-e/install-action`), and the Java benchmark's `org.wickra:wickra`
|
||||||
|
dependency. No runtime code changes.
|
||||||
|
|
||||||
|
## [0.9.6] - 2026-06-18
|
||||||
|
|
||||||
|
Documentation release for the R binding. The library API and every indicator
|
||||||
|
are unchanged from `0.9.5`; only the R package's help pages change.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **R package: document the data-layer exports and refresh the man pages.**
|
||||||
|
r-universe's `R CMD check` reported two warnings against the `0.9.3` data layer
|
||||||
|
it built for the first time in `0.9.5`: twelve undocumented exported objects
|
||||||
|
(`BinanceFeed`, `CandleReader`, `Resampler`, `TickAggregator`,
|
||||||
|
`fetch_binance_klines` and the `name` / `is_ready` / `warmup_period` / `push` /
|
||||||
|
`read` generics) and a codoc mismatch on `AwesomeOscillatorHistogram` (its help
|
||||||
|
page still listed `sma_period` after the argument was renamed to `lookback`).
|
||||||
|
The roxygen sources existed but the `man/*.Rd` had never been regenerated; they
|
||||||
|
are now complete, and a `push()` example that constructed a `TickAggregator`
|
||||||
|
without its required `gap_fill` argument is fixed. CI now runs `R CMD check` so
|
||||||
|
documentation drift fails the pull request instead of surfacing on r-universe.
|
||||||
|
|
||||||
|
|
||||||
|
## [0.9.5] - 2026-06-17
|
||||||
|
|
||||||
|
Maintenance release. The library API and every indicator are unchanged from
|
||||||
|
`0.9.4`; the only change that ships to users is to the R package's build script.
|
||||||
|
The rest of the release is CI / release-pipeline hardening (dependency caching,
|
||||||
|
job timeouts, and network-install retries) that does not affect the artifacts.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **R package: retry the C ABI download.** `configure` / `configure.win` fetch the
|
||||||
|
prebuilt `wickra-c-<triple>.tar.gz` from the matching GitHub release. A freshly
|
||||||
|
cut release can briefly return 404 while its assets propagate across the CDN
|
||||||
|
(and a transient network blip would also fail it), so the single-shot download
|
||||||
|
is now retried with a backoff (~2 min) before giving up. Fixes
|
||||||
|
`cannot open URL … 404 Not Found` on r-universe / source installs taken right
|
||||||
|
after a release.
|
||||||
|
|
||||||
|
|
||||||
## [0.9.4] - 2026-06-17
|
## [0.9.4] - 2026-06-17
|
||||||
|
|
||||||
Packaging fix for the `0.9.3` data layer. The library is identical to `0.9.3` on
|
Packaging fix for the `0.9.3` data layer. The library is identical to `0.9.3` on
|
||||||
@@ -1836,7 +1922,12 @@ public API changes.
|
|||||||
optional Binance live feed.
|
optional Binance live feed.
|
||||||
- Bindings for Python, Node.js, and WebAssembly.
|
- Bindings for Python, Node.js, and WebAssembly.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.4...HEAD
|
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.9...HEAD
|
||||||
|
[0.9.9]: https://github.com/wickra-lib/wickra/compare/v0.9.8...v0.9.9
|
||||||
|
[0.9.8]: https://github.com/wickra-lib/wickra/compare/v0.9.7...v0.9.8
|
||||||
|
[0.9.7]: https://github.com/wickra-lib/wickra/compare/v0.9.6...v0.9.7
|
||||||
|
[0.9.6]: https://github.com/wickra-lib/wickra/compare/v0.9.5...v0.9.6
|
||||||
|
[0.9.5]: https://github.com/wickra-lib/wickra/compare/v0.9.4...v0.9.5
|
||||||
[0.9.4]: https://github.com/wickra-lib/wickra/compare/v0.9.3...v0.9.4
|
[0.9.4]: https://github.com/wickra-lib/wickra/compare/v0.9.3...v0.9.4
|
||||||
[0.9.3]: https://github.com/wickra-lib/wickra/compare/v0.9.2...v0.9.3
|
[0.9.3]: https://github.com/wickra-lib/wickra/compare/v0.9.2...v0.9.3
|
||||||
[0.9.2]: https://github.com/wickra-lib/wickra/compare/v0.9.1...v0.9.2
|
[0.9.2]: https://github.com/wickra-lib/wickra/compare/v0.9.1...v0.9.2
|
||||||
|
|||||||
Generated
+87
-34
@@ -198,9 +198,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.6.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
@@ -277,9 +277,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.18"
|
version = "0.9.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
@@ -329,13 +329,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.2.9"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
|
checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
@@ -428,12 +424,54 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
@@ -463,10 +501,13 @@ version = "0.3.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
@@ -690,9 +731,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.8.9"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-link",
|
"windows-link",
|
||||||
@@ -751,15 +792,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "napi"
|
name = "napi"
|
||||||
version = "2.16.17"
|
version = "3.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3"
|
checksum = "b41bda2ac390efb5e8d22025d925ccc3f3807d8c1bea6d19b36127247c4b8f83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"ctor",
|
"ctor",
|
||||||
"napi-derive",
|
"futures",
|
||||||
|
"napi-build",
|
||||||
"napi-sys",
|
"napi-sys",
|
||||||
"once_cell",
|
"nohash-hasher",
|
||||||
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -770,12 +813,12 @@ checksum = "c9c366d2c8c60b86fa632df75f745509b52f9128f91a6bad4c796e44abb505e1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "napi-derive"
|
name = "napi-derive"
|
||||||
version = "2.16.13"
|
version = "3.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c"
|
checksum = "61d66f70256ad5aef58659966064471d0ad90e2897bc36a5a5e0389c85aabc1e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"convert_case",
|
"convert_case",
|
||||||
|
"ctor",
|
||||||
"napi-derive-backend",
|
"napi-derive-backend",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -784,24 +827,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "napi-derive-backend"
|
name = "napi-derive-backend"
|
||||||
version = "1.0.75"
|
version = "5.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf"
|
checksum = "81b4b08f15eed7a2a20c3f4c6314013fc3ac890a3afa9892b594485299ebdb2d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"once_cell",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
|
||||||
"semver",
|
"semver",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "napi-sys"
|
name = "napi-sys"
|
||||||
version = "2.4.0"
|
version = "3.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3"
|
checksum = "1f5bcdf71abd3a50d00b49c1c2c75251cb3c913777d6139cd37dabc093a5e400"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
@@ -823,6 +864,12 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nohash-hasher"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-ansi-term"
|
name = "nu-ansi-term"
|
||||||
version = "0.50.3"
|
version = "0.50.3"
|
||||||
@@ -1211,6 +1258,12 @@ version = "0.8.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
@@ -1785,7 +1838,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra"
|
name = "wickra"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"criterion",
|
"criterion",
|
||||||
@@ -1796,7 +1849,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-bench"
|
name = "wickra-bench"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"criterion",
|
"criterion",
|
||||||
"kand",
|
"kand",
|
||||||
@@ -1808,7 +1861,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-c"
|
name = "wickra-c"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"wickra-core",
|
"wickra-core",
|
||||||
@@ -1817,7 +1870,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-core"
|
name = "wickra-core"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"proptest",
|
"proptest",
|
||||||
@@ -1827,7 +1880,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-data"
|
name = "wickra-data"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"csv",
|
"csv",
|
||||||
@@ -1846,7 +1899,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-examples"
|
name = "wickra-examples"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1856,7 +1909,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-node"
|
name = "wickra-node"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"napi",
|
"napi",
|
||||||
"napi-build",
|
"napi-build",
|
||||||
@@ -1868,7 +1921,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-python"
|
name = "wickra-python"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"pyo3",
|
"pyo3",
|
||||||
@@ -1879,7 +1932,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-wasm"
|
name = "wickra-wasm"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
|||||||
+3
-3
@@ -14,7 +14,7 @@ members = [
|
|||||||
exclude = ["fuzz"]
|
exclude = ["fuzz"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
authors = ["kingchenc <support@wickra.org>"]
|
authors = ["kingchenc <support@wickra.org>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.86"
|
rust-version = "1.86"
|
||||||
@@ -26,8 +26,8 @@ keywords = ["finance", "trading", "indicators", "technical-analysis", "ta"]
|
|||||||
categories = ["finance", "mathematics", "science"]
|
categories = ["finance", "mathematics", "science"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
wickra-core = { path = "crates/wickra-core", version = "0.9.4" }
|
wickra-core = { path = "crates/wickra-core", version = "0.9.9" }
|
||||||
wickra-data = { path = "crates/wickra-data", version = "0.9.4" }
|
wickra-data = { path = "crates/wickra-data", version = "0.9.9" }
|
||||||
|
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
rayon = "1.10"
|
rayon = "1.10"
|
||||||
|
|||||||
@@ -18,10 +18,17 @@
|
|||||||
[](https://www.bestpractices.dev/projects/13094)
|
[](https://www.bestpractices.dev/projects/13094)
|
||||||
[](https://github.com/wickra-lib/wickra/attestations)
|
[](https://github.com/wickra-lib/wickra/attestations)
|
||||||
[](https://docs.wickra.org)
|
[](https://docs.wickra.org)
|
||||||
|
[](https://live.wickra.org)
|
||||||
[](https://docs.wickra.org/FAQ#do-all-the-language-bindings-compute-the-same-values)
|
[](https://docs.wickra.org/FAQ#do-all-the-language-bindings-compute-the-same-values)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
**Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies, zero third-party packages.**
|
**Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies, zero third-party packages.**
|
||||||
|
|
||||||
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
|
|
||||||
|
**Part of the [Wickra ecosystem](#ecosystem):** the same data-driven core and ten-language binding surface also power [wickra-exchange](https://github.com/wickra-lib/wickra-exchange), [wickra-backtest](https://github.com/wickra-lib/wickra-backtest), [wickra-terminal](https://github.com/wickra-lib/wickra-terminal), [wickra-screener](https://github.com/wickra-lib/wickra-screener), [wickra-xray](https://github.com/wickra-lib/wickra-xray), [wickra-radar](https://github.com/wickra-lib/wickra-radar), [wickra-copilot](https://github.com/wickra-lib/wickra-copilot) and [wickra-shazam](https://github.com/wickra-lib/wickra-shazam).
|
||||||
|
|
||||||
Wickra is a multi-language technical-analysis library with a Rust core and
|
Wickra is a multi-language technical-analysis library with a Rust core and
|
||||||
native bindings for Python, Node.js and WASM, plus a C ABI that C, C++,
|
native bindings for Python, Node.js and WASM, plus a C ABI that C, C++,
|
||||||
C#, Go, Java, R and any other C-capable language links against. Every indicator is a
|
C#, Go, Java, R and any other C-capable language links against. Every indicator is a
|
||||||
@@ -435,6 +442,22 @@ order-book, trade, profile, alt-chart bars, footprint). This catches FFI wiring
|
|||||||
bugs the math-only core tests cannot see — it has already found and fixed real
|
bugs the math-only core tests cannot see — it has already found and fixed real
|
||||||
cross-language marshalling bugs in the Java and R bindings.
|
cross-language marshalling bugs in the Java and R bindings.
|
||||||
|
|
||||||
|
## Ecosystem
|
||||||
|
|
||||||
|
Wickra is the core library. The same data-driven core + ten-language binding
|
||||||
|
pattern powers a family of products built on it:
|
||||||
|
|
||||||
|
- [**wickra-exchange**](https://github.com/wickra-lib/wickra-exchange) — unified market-data + execution across ten crypto exchanges
|
||||||
|
- [**wickra-backtest**](https://github.com/wickra-lib/wickra-backtest) — event-driven backtester over the Wickra core
|
||||||
|
- [**wickra-terminal**](https://github.com/wickra-lib/wickra-terminal) — the trading terminal: a TUI and a browser renderer over the stack
|
||||||
|
- [**wickra-screener**](https://github.com/wickra-lib/wickra-screener) — parallel multi-symbol screening over 514 streaming indicators
|
||||||
|
- [**wickra-xray**](https://github.com/wickra-lib/wickra-xray) — market-microstructure explorer: footprint, order-book heatmap, liquidation map, funding/OI divergence
|
||||||
|
- [**wickra-radar**](https://github.com/wickra-lib/wickra-radar) — perp-universe alert radar: OI delta, funding flip, book imbalance, liquidation clusters, OI/price divergence
|
||||||
|
- [**wickra-copilot**](https://github.com/wickra-lib/wickra-copilot) — local market copilot grounded in real order-book, liquidation and funding microstructure
|
||||||
|
- [**wickra-shazam**](https://github.com/wickra-lib/wickra-shazam) — match an asset's current microstructure fingerprint against its entire history
|
||||||
|
|
||||||
|
Docs live at [docs.wickra.org](https://docs.wickra.org) ([wickra-docs](https://github.com/wickra-lib/wickra-docs)); the marketing site and in-browser demo at [wickra.org](https://wickra.org) ([webpage](https://github.com/wickra-lib/webpage)).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are very welcome — issues, bug reports, ideas, and pull requests
|
Contributions are very welcome — issues, bug reports, ideas, and pull requests
|
||||||
@@ -507,6 +530,6 @@ The library is provided **as is**, without warranty of any kind; see
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://star-history.com/#wickra-lib/wickra&Date">
|
<a href="https://star-history.com/#wickra-lib/wickra&Date">
|
||||||
<img alt="Wickra star history" width="640"
|
<img alt="Wickra star history" width="640"
|
||||||
src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/star-history.svg">
|
src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/star-history.svg?v=2">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+3
-3
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
## Supported versions
|
## Supported versions
|
||||||
|
|
||||||
Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.4`
|
Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.9`
|
||||||
version only; please upgrade to the newest release before reporting an issue.
|
version only; please upgrade to the newest release before reporting an issue.
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 0.9.4 (latest) | :white_check_mark: |
|
| 0.9.9 (latest) | :white_check_mark: |
|
||||||
| < 0.9.4 | :x: |
|
| < 0.9.9 | :x: |
|
||||||
|
|
||||||
## Reporting a vulnerability
|
## Reporting a vulnerability
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ Most questions are answered in the documentation:
|
|||||||
data layer, and an FAQ.
|
data layer, and an FAQ.
|
||||||
- **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a
|
- **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a
|
||||||
quick overview.
|
quick overview.
|
||||||
- **API docs (Rust):** <https://docs.rs/wickra>.
|
- **API docs (Rust):** <https://docs.rs/wickra/latest/wickra/>.
|
||||||
|
|
||||||
## Questions and help
|
## Questions and help
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://github.com/wickra-lib/wickra/releases/latest)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — C / C++
|
# Wickra — C / C++
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://github.com/wickra-lib/wickra/releases/latest)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for C and C++. A prebuilt shared/static
|
**Streaming-first technical indicators for C and C++. A prebuilt shared/static
|
||||||
library plus a generated `wickra.h` — no system dependencies.**
|
library plus a generated `wickra.h` — no system dependencies.**
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://www.nuget.org/packages/Wickra)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — C#
|
# Wickra — C#
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://www.nuget.org/packages/Wickra)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for C#. `dotnet add package Wickra` —
|
**Streaming-first technical indicators for C#. `dotnet add package Wickra` —
|
||||||
prebuilt native library, no system dependencies.**
|
prebuilt native library, no system dependencies.**
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
|
||||||
<PackageReference Include="xunit" Version="2.9.2" />
|
<PackageReference Include="xunit" Version="2.9.3" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<!-- NuGet package metadata -->
|
<!-- NuGet package metadata -->
|
||||||
<PackageId>Wickra</PackageId>
|
<PackageId>Wickra</PackageId>
|
||||||
<Version>0.9.4</Version>
|
<Version>0.9.9</Version>
|
||||||
<Authors>kingchenc</Authors>
|
<Authors>kingchenc</Authors>
|
||||||
<Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description>
|
<Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description>
|
||||||
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
|
||||||
|
|||||||
+12
-4
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://pkg.go.dev/github.com/wickra-lib/wickra/bindings/go)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — Go
|
# Wickra — Go
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://pkg.go.dev/github.com/wickra-lib/wickra/bindings/go)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.**
|
**Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.**
|
||||||
|
|
||||||
|
|||||||
+14
-6
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://central.sonatype.com/artifact/org.wickra/wickra)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — Java
|
# Wickra — Java
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://central.sonatype.com/artifact/org.wickra/wickra)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for the JVM, on the Java Foreign Function
|
**Streaming-first technical indicators for the JVM, on the Java Foreign Function
|
||||||
& Memory API — prebuilt native library, no JNI, no system dependencies.**
|
& Memory API — prebuilt native library, no JNI, no system dependencies.**
|
||||||
@@ -30,14 +38,14 @@ Maven:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.wickra</groupId>
|
<groupId>org.wickra</groupId>
|
||||||
<artifactId>wickra</artifactId>
|
<artifactId>wickra</artifactId>
|
||||||
<version>0.9.4</version>
|
<version>0.9.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
Gradle:
|
Gradle:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
implementation("org.wickra:wickra:0.9.4")
|
implementation("org.wickra:wickra:0.9.9")
|
||||||
```
|
```
|
||||||
|
|
||||||
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
|
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.wickra</groupId>
|
<groupId>org.wickra</groupId>
|
||||||
<artifactId>wickra</artifactId>
|
<artifactId>wickra</artifactId>
|
||||||
<version>0.8.2</version>
|
<version>0.9.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>org.wickra</groupId>
|
<groupId>org.wickra</groupId>
|
||||||
<artifactId>wickra</artifactId>
|
<artifactId>wickra</artifactId>
|
||||||
<version>0.9.4</version>
|
<version>0.9.9</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Wickra</name>
|
<name>Wickra</name>
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.central</groupId>
|
<groupId>org.sonatype.central</groupId>
|
||||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||||
<version>0.10.0</version>
|
<version>0.11.0</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<publishingServerId>central</publishingServerId>
|
<publishingServerId>central</publishingServerId>
|
||||||
|
|||||||
@@ -20,14 +20,35 @@ publish = false
|
|||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[lints]
|
# Mirrors [workspace.lints] (the source of truth) EXCEPT `unsafe_code`, which is
|
||||||
workspace = true
|
# relaxed from the workspace `forbid` to `deny`: the napi-rs 3 derive macros emit
|
||||||
|
# `#[allow(unsafe_code)]`, which `forbid` cannot permit. `deny` still fails the
|
||||||
|
# build on any unguarded unsafe in our own code. Keep this list in sync with the
|
||||||
|
# workspace if its lints change.
|
||||||
|
[lints.rust]
|
||||||
|
unsafe_code = "deny"
|
||||||
|
missing_debug_implementations = "warn"
|
||||||
|
unreachable_pub = "warn"
|
||||||
|
unused_must_use = "deny"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
all = { level = "warn", priority = -1 }
|
||||||
|
pedantic = { level = "warn", priority = -1 }
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
must_use_candidate = "allow"
|
||||||
|
missing_errors_doc = "allow"
|
||||||
|
missing_panics_doc = "allow"
|
||||||
|
cast_precision_loss = "allow"
|
||||||
|
cast_possible_truncation = "allow"
|
||||||
|
cast_sign_loss = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
float_cmp = "allow"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wickra-core = { workspace = true }
|
wickra-core = { workspace = true }
|
||||||
wickra-data = { workspace = true, features = ["live-binance"] }
|
wickra-data = { workspace = true, features = ["live-binance"] }
|
||||||
napi = { version = "2.16", features = ["napi8"] }
|
napi = { version = "3.9", features = ["napi8"] }
|
||||||
napi-derive = "2.16"
|
napi-derive = "3.5"
|
||||||
# Drives the async Binance feed behind the blocking poll.
|
# Drives the async Binance feed behind the blocking poll.
|
||||||
tokio = { version = "1", features = ["rt", "net", "time"] }
|
tokio = { version = "1", features = ["rt", "net", "time"] }
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://www.npmjs.com/package/wickra)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — Node.js
|
# Wickra — Node.js
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://www.npmjs.com/package/wickra)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for Node.js. `npm install wickra` —
|
**Streaming-first technical indicators for Node.js. `npm install wickra` —
|
||||||
prebuilt native binary, no system dependencies.**
|
prebuilt native binary, no system dependencies.**
|
||||||
|
|||||||
Vendored
+6400
-5778
File diff suppressed because it is too large
Load Diff
+1593
-800
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-darwin-arm64",
|
"name": "wickra-darwin-arm64",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.darwin-arm64.node",
|
"main": "wickra.darwin-arm64.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-darwin-x64",
|
"name": "wickra-darwin-x64",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.darwin-x64.node",
|
"main": "wickra.darwin-x64.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-linux-arm64-gnu",
|
"name": "wickra-linux-arm64-gnu",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.linux-arm64-gnu.node",
|
"main": "wickra.linux-arm64-gnu.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-linux-x64-gnu",
|
"name": "wickra-linux-x64-gnu",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.linux-x64-gnu.node",
|
"main": "wickra.linux-x64-gnu.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-win32-arm64-msvc",
|
"name": "wickra-win32-arm64-msvc",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.win32-arm64-msvc.node",
|
"main": "wickra.win32-arm64-msvc.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra-win32-x64-msvc",
|
"name": "wickra-win32-x64-msvc",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
"description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||||
"main": "wickra.win32-x64-msvc.node",
|
"main": "wickra.win32-x64-msvc.node",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
Generated
+1832
-27
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wickra",
|
"name": "wickra",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.",
|
"description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.",
|
||||||
"author": "kingchenc <support@wickra.org>",
|
"author": "kingchenc <support@wickra.org>",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@@ -44,15 +44,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 20"
|
"node": ">= 22"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"wickra-linux-x64-gnu": "0.9.4",
|
"wickra-linux-x64-gnu": "0.9.9",
|
||||||
"wickra-linux-arm64-gnu": "0.9.4",
|
"wickra-linux-arm64-gnu": "0.9.9",
|
||||||
"wickra-darwin-x64": "0.9.4",
|
"wickra-darwin-x64": "0.9.9",
|
||||||
"wickra-darwin-arm64": "0.9.4",
|
"wickra-darwin-arm64": "0.9.9",
|
||||||
"wickra-win32-x64-msvc": "0.9.4",
|
"wickra-win32-x64-msvc": "0.9.9",
|
||||||
"wickra-win32-arm64-msvc": "0.9.4"
|
"wickra-win32-arm64-msvc": "0.9.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "napi build --platform --release",
|
"build": "napi build --platform --release",
|
||||||
@@ -64,6 +64,6 @@
|
|||||||
"bench": "node benchmarks/throughput.js"
|
"bench": "node benchmarks/throughput.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@napi-rs/cli": "^2.18.0"
|
"@napi-rs/cli": "^3.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://pypi.org/project/wickra/)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — Python
|
# Wickra — Python
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://pypi.org/project/wickra/)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators for Python. `pip install wickra` — zero
|
**Streaming-first technical indicators for Python. `pip install wickra` — zero
|
||||||
third-party dependencies (not even NumPy), no system dependencies, no C build tooling.**
|
third-party dependencies (not even NumPy), no system dependencies, no C build tooling.**
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "wickra"
|
name = "wickra"
|
||||||
version = "0.9.4"
|
version = "0.9.9"
|
||||||
description = "Streaming-first technical indicators: incremental, fast, install-free."
|
description = "Streaming-first technical indicators: incremental, fast, install-free."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Package: wickra
|
Package: wickra
|
||||||
Type: Package
|
Type: Package
|
||||||
Title: Streaming-First Technical Indicators
|
Title: Streaming-First Technical Indicators
|
||||||
Version: 0.9.4
|
Version: 0.9.9
|
||||||
Authors@R: person("Wickra contributors", role = c("aut", "cre"), email = "support@wickra.org")
|
Authors@R: person("kingchenc", role = c("aut", "cre"), email = "support@wickra.org")
|
||||||
Description: R bindings for the Wickra technical-analysis library over its C ABI
|
Description: R bindings for the Wickra technical-analysis library over its C ABI
|
||||||
hub. Exposes 514 indicators, each an O(1) streaming state machine shared with
|
hub. Exposes 514 indicators, each an O(1) streaming state machine shared with
|
||||||
the Rust core and the other language bindings, so that live and historical
|
the Rust core and the other language bindings, so that live and historical
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
YEAR: 2026
|
YEAR: 2026
|
||||||
COPYRIGHT HOLDER: Wickra contributors
|
COPYRIGHT HOLDER: kingchenc and the Wickra contributors
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Generated by roxygen2: do not edit by hand
|
# Generated by roxygen2: do not edit by hand
|
||||||
|
|
||||||
|
S3method(base::flush,wickra_indicator)
|
||||||
S3method(batch,wickra_indicator)
|
S3method(batch,wickra_indicator)
|
||||||
S3method(flush,wickra_indicator)
|
|
||||||
S3method(is_ready,wickra_indicator)
|
S3method(is_ready,wickra_indicator)
|
||||||
S3method(name,wickra_indicator)
|
S3method(name,wickra_indicator)
|
||||||
S3method(push,wickra_indicator)
|
S3method(push,wickra_indicator)
|
||||||
|
|||||||
@@ -479,7 +479,14 @@ Camarilla <- function() {
|
|||||||
.wk_obj("camarilla", ptr, "Camarilla")
|
.wk_obj("camarilla", ptr, "Camarilla")
|
||||||
}
|
}
|
||||||
|
|
||||||
#' CandleReader: parse OHLCV candles from a CSV string
|
#' Parse OHLCV candles from a CSV string
|
||||||
|
#'
|
||||||
|
#' Builds a reader over an in-memory CSV string with a header row and OHLCV
|
||||||
|
#' columns. Pass the result to [read()] to get every parsed candle.
|
||||||
|
#'
|
||||||
|
#' @param csv A length-one character string of CSV text (a header row followed
|
||||||
|
#' by OHLCV data rows).
|
||||||
|
#' @return A `wickra_indicator` candle reader; read its candles with [read()].
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
CandleReader <- function(csv) {
|
CandleReader <- function(csv) {
|
||||||
@@ -2687,7 +2694,14 @@ RenkoTrailingStop <- function(block_size) {
|
|||||||
.wk_obj("renko_trailing_stop", ptr, "RenkoTrailingStop")
|
.wk_obj("renko_trailing_stop", ptr, "RenkoTrailingStop")
|
||||||
}
|
}
|
||||||
|
|
||||||
#' Resampler indicator
|
#' Resample candles to a higher timeframe
|
||||||
|
#'
|
||||||
|
#' Aggregates a stream of candles into higher-timeframe bars. Feed candles with
|
||||||
|
#' [update()] (it returns a completed higher-timeframe bar, or `NULL` while the
|
||||||
|
#' current bar is still open) and emit the final, still-open bar with [flush()].
|
||||||
|
#'
|
||||||
|
#' @param timeframe Integer number of input candles per higher-timeframe bar.
|
||||||
|
#' @return A `wickra_indicator` resampler.
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
Resampler <- function(timeframe) {
|
Resampler <- function(timeframe) {
|
||||||
@@ -3487,7 +3501,15 @@ Thrusting <- function() {
|
|||||||
.wk_obj("thrusting", ptr, "Thrusting")
|
.wk_obj("thrusting", ptr, "Thrusting")
|
||||||
}
|
}
|
||||||
|
|
||||||
#' TickAggregator indicator
|
#' Aggregate trade ticks into time-bucketed candles
|
||||||
|
#'
|
||||||
|
#' Builds OHLCV candles from a stream of trade ticks. Feed ticks with [push()],
|
||||||
|
#' which returns the candles closed by that tick.
|
||||||
|
#'
|
||||||
|
#' @param bucket Time-bucket width, in the same unit as the tick timestamps.
|
||||||
|
#' @param gap_fill Logical; if `TRUE`, empty buckets with no trades are still
|
||||||
|
#' emitted (carried forward) instead of skipped.
|
||||||
|
#' @return A `wickra_indicator` tick aggregator; feed it ticks with [push()].
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
TickAggregator <- function(bucket, gap_fill) {
|
TickAggregator <- function(bucket, gap_fill) {
|
||||||
@@ -4151,6 +4173,13 @@ Zlema <- function(period) {
|
|||||||
#' 15 = 1M). `base_url` overrides the endpoint (`NULL` = production). Not
|
#' 15 = 1M). `base_url` overrides the endpoint (`NULL` = production). Not
|
||||||
#' available in the wasm (r-universe/webR) build, which has no raw sockets.
|
#' available in the wasm (r-universe/webR) build, which has no raw sockets.
|
||||||
#'
|
#'
|
||||||
|
#' @param symbols Comma-separated trading symbols (case-insensitive), e.g.
|
||||||
|
#' `"btcusdt,ethusdt"`.
|
||||||
|
#' @param interval Integer interval code `0:15` (`0` = 1s, `1` = 1m, ...,
|
||||||
|
#' `12` = 1d, `13` = 3d, `14` = 1w, `15` = 1M).
|
||||||
|
#' @param base_url Optional endpoint override; `NULL` uses production.
|
||||||
|
#' @return A `wickra_binance_feed`; poll it with [binance_next()] and close it
|
||||||
|
#' with [binance_close()].
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
BinanceFeed <- function(symbols, interval, base_url = NULL) {
|
BinanceFeed <- function(symbols, interval, base_url = NULL) {
|
||||||
@@ -4165,6 +4194,10 @@ BinanceFeed <- function(symbols, interval, base_url = NULL) {
|
|||||||
#' `high`, `low`, `close`, `volume`, `open_time`, `is_closed`) when an event
|
#' `high`, `low`, `close`, `volume`, `open_time`, `is_closed`) when an event
|
||||||
#' arrives, or `NULL` on timeout. Errors once the stream is closed.
|
#' arrives, or `NULL` on timeout. Errors once the stream is closed.
|
||||||
#'
|
#'
|
||||||
|
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
|
||||||
|
#' @param timeout_ms Poll timeout in milliseconds.
|
||||||
|
#' @return A named list (`symbol`, `open`, `high`, `low`, `close`, `volume`,
|
||||||
|
#' `open_time`, `is_closed`) for an event, or `NULL` on timeout.
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
binance_next <- function(feed, timeout_ms = 1000) {
|
binance_next <- function(feed, timeout_ms = 1000) {
|
||||||
@@ -4173,6 +4206,8 @@ binance_next <- function(feed, timeout_ms = 1000) {
|
|||||||
|
|
||||||
#' Close a Binance feed
|
#' Close a Binance feed
|
||||||
#'
|
#'
|
||||||
|
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
|
||||||
|
#' @return `NULL`, invisibly.
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
binance_close <- function(feed) {
|
binance_close <- function(feed) {
|
||||||
@@ -4190,6 +4225,14 @@ binance_close <- function(feed) {
|
|||||||
#' `volume`, `timestamp`. Blocks until the response arrives. Not available in the
|
#' `volume`, `timestamp`. Blocks until the response arrives. Not available in the
|
||||||
#' wasm (r-universe/webR) build, which has no raw sockets.
|
#' wasm (r-universe/webR) build, which has no raw sockets.
|
||||||
#'
|
#'
|
||||||
|
#' @param symbol Trading symbol (case-insensitive), e.g. `"btcusdt"`.
|
||||||
|
#' @param interval Integer interval code `0:15` (see [BinanceFeed()]).
|
||||||
|
#' @param limit Number of klines to fetch (`1:1000`).
|
||||||
|
#' @param start_ms,end_ms Optional inclusive Unix-millisecond bounds; a negative
|
||||||
|
#' value means unset.
|
||||||
|
#' @param base_url Optional host override; `NULL` uses production.
|
||||||
|
#' @return An `n x 6` numeric matrix with columns `open`, `high`, `low`,
|
||||||
|
#' `close`, `volume`, `timestamp`.
|
||||||
#' @keywords internal
|
#' @keywords internal
|
||||||
#' @export
|
#' @export
|
||||||
fetch_binance_klines <- function(symbol, interval, limit, start_ms = -1,
|
fetch_binance_klines <- function(symbol, interval, limit, start_ms = -1,
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ name.wickra_indicator <- function(object) {
|
|||||||
#' @param timestamp Trade timestamp, in the same unit as the aggregator bucket.
|
#' @param timestamp Trade timestamp, in the same unit as the aggregator bucket.
|
||||||
#' @return A numeric matrix with six named columns (possibly zero rows).
|
#' @return A numeric matrix with six named columns (possibly zero rows).
|
||||||
#' @examples
|
#' @examples
|
||||||
#' agg <- TickAggregator(1000)
|
#' agg <- TickAggregator(1000, FALSE)
|
||||||
#' push(agg, 100, 1, 0)
|
#' push(agg, 100, 1, 0)
|
||||||
#' push(agg, 102, 1, 1000) # closes the first bucket
|
#' push(agg, 102, 1, 1000) # closes the first bucket
|
||||||
#' @export
|
#' @export
|
||||||
|
|||||||
+12
-3
@@ -1,8 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://wickra-lib.r-universe.dev)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — R <img src="man/figures/logo.png" align="right" height="120" alt="Wickra logo" />
|
# Wickra — R <img src="man/figures/logo.png" align="right" height="120" alt="Wickra logo" />
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
|
|
||||||
**Streaming-first technical indicators for R, over the Wickra C ABI hub via `.Call`.**
|
**Streaming-first technical indicators for R, over the Wickra C ABI hub via `.Call`.**
|
||||||
|
|
||||||
|
|||||||
Vendored
+22
-4
@@ -14,6 +14,26 @@ set -e
|
|||||||
inc=""
|
inc=""
|
||||||
lib=""
|
lib=""
|
||||||
|
|
||||||
|
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||||
|
# across the CDN, and a transient network blip should not fail the build either.
|
||||||
|
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||||
|
# on the first miss.
|
||||||
|
wickra_download() {
|
||||||
|
_url="$1"
|
||||||
|
_dest="$2"
|
||||||
|
_attempt=1
|
||||||
|
while [ "${_attempt}" -le 6 ]; do
|
||||||
|
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||||
|
sleep 20
|
||||||
|
_attempt=$((_attempt + 1))
|
||||||
|
done
|
||||||
|
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
|
# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
|
||||||
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten
|
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten
|
||||||
# (EMSDK on PATH), so build the C ABI staticlib from source for
|
# (EMSDK on PATH), so build the C ABI staticlib from source for
|
||||||
@@ -26,8 +46,7 @@ if [ "$(uname -s)" = "Emscripten" ]; then
|
|||||||
echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})"
|
echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})"
|
||||||
build=$(mktemp -d)
|
build=$(mktemp -d)
|
||||||
url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz"
|
url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz"
|
||||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', '${build}/src.tar.gz', mode = 'wb', quiet = TRUE)" \
|
wickra_download "${url}" "${build}/src.tar.gz" || exit 1
|
||||||
|| { echo "wickra: failed to download source ${url}"; exit 1; }
|
|
||||||
"${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
|
"${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
|
||||||
root="${build}/wickra-${version}"
|
root="${build}/wickra-${version}"
|
||||||
rustup target add wasm32-unknown-emscripten 2>/dev/null || true
|
rustup target add wasm32-unknown-emscripten 2>/dev/null || true
|
||||||
@@ -73,8 +92,7 @@ else
|
|||||||
esac
|
esac
|
||||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
|
||||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||||
|
|||||||
@@ -10,6 +10,26 @@
|
|||||||
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
|
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||||
|
# across the CDN, and a transient network blip should not fail the build either.
|
||||||
|
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||||
|
# on the first miss.
|
||||||
|
wickra_download() {
|
||||||
|
_url="$1"
|
||||||
|
_dest="$2"
|
||||||
|
_attempt=1
|
||||||
|
while [ "${_attempt}" -le 6 ]; do
|
||||||
|
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||||
|
sleep 20
|
||||||
|
_attempt=$((_attempt + 1))
|
||||||
|
done
|
||||||
|
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
|
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
|
||||||
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
|
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
|
||||||
inc="${WICKRA_INCLUDE_DIR}"
|
inc="${WICKRA_INCLUDE_DIR}"
|
||||||
@@ -24,8 +44,7 @@ else
|
|||||||
esac
|
esac
|
||||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
|
||||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
\alias{AwesomeOscillatorHistogram}
|
\alias{AwesomeOscillatorHistogram}
|
||||||
\title{AwesomeOscillatorHistogram indicator}
|
\title{AwesomeOscillatorHistogram indicator}
|
||||||
\usage{
|
\usage{
|
||||||
AwesomeOscillatorHistogram(fast, slow, sma_period)
|
AwesomeOscillatorHistogram(fast, slow, lookback)
|
||||||
}
|
}
|
||||||
\description{
|
\description{
|
||||||
AwesomeOscillatorHistogram indicator
|
AwesomeOscillatorHistogram indicator
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{BinanceFeed}
|
||||||
|
\alias{BinanceFeed}
|
||||||
|
\title{Connect to a live Binance kline feed}
|
||||||
|
\usage{
|
||||||
|
BinanceFeed(symbols, interval, base_url = NULL)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{symbols}{Comma-separated trading symbols (case-insensitive), e.g.
|
||||||
|
\code{"btcusdt,ethusdt"}.}
|
||||||
|
|
||||||
|
\item{interval}{Integer interval code \code{0:15} (\code{0} = 1s, \code{1} = 1m, ...,
|
||||||
|
\code{12} = 1d, \code{13} = 3d, \code{14} = 1w, \code{15} = 1M).}
|
||||||
|
|
||||||
|
\item{base_url}{Optional endpoint override; \code{NULL} uses production.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A \code{wickra_binance_feed}; poll it with \code{\link[=binance_next]{binance_next()}} and close it
|
||||||
|
with \code{\link[=binance_close]{binance_close()}}.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Opens a live Binance kline stream for one or more comma-separated \code{symbols}
|
||||||
|
(case-insensitive) at the given \code{interval} code (an integer \code{0:15}, the same
|
||||||
|
order as the other bindings: 0 = 1s, 1 = 1m, ... 12 = 1d, 13 = 3d, 14 = 1w,
|
||||||
|
15 = 1M). \code{base_url} overrides the endpoint (\code{NULL} = production). Not
|
||||||
|
available in the wasm (r-universe/webR) build, which has no raw sockets.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{CandleReader}
|
||||||
|
\alias{CandleReader}
|
||||||
|
\title{Parse OHLCV candles from a CSV string}
|
||||||
|
\usage{
|
||||||
|
CandleReader(csv)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{csv}{A length-one character string of CSV text (a header row followed
|
||||||
|
by OHLCV data rows).}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A \code{wickra_indicator} candle reader; read its candles with \code{\link[=read]{read()}}.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Builds a reader over an in-memory CSV string with a header row and OHLCV
|
||||||
|
columns. Pass the result to \code{\link[=read]{read()}} to get every parsed candle.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{Resampler}
|
||||||
|
\alias{Resampler}
|
||||||
|
\title{Resample candles to a higher timeframe}
|
||||||
|
\usage{
|
||||||
|
Resampler(timeframe)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{timeframe}{Integer number of input candles per higher-timeframe bar.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A \code{wickra_indicator} resampler.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Aggregates a stream of candles into higher-timeframe bars. Feed candles with
|
||||||
|
\code{\link[=update]{update()}} (it returns a completed higher-timeframe bar, or \code{NULL} while the
|
||||||
|
current bar is still open) and emit the final, still-open bar with \code{\link[=flush]{flush()}}.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{TickAggregator}
|
||||||
|
\alias{TickAggregator}
|
||||||
|
\title{Aggregate trade ticks into time-bucketed candles}
|
||||||
|
\usage{
|
||||||
|
TickAggregator(bucket, gap_fill)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{bucket}{Time-bucket width, in the same unit as the tick timestamps.}
|
||||||
|
|
||||||
|
\item{gap_fill}{Logical; if \code{TRUE}, empty buckets with no trades are still
|
||||||
|
emitted (carried forward) instead of skipped.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A \code{wickra_indicator} tick aggregator; feed it ticks with \code{\link[=push]{push()}}.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Builds OHLCV candles from a stream of trade ticks. Feed ticks with \code{\link[=push]{push()}},
|
||||||
|
which returns the candles closed by that tick.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{binance_close}
|
||||||
|
\alias{binance_close}
|
||||||
|
\title{Close a Binance feed}
|
||||||
|
\usage{
|
||||||
|
binance_close(feed)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
\code{NULL}, invisibly.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Close a Binance feed
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{binance_next}
|
||||||
|
\alias{binance_next}
|
||||||
|
\title{Poll a Binance feed for the next kline event}
|
||||||
|
\usage{
|
||||||
|
binance_next(feed, timeout_ms = 1000)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
|
||||||
|
|
||||||
|
\item{timeout_ms}{Poll timeout in milliseconds.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A named list (\code{symbol}, \code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
|
||||||
|
\code{open_time}, \code{is_closed}) for an event, or \code{NULL} on timeout.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Waits up to \code{timeout_ms} milliseconds. Returns a named list (\code{symbol}, \code{open},
|
||||||
|
\code{high}, \code{low}, \code{close}, \code{volume}, \code{open_time}, \code{is_closed}) when an event
|
||||||
|
arrives, or \code{NULL} on timeout. Errors once the stream is closed.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/indicators.R
|
||||||
|
\name{fetch_binance_klines}
|
||||||
|
\alias{fetch_binance_klines}
|
||||||
|
\title{Fetch historical Binance klines over REST}
|
||||||
|
\usage{
|
||||||
|
fetch_binance_klines(
|
||||||
|
symbol,
|
||||||
|
interval,
|
||||||
|
limit,
|
||||||
|
start_ms = -1,
|
||||||
|
end_ms = -1,
|
||||||
|
base_url = NULL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{symbol}{Trading symbol (case-insensitive), e.g. \code{"btcusdt"}.}
|
||||||
|
|
||||||
|
\item{interval}{Integer interval code \code{0:15} (see \code{\link[=BinanceFeed]{BinanceFeed()}}).}
|
||||||
|
|
||||||
|
\item{limit}{Number of klines to fetch (\code{1:1000}).}
|
||||||
|
|
||||||
|
\item{start_ms, end_ms}{Optional inclusive Unix-millisecond bounds; a negative
|
||||||
|
value means unset.}
|
||||||
|
|
||||||
|
\item{base_url}{Optional host override; \code{NULL} uses production.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
An \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low},
|
||||||
|
\code{close}, \code{volume}, \code{timestamp}.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Downloads up to \code{limit} (\code{1:1000}) historical klines for \code{symbol} at the given
|
||||||
|
\code{interval} code (an integer \code{0:15}, the same order as the other bindings).
|
||||||
|
\code{start_ms}/\code{end_ms} are optional inclusive Unix-millisecond bounds (a negative
|
||||||
|
value means unset); \code{base_url} overrides the host (\code{NULL} = production). Returns
|
||||||
|
an \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
|
||||||
|
\code{volume}, \code{timestamp}. Blocks until the response arrives. Not available in the
|
||||||
|
wasm (r-universe/webR) build, which has no raw sockets.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{flush.wickra_indicator}
|
||||||
|
\alias{flush.wickra_indicator}
|
||||||
|
\title{Flush a resampler's final candle}
|
||||||
|
\usage{
|
||||||
|
\method{flush}{wickra_indicator}(con)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{con}{A \code{wickra_indicator} created by \code{\link[=Resampler]{Resampler()}}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A named numeric vector (\code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
|
||||||
|
\code{timestamp}), or \code{NULL} if nothing is pending.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Emit the final, still-open candle a \code{\link[=Resampler]{Resampler()}} is aggregating (the partial
|
||||||
|
higher-timeframe bar that no later input has closed yet). Extends the base
|
||||||
|
generic \code{\link[base:flush]{base::flush()}}.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
r <- Resampler(5)
|
||||||
|
for (t in 0:6) update(r, 100 + t, 101 + t, 99 + t, 100 + t, 10, t)
|
||||||
|
flush(r)
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{is_ready}
|
||||||
|
\alias{is_ready}
|
||||||
|
\alias{is_ready.wickra_indicator}
|
||||||
|
\title{Whether an indicator has consumed enough input to emit a value}
|
||||||
|
\usage{
|
||||||
|
is_ready(object)
|
||||||
|
|
||||||
|
\method{is_ready}{wickra_indicator}(object)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{object}{A \code{wickra_indicator}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A single logical.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Not available for the alt-chart bar builders, which have no warmup.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
sma <- Sma(3)
|
||||||
|
is_ready(sma) # FALSE
|
||||||
|
for (x in c(1, 2, 3)) update(sma, x)
|
||||||
|
is_ready(sma) # TRUE
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{name}
|
||||||
|
\alias{name}
|
||||||
|
\alias{name.wickra_indicator}
|
||||||
|
\title{Canonical name of an indicator}
|
||||||
|
\usage{
|
||||||
|
name(object)
|
||||||
|
|
||||||
|
\method{name}{wickra_indicator}(object)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{object}{A \code{wickra_indicator}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A single character string.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Returns the stable, human-readable name of the indicator (the same name
|
||||||
|
reported by every other Wickra binding), e.g. \code{"SMA"} for \code{\link[=Sma]{Sma()}}.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
name(Sma(14)) # "SMA"
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{push}
|
||||||
|
\alias{push}
|
||||||
|
\alias{push.wickra_indicator}
|
||||||
|
\title{Push a trade tick into a tick aggregator}
|
||||||
|
\usage{
|
||||||
|
push(object, price, size, timestamp)
|
||||||
|
|
||||||
|
\method{push}{wickra_indicator}(object, price, size, timestamp)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{object}{A \code{wickra_indicator} created by \code{\link[=TickAggregator]{TickAggregator()}}.}
|
||||||
|
|
||||||
|
\item{price}{Trade price.}
|
||||||
|
|
||||||
|
\item{size}{Trade size (volume).}
|
||||||
|
|
||||||
|
\item{timestamp}{Trade timestamp, in the same unit as the aggregator bucket.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A numeric matrix with six named columns (possibly zero rows).
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Feeds one trade tick to a \code{\link[=TickAggregator]{TickAggregator()}} and returns the candles it
|
||||||
|
closed as a numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
|
||||||
|
\code{volume}, \code{timestamp} (zero rows while the open bar merely grows).
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
agg <- TickAggregator(1000, FALSE)
|
||||||
|
push(agg, 100, 1, 0)
|
||||||
|
push(agg, 102, 1, 1000) # closes the first bucket
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{read}
|
||||||
|
\alias{read}
|
||||||
|
\alias{read.wickra_indicator}
|
||||||
|
\title{Read every candle parsed by a CSV candle reader}
|
||||||
|
\usage{
|
||||||
|
read(object)
|
||||||
|
|
||||||
|
\method{read}{wickra_indicator}(object)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{object}{A \code{wickra_indicator} created by \code{\link[=CandleReader]{CandleReader()}}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A numeric matrix with six named columns (zero rows for an empty CSV).
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Returns all the candles a \code{\link[=CandleReader]{CandleReader()}} parsed from its CSV, as a numeric
|
||||||
|
matrix with columns \code{open}, \code{high}, \code{low}, \code{close}, \code{volume}, \code{timestamp}.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
r <- CandleReader("timestamp,open,high,low,close,volume\n0,100,101,99,100.5,10\n")
|
||||||
|
read(r)
|
||||||
|
}
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
\format{
|
\format{
|
||||||
A data frame with 250 rows and 6 columns:
|
A data frame with 250 rows and 6 columns:
|
||||||
\describe{
|
\describe{
|
||||||
\item{date}{Trading date (\code{Date}).}
|
\item{date}{Trading date (\code{Date}).}
|
||||||
\item{open}{Opening price.}
|
\item{open}{Opening price.}
|
||||||
\item{high}{Session high.}
|
\item{high}{Session high.}
|
||||||
\item{low}{Session low.}
|
\item{low}{Session low.}
|
||||||
\item{close}{Closing price.}
|
\item{close}{Closing price.}
|
||||||
\item{volume}{Traded volume.}
|
\item{volume}{Traded volume.}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\usage{
|
\usage{
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/methods.R
|
||||||
|
\name{warmup_period}
|
||||||
|
\alias{warmup_period}
|
||||||
|
\alias{warmup_period.wickra_indicator}
|
||||||
|
\title{Number of updates an indicator needs before it produces a value}
|
||||||
|
\usage{
|
||||||
|
warmup_period(object)
|
||||||
|
|
||||||
|
\method{warmup_period}{wickra_indicator}(object)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{object}{A \code{wickra_indicator}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A single integer: the warmup period.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Not available for the alt-chart bar builders (\code{\link[=RenkoBars]{RenkoBars()}}, \code{\link[=KagiBars]{KagiBars()}},
|
||||||
|
\code{\link[=PointAndFigureBars]{PointAndFigureBars()}}, …), which have no warmup.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
warmup_period(Sma(14)) # 14
|
||||||
|
}
|
||||||
@@ -18,16 +18,17 @@ Useful links:
|
|||||||
\itemize{
|
\itemize{
|
||||||
\item \url{https://github.com/wickra-lib/wickra}
|
\item \url{https://github.com/wickra-lib/wickra}
|
||||||
\item \url{https://docs.wickra.org}
|
\item \url{https://docs.wickra.org}
|
||||||
|
\item \url{https://wickra-lib.r-universe.dev}
|
||||||
\item Report bugs at \url{https://github.com/wickra-lib/wickra/issues}
|
\item Report bugs at \url{https://github.com/wickra-lib/wickra/issues}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
\author{
|
\author{
|
||||||
\strong{Maintainer}: Wickra contributors \email{support@wickra.org}
|
\strong{Maintainer}: kingchenc \email{support@wickra.org}
|
||||||
|
|
||||||
Authors:
|
Authors:
|
||||||
\itemize{
|
\itemize{
|
||||||
\item Wickra contributors \email{support@wickra.org}
|
\item kingchenc \email{support@wickra.org}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-4
@@ -1,9 +1,17 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/wickra-lib/wickra)
|
||||||
|
[](https://www.npmjs.com/package/wickra-wasm)
|
||||||
|
[](https://github.com/wickra-lib/wickra#license)
|
||||||
|
|
||||||
# Wickra — WASM
|
# Wickra — WASM
|
||||||
|
|
||||||
[](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
|
---
|
||||||
[](https://codecov.io/gh/wickra-lib/wickra)
|
|
||||||
[](https://www.npmjs.com/package/wickra-wasm)
|
> **▶ Live demo:** all 514 indicators over real Binance market data, computed live in your browser — **[live.wickra.org](https://live.wickra.org)** · zero backend, powered by `wickra-wasm`.
|
||||||
[](https://github.com/wickra-lib/wickra#license)
|
|
||||||
|
|
||||||
**Streaming-first technical indicators in the browser. `npm install
|
**Streaming-first technical indicators in the browser. `npm install
|
||||||
wickra-wasm` — pure WebAssembly, runs anywhere a modern JS engine does.**
|
wickra-wasm` — pure WebAssembly, runs anywhere a modern JS engine does.**
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ workspace = true
|
|||||||
# (rayon) feature on — the WASM binding needs a rayon-free build and the data
|
# (rayon) feature on — the WASM binding needs a rayon-free build and the data
|
||||||
# layer never uses the parallel batch path. Native bindings re-enable `parallel`
|
# layer never uses the parallel batch path. Native bindings re-enable `parallel`
|
||||||
# through their own wickra-core dependency (cargo unifies the features).
|
# through their own wickra-core dependency (cargo unifies the features).
|
||||||
wickra-core = { path = "../wickra-core", version = "0.9.2", default-features = false }
|
wickra-core = { path = "../wickra-core", version = "0.9.9", default-features = false }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
csv = "1.3"
|
csv = "1.3"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>org.wickra.examples</groupId>
|
<groupId>org.wickra.examples</groupId>
|
||||||
<artifactId>wickra-examples</artifactId>
|
<artifactId>wickra-examples</artifactId>
|
||||||
<version>0.9.4</version>
|
<version>0.9.9</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Wickra Java examples</name>
|
<name>Wickra Java examples</name>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.wickra</groupId>
|
<groupId>org.wickra</groupId>
|
||||||
<artifactId>wickra</artifactId>
|
<artifactId>wickra</artifactId>
|
||||||
<version>0.9.4</version>
|
<version>0.9.9</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
Generated
+7
-7
@@ -14,7 +14,7 @@
|
|||||||
},
|
},
|
||||||
"../../bindings/node": {
|
"../../bindings/node": {
|
||||||
"name": "wickra",
|
"name": "wickra",
|
||||||
"version": "0.9.4",
|
"version": "0.9.9",
|
||||||
"license": "MIT OR Apache-2.0",
|
"license": "MIT OR Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@napi-rs/cli": "^2.18.0"
|
"@napi-rs/cli": "^2.18.0"
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
"node": ">= 20"
|
"node": ">= 20"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"wickra-darwin-arm64": "0.9.4",
|
"wickra-darwin-arm64": "0.9.9",
|
||||||
"wickra-darwin-x64": "0.9.4",
|
"wickra-darwin-x64": "0.9.9",
|
||||||
"wickra-linux-arm64-gnu": "0.9.4",
|
"wickra-linux-arm64-gnu": "0.9.9",
|
||||||
"wickra-linux-x64-gnu": "0.9.4",
|
"wickra-linux-x64-gnu": "0.9.9",
|
||||||
"wickra-win32-arm64-msvc": "0.9.4",
|
"wickra-win32-arm64-msvc": "0.9.9",
|
||||||
"wickra-win32-x64-msvc": "0.9.4"
|
"wickra-win32-x64-msvc": "0.9.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wickra": {
|
"node_modules/wickra": {
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
# lychee external-link checker config (see .github/workflows/links.yml).
|
||||||
|
# Only http(s) URLs are checked; relative/internal links are skipped via the
|
||||||
|
# scheme filter and --root-dir resolution. Loopback and private addresses are
|
||||||
|
# skipped too.
|
||||||
|
|
||||||
|
max_retries = 3
|
||||||
|
retry_wait_time = 2
|
||||||
|
timeout = 20
|
||||||
|
|
||||||
|
# Treat these as success: OK, partial content, and rate-limited (transient).
|
||||||
|
accept = [200, 206, 429]
|
||||||
|
|
||||||
|
scheme = ["https", "http"]
|
||||||
|
exclude_all_private = true
|
||||||
|
|
||||||
|
# Known false positives (the URLs are valid; lychee just can't verify them at
|
||||||
|
# check time):
|
||||||
|
# - crates.io and npmjs.com return 403/404 to non-browser requests
|
||||||
|
# (anti-scraping); the package pages are live in a browser.
|
||||||
|
# - GitHub serves 404 for /stargazers and /network/members to anonymous clients
|
||||||
|
# (anti-scraping). The README social-footer badges link there; the pages are
|
||||||
|
# live in a browser.
|
||||||
|
# - the CHANGELOG version-compare links point at the release tag that is created
|
||||||
|
# *after* the bump is merged. ci.yml runs on push/PR (never on the tag), so the
|
||||||
|
# tag never exists when lychee runs and the compare URL 404s. One pattern
|
||||||
|
# covers every future version — no per-release exclude needed.
|
||||||
|
exclude = [
|
||||||
|
'crates\.io/crates/',
|
||||||
|
'www\.npmjs\.com/package/',
|
||||||
|
'github\.com/wickra-lib/wickra/compare/',
|
||||||
|
'github\.com/wickra-lib/wickra/stargazers',
|
||||||
|
'github\.com/wickra-lib/wickra/network/members',
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user