Skip to content

xbbg 1.4.7

Latest

Choose a tag to compare

@github-actions github-actions released this 28 Aug 01:10
· 4 commits to main since this release

Added

  • Rust crates now publish automatically on release. .github/workflows/crates-publish.yml publishes the six public crates to crates.io in dependency order, authenticating tokenlessly through rust-lang/crates-io-auth-action (GitHub OIDC), so no CARGO_REGISTRY_TOKEN secret exists. semantic_version.yml invokes it as a workflow_call job rather than relying on a tag trigger, because a tag pushed with GITHUB_TOKEN does not start tag-triggered workflows -- the documented reason the PyPI and npm workflows still need a manual dispatch. The job skips any version already in the index, so a retry after a partial failure is safe, and it stamps workspace.package.version plus every internal [workspace.dependencies] entry from the release version so all crates ship in lockstep.

Changed

  • BREAKING -- optional-backend and narwhals floors now reflect versions that actually work. The previous lower bounds were never resolved or exercised by CI, and three of them named combinations that cannot function. narwhals moves from >=2.0 to >=2.10.0 -- it is the only mandatory runtime dependency, and only 2.10.0 onward honours the narwhals.plugins entry point xbbg registers, so on 2.0-2.9 the plugin never loads and any conversion raises TypeError: Expected pandas-like dataframe, Polars dataframe, or Polars lazyframe, got: <class 'xbbg._core.ArrowTable'>. The pandas extra moves from >=2.0 to >=2.2.2,<4, because pandas 2.0.x declares no numpy<2 bound, so a fresh resolve pairs it with numpy 2.x and pandas then fails to import with numpy.dtype size changed, may indicate binary incompatibility; 2.2.2 is the first release supporting numpy 2. The duckdb extra moves from >=1.0 to >=1.5.0, because below 1.5.0 the connection backing a returned relation is lost (Connection has already been closed), and 1.0.0 additionally cannot register an Arrow PyCapsule object at all. pytest-cov in the test extra gains a >=5.0 bound; unpinned, a lowest-direct resolve selected pytest-cov 2.0.0 from 2018. polars>=0.20 and pyarrow>=22.0.0 were verified as genuinely working and are unchanged. Environments already on current releases are unaffected; anyone pinned below these bounds must upgrade.
  • Declared floors are now verified by CI. A new floors job resolves the project with uv pip install --resolution lowest-direct on Python 3.10 -- the lowest supported interpreter, and the only one where the oldest wheels are still selectable -- and runs the full non-live suite against the result. Each floor in pyproject.toml carries a comment recording the measured reason it cannot go lower.
  • Rust MSRV is declared. [workspace.package] now sets rust-version = "1.88", matching the highest rust-version in the resolved dependency graph, and pixi.toml raises its rust floor from >=1.75 to >=1.88 to agree. The published sdist compiles the Rust extension on the user's machine, so the toolchain requirement is part of the package contract rather than a local development detail; >=1.75 had been unsatisfiable for several majors.
  • Third-party Rust versions are centralized in [workspace.dependencies]. The arrow family alone was restated across eight manifests and tokio across five, and the disabled xbbg-cli / dotnet-xbbg manifests had already drifted to arrow 57.1.0 and a csbindgen 2 that has never been published. Members now inherit with { workspace = true } and layer only their own features. default-features is set in the workspace table because Cargo silently ignores a member's default-features = false when the workspace entry omits it. The migration is feature-neutral: resolved feature sets were diffed per package before and after.
  • rmcp upgraded from 2.1.0 to 3.1.2 in xbbg-mcp, with no source changes required. Both versions default ProtocolVersion::LATEST to MCP 2025-11-25, so the advertised revision is unchanged; 3.x additionally negotiates the 2026-07-28 draft.
  • Internal crate versions are centralized too, and now carry a version. Every intra-workspace dependency was a bare { path = ... }. cargo publish rejects a path dependency with no version, so no crate with an internal dependency could be published at all -- the actual reason the Rust crates sat at 1.1.2 while the project tagged v1.4.6. The internal crates now sit in [workspace.dependencies] as { path, version } and members inherit with { workspace = true }, matching the convention already used for third-party crates. Because those entries set default-features = false, xbbg-mcp and xbbg-bench now name features = ["live"] explicitly where they previously inherited it via default features.
  • crates.io package metadata is complete and points at the project, not a personal account. All five published crates had repository and homepage pointing at a legacy personal GitHub account and its github.io pages site; both now resolve to the xbbg-org repository and https://xbbg.org/. main had also dropped the homepage, readme, and keywords that 1.1.2 actually shipped. Every published crate now declares homepage, readme, keywords, categories, and rust-version (crates.io reported the MSRV as unset for all of them), plus an explicit include allowlist so only source, Cargo.toml, and README.md are ever packaged.
  • blpapi-sys is renamed to xbbg-blpapi-sys to match the name it is published under. The bare blpapi-sys name is taken on crates.io, so the local package name never matched the registry name and cargo publish -p xbbg-blpapi-sys could not resolve. [lib] name = "blpapi_sys" is retained, so Rust code still says blpapi_sys:: and the change is source-compatible with the published 1.1.2.
  • exchanges.toml moved from defs/ into crates/xbbg-ext/data/. xbbg-ext embeds it with include_str!, and the path reached outside the crate root, so the published sdist would not have contained the file and the crate would have been unbuildable from crates.io. xbbg-ext was its only consumer.

Removed

  • xbbg-sys is deleted. It was 16 lines that re-exported blpapi_sys::* behind a mandatory live feature, with a compile_error! on every other configuration -- a leftover seam from the removed mock backend. xbbg_core now depends on xbbg-blpapi-sys directly, and the compile_error! guard moves to xbbg_core/src/lib.rs so a non-live build still fails with one clear message instead of dozens of unresolved imports. The crate should also be deleted on crates.io, which is possible only after a release where xbbg_core no longer depends on it.
  • apps/xbbg-cli and bindings/dotnet-xbbg are deleted. Both were stubs of 16 and 10 lines, commented out of the workspace members, and had already drifted to dependency versions that do not resolve.

Fixed

  • Engine teardown no longer panics when the engine is dropped inside an async context. Engine owns its tokio runtime, and tokio refuses to release a runtime's last handle from inside another runtime because teardown must block to join worker threads. Any async owner therefore aborted with Cannot drop a runtime in a context where blocking is not allowed -- including xbbg-mcp, which holds the engine across #[tokio::main] and so panicked on every clean shutdown once an engine had started. Engine::drop now takes the runtime out of its field and hands it to Runtime::shutdown_background() when a runtime is current, which is race-free because the field is left empty and no second release path can reach a zero refcount. Outside an async context the previous blocking drop is retained. The live integration test that used std::mem::forget to dodge this panic -- and leaked the runtime doing so -- now drops the engine normally.
  • Engine startup failures report the real error instead of a runtime-teardown panic. Engine::start built its tokio runtime before constructing the worker pools, so any early return dropped the runtime on an async caller's thread and replaced the underlying failure with tokio's unrelated panic message. With a Bloomberg terminal unavailable, Engine::start now surfaces failed to spawn worker 0: session start failed rather than Cannot drop a runtime in a context where blocking is not allowed. The runtime is constructed after every fallible step.
  • Three high-severity advisories cleared from the JavaScript dev dependency trees (postcss GHSA-fxqj-rqcc-2cmp / GHSA-r28c-9q8g-f849, nanoid GHSA-28wg-ghj8-5hjv / GHSA-2v37-7h3g-55p8, brace-expansion GHSA-mh99-v99m-4gvg / GHSA-rgw5-rvv9-x895), plus cryptography GHSA-g6cj-pr64-35w5 and c-ares CVE-2026-33630 in the pixi environment. These are build- and test-time dependencies only and are not redistributed in any published artifact.
  • Stale pyo3 advisory ignores removed from .cargo/audit.toml and deny.toml. They suppressed RUSTSEC-2026-0176 and RUSTSEC-2026-0177 on the premise that the fix required a pyo3 0.29 chain that dependencies did not yet support; the workspace has since resolved to pyo3 0.29.2 exclusively, so the entries were unreachable and would have masked a future regression onto a vulnerable pyo3.
  • blpapi-sys no longer advertises a documentation build it cannot perform. Its docs.rs metadata requested all-features = true while build.rs panics when the mutually exclusive static and dynamic linkage features are both enabled, which also broke cargo clippy --all-features for the whole workspace. The metadata now names the default dynamic linkage.
  • xbbg_core keeps its underscore, permanently. crates.io normalizes - and _ to the same package identity, so xbbg-core is not an available name while xbbg_core exists, and claiming it would require deleting the crate and waiting out the name-reuse block. The manifest documents this so the inconsistency is not "corrected" later.

Full Changelog: v1.4.6...v1.4.7