betula-cluster
Rust-powered, memory-bounded clustering for large embeddings & tabular streams. It compresses raw data into numerically stable BETULA microclusters, then runs the clustering head on the compressed representation — k-means · GMM (diagonal & full) · Ward · spectral · Leiden community detection · directional (von Mises–Fisher / spherical) · HDBSCAN-CF · scale-space modes · Mapper — so cost scales with the microcluster count, not
N. Streamingpartial_fit, a scikit-learn API, from-scratch Rust core + PyO3, no LAPACK or SciPy at runtime.
pip install betula-cluster
Verified: a 210-case Python suite at 100% wrapper coverage + 182 Rust tests,
clippy -D warnings + fmt clean across all feature sets, CI on CPython 3.11–3.14 (one abi3 wheel).
At a glance — honest benchmarks
Measured against scikit-learn on StandardScaler-normalized data, each method in its own subprocess
with peak RSS sampled from /proc/self/statm. Full methodology, every metric, and all tables (wins
and losses) live in bench/RESULTS.md.
- ⚡🪶 Always faster — and lighter — at scale (the unconditional win). betula labels 1 M points in 0.22 s: 13× faster than scikit-learn KMeans, 23× vs GaussianMixture, 37× vs Birch — and streams 10 M in a flat ~60 MB where an in-core KMeans needs ~5 GB (≈83× less, and the gap grows without bound). This holds for every method at every size.
- 🎯 Quality at parity — or better — on most tasks. betula's k-means is at exact parity with
scikit-learn (blobs 0.861 = 0.861); full-covariance GMM matches it on anisotropic data (0.90 vs
0.90) and beats scikit-learn's GMM on real 64-D
digits(0.51 vs 0.40, via the high-dimensional covariance floor); betula-ward clusters 1 M in 0.30 s whereO(N²)sklearn-ward can't run past ~10 k; and on non-convex moons & circles the spectral and HDBSCAN heads hit ARI 1.00 — spectral matching scikit-learn'sSpectralClusteringat 3–5× the speed. - 🌍 Real data, honest trade-offs. On
digitsbetula-kmeans leads (0.57 vs 0.47); given adequate leaf resolution its diagonal GMM overtakes scikit-learn on hardcovtypetoo (0.096 vs 0.080); it clusters full covtype (581 k rows) ~5.8× faster at matching ARI; in 784-D MNISTnormalize=Truebeats scikit-learn (0.33 vs 0.32). Where a compression method costs some quality — raw-Euclidean k-means in 784-D, HDBSCAN on overlapping blobs —bench/RESULTS.mdreports it rather than hides it.
| Phase-3 clusters only the ~2 000 leaf microclusters, not the raw points, so every head finishes 1 M points in under ½ s. | The CF-tree is capped by max_leaves, so streaming memory stays flat — it clusters data larger than RAM. |
Why
Who it's for: practitioners clustering large embedding or tabular datasets — in batch or as a stream — who need bounded memory and the numerical stability that classic BIRCH and in-core scikit-learn don't provide together.
Clustering libraries tend to either not scale (full GMM/HDBSCAN on raw points), lose precision
(classic BIRCH computes variance as SS − ‖LS‖²/n, which catastrophically cancels far from the
origin), or blow up in memory (BIRCH-family subcluster explosion in high dimensions). betula-cluster
addresses all three:
- Numerically stable — clustering features
(n, μ, S)via Welford / Chan updates; the covariance is PSD by construction. Classic BIRCH loses all digits near coordinate1e7; betula does not. - Memory-bounded by design — the CF-tree caps its leaves (
max_leaves) and rebuilds, so it never explodes; streaming memory is flat inNand clusters data larger than RAM. - Complete — one stable engine spanning k-means / GMM (diag & full) / Ward / spectral / Leiden
community detection / HDBSCAN-style / Mapper, with streaming
partial_fit, a scikit-learn API, and dataset-structure inspection.
The math (stable CF, the expected-log GMM E-step, distance derivations, relation to BIRCH/BETULA) is
written up — verified symbolically and numerically — in docs/MATH.md.
When to use it
Reach for betula-cluster when the data is large or streaming, memory must stay bounded, you want
fast predict on new points, or you want one numerically stable engine spanning k-means / GMM / Ward /
density / topology plus dedup / outliers / representatives — especially on embeddings and tabular
streams.
Use raw scikit-learn instead when N fits comfortably in RAM and you want the exact point-level
algorithm with no compression: at small N the two-phase overhead removes the speed edge, and raw
HDBSCAN is stronger on overlapping density. betula-cluster trades a CF-compression approximation for
scale and bounded memory — if you need neither, a plain in-core clusterer is simpler.
Installation
pip install betula-cluster # prebuilt abi3 wheels, CPython 3.11–3.14
pip install 'betula-cluster[tune]' # + Optuna backend for memory-aware tuning
NumPy is the only runtime dependency — no SciPy, LAPACK, or BLAS. Prebuilt wheels ship for Linux
(x86-64 + aarch64), macOS (Intel + Apple Silicon), and Windows (x64); one abi3 wheel covers every
supported Python. Building from source needs a Rust toolchain — maturin develop --release (or
pip install .) in a clone.
Quick start
import numpy as np
import betula_cluster
X = np.random.default_rng(0).normal(size=(100_000, 10))
labels = betula_cluster.fit_predict(X, n_clusters=10, method="kmeans")
labels = betula_cluster.fit_predict(X, n_clusters=0, feature="full", method="gmm-full") # auto-k via BIC
labels = betula_cluster.fit_predict(X, n_clusters=8, method="spectral", threshold=0.0) # non-convex / manifold
labels = betula_cluster.fit_predict(X, method="leiden", threshold=0.4) # graph communities; count auto-discovered
labels = betula_cluster.fit_predict(X, method="hdbscan", min_cluster_size=25) # HDBSCAN-CF; -1 = noise
labels = betula_cluster.fit_predict(X, n_clusters=10, method="vmf") # directional / cosine (input auto-L2-normalized)
Streaming / out-of-core — feed chunks, finalize, predict; memory stays bounded by max_leaves:
est = betula_cluster.Betula(method="gmm", memory_budget_mb=512)
for chunk in stream_of_arrays: # each chunk is a 2-D float32/float64 array
est.partial_fit(chunk)
est.partial_fit() # finalize the global clustering over everything seen
labels = est.predict(X_query)
Robustness — the CF-tree is insertion-order sensitive, so consensus clusters several random
permutations and votes, returning a consensus labelling plus a per-point stability score (any
partitional head — kmeans / gmm / ward / spectral):
res = betula_cluster.consensus(X, n_clusters=10, n_runs=5, method="kmeans", n_jobs=-1) # -1 = all cores
res.labels # (n,) consensus label per point
res.confidence # (n,) in [0, 1] — per-point agreement across runs (1.0 = every order agrees)
res.mean_confidence # scalar robustness summary
Memory-aware hyperparameter tuning (tune, optional Optuna), Mapper topology (mapper),
semi-supervised constraints (COP-KMeans), mixed numeric+categorical (KPrototypes), streaming
density (DenStream / DbStream), the O(nnz) sparse-native path (fit_predict_sparse),
CF-weighted NMF for nonnegative data (projection="weighted-nmf"), quantile
sketches, scipy.sparse input, threshold="auto", soft assignment / coresets / diagnostics / drift
snapshots / active-learning batches, the Rust API, and the CLI — all in the
usage guide.
Capabilities
Stable core — production-ready:
- Clustering heads — weighted k-means (Hamerly), GMM (diagonal & full covariance, BIC auto-
k), exact Ward HAC, spectral (non-convex / manifold), Leiden graph community detection (auto community count,resolution/ CPM, optional covariance/manifold-aware affinity), and directional spherical k-means / von Mises–Fisher mixtures for L2-normalized embeddings (cosine geometry), all over the numerically stable BETULA CF-tree. - Streaming —
partial_fitat bounded memory (max_leaves/memory_budget_mb), EWMAdecay. - scikit-learn API —
fit/predict/fit_predict,get_params/set_params(works withPipeline/clone/GridSearchCV); typed abi3 wheel,save/load+ pickle, reusable Rust core. - Inspection & robustness —
predict_proba, coresets, microcluster/cluster geometry, outliers, near-duplicates, representatives, diagnostics, andconsensus(per-point stability across insertion-order permutations). - Tuning —
tune: memory-aware hyperparameter search with a quality / memory / speed Pareto mode; NumPy-only, optional Optuna backend (pip install 'betula-cluster[tune]').
Experimental / evolving — useful today, API may still move:
- Density & topology — HDBSCAN-CF (density over microclusters), scale-space Morse-persistence
density-mode clustering (
method="scale-space"— nok, no bandwidth), and a Mapper topological skeleton (mapper/mapper_stability). - Structured-covariance GMM —
method="gmm-toeplitz"(banded AR) and"gmm-toeplitz-full"(general positive-definite Toeplitz): covariance-shape clustering for ordered, stationary signals (time-series windows, trajectories, sensor waveforms), well-posed where full covariance is singular (N_k ≪ d) and a diagonal model ignores neighbour correlation; the general head also captures structure beyond a low-order AR (e.g. a long-lag echo). - More heads & data —
DenStream/DbStreamevolving-stream density, mergeableKllSketch/DdSketchquantiles,scipy.sparse(O(nnz), never densified), mixed numeric+categorical (KPrototypes), COP-KMeans constraints, robust (Huber) insertion, drift snapshots, dependency-free CLI.
Full reference: docs/FEATURES.md.
Examples
Seventeen executed, plotted notebooks — one per capability — live in
examples/ (render on GitHub):
- Core — quickstart, embeddings & inspection, streaming & persistence, method comparison, Mapper topology.
- Streaming density —
DenStream&DbStream. - Mixed data —
KPrototypes. - Sketches —
KllSketch&DdSketch. - Semi-supervised — must-link / cannot-link.
- Sparse / high-dim —
scipy.sparse+fit_predict_sparse. - Soft assignment & coresets —
predict_proba, coresets, diagnostics. - Production ops — drift, active learning, robust, memory budgets.
- Graph & geometry — graph clustering (Leiden), directional embeddings (vMF / spherical), geometry-aware clustering (covariance / manifold).
- Time-series —
gmm-toeplitzAR/Toeplitz covariance for stationary signals. - Nonnegative data —
projection="weighted-nmf"CF-weighted NMF on topic counts.
And six end-to-end use cases (each scored against ground truth):
- 🧹 Embedding dedup — collapse a repost-heavy corpus to representatives.
- 🚨 Log anomaly detection — batch outlier scoring + streaming
DbStreamflags. - 👥 Customer segmentation — mixed RFM + categorical personas with
KPrototypes. - 🧠 RAG corpus curation — junk removal, topic coherence, and topic-leakage detection via Mapper.
- 🔢 Real-data clustering — handwritten digits, ARI parity + centroid/exemplar inspection.
- 🌐 Graph communities — Leiden community detection on a network, scored against planted communities.
Documentation
- Usage guide — runnable snippets for every interface.
- Features — full capability reference + crate architecture.
- Math — stable CF, GMM E-step, distance derivations, relation to BIRCH/BETULA.
- Benchmarks — methodology, every metric, all tables, honest wins & losses.
- Design — internal design, invariants, and testing strategy.
Verified: 182 Rust unit + 4 integration tests + a 210-case Python suite at 100% wrapper
coverage (Rust ≥95%, CI-enforced), clippy -D warnings + fmt clean across all feature sets, on
Python 3.11–3.14 (single abi3 wheel).
Known limitations
Honest scope — inherent to a CF-compression + streaming design, not bugs:
- Insertion-order sensitive — like every BIRCH-family streaming method, the labels depend on the order points arrive (the parallel build differs from the serial one, as a different order would).
threshold/max_leavesare real hyperparameters — they trade compression against resolution;n_rebuilds_/threshold_expose thrashing / over-coarsening.- CF-level heads approximate raw-data clustering — Phase-3 runs on the
M ≪ Nmicroclusters; quality degrades when clusters overlap at the compression scale. Mitigation: more leaves. - HDBSCAN-on-CF ≠ raw-point HDBSCAN — mass-aware HDBSCAN over microclusters: fast and close, but an approximation (weaker on overlapping blobs; see the benchmarks).
- The expected-log GMM optimizes a CF-level objective, not pointwise EM (a deliberate, measured choice for coarse CFs).
- Frequent-Directions is an approximate low-rank covariance (exact only up to its rank
ℓ).
How to cite
If betula-cluster supports your research, please cite the software and the underlying
algorithms it implements. Machine-readable metadata (including the method references) lives in
CITATION.cff — GitHub's
"Cite this repository" renders it directly.
@software{gradina_betula_cluster,
author = {Gradina, Ilia},
title = {betula-cluster: numerically stable {BETULA} clustering with a {Rust} core},
year = {2026},
version = {0.2.0},
doi = {10.5281/zenodo.21427331},
license = {MIT},
url = {https://github.com/ilgrad/betula-cluster}
}
betula-cluster is an independent implementation (with extensions); the algorithms are due to BETULA — Lang & Schubert, Information Systems (2022), doi:10.1016/j.is.2021.101918 — building on BIRCH — Zhang, Ramakrishnan & Livny, SIGMOD (1996), doi:10.1145/233269.233324.
License
MIT © Ilia Gradina
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file betula_cluster-0.4.0.tar.gz.
File metadata
- Download URL: betula_cluster-0.4.0.tar.gz
- Upload date:
- Size: 238.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3893c08649cf92d4dd0055db806c5e3663059771da89591981dc5ca3bdc7b6b4
|
|
| MD5 |
dcc15cac38d69652f9615a3263d3bc65
|
|
| BLAKE2b-256 |
9851a6e014f404b491eed12ec0ba3abf3a95eb339f6626f01565431007dcf654
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0.tar.gz:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0.tar.gz -
Subject digest:
3893c08649cf92d4dd0055db806c5e3663059771da89591981dc5ca3bdc7b6b4 - Sigstore transparency entry: 2194646368
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file betula_cluster-0.4.0-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: betula_cluster-0.4.0-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26d14962942854ea6edcad6ac0267420a3012f6926f302327599e44f7e42e3ac
|
|
| MD5 |
b9582b6b492df317217d29800803bd83
|
|
| BLAKE2b-256 |
7fe64fecf53cb94d7e4d6a98afebab48f4407bb2eeef23931769fdf296d11167
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0-cp311-abi3-win_amd64.whl:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0-cp311-abi3-win_amd64.whl -
Subject digest:
26d14962942854ea6edcad6ac0267420a3012f6926f302327599e44f7e42e3ac - Sigstore transparency entry: 2194646377
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcc8942452a09d8c26df41ac0b407a80321a0907113cabd31fdc843a7b19e147
|
|
| MD5 |
9289b1b99d7372f01ac5a805587ab6a9
|
|
| BLAKE2b-256 |
fb7e876e3bc9c30ade6a0268f8f79056b96df48790142f325dff197af6e16345
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
bcc8942452a09d8c26df41ac0b407a80321a0907113cabd31fdc843a7b19e147 - Sigstore transparency entry: 2194646374
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4be75a6d579731712a50dc6754327dee9a91d1c44e949d1fca459c26b26e5d87
|
|
| MD5 |
7fec021c12f871dc4243865547ae4b9f
|
|
| BLAKE2b-256 |
2a6dad348e0d326c57c766d62993b37d82c2dad6cbb96f220d82b75195fa0966
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
4be75a6d579731712a50dc6754327dee9a91d1c44e949d1fca459c26b26e5d87 - Sigstore transparency entry: 2194646372
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file betula_cluster-0.4.0-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: betula_cluster-0.4.0-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ac9567e94163a8e2b9f1fb20c4c5b3cef98006c24680de80c4c674858b763ed
|
|
| MD5 |
3597bf81c0c1283c35cb5ee5e4a6f082
|
|
| BLAKE2b-256 |
54a2d3c1a2592272a318b1c7d63a0dc79d5e983085780ae3e16cd7d3fabaf8f4
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0-cp311-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
0ac9567e94163a8e2b9f1fb20c4c5b3cef98006c24680de80c4c674858b763ed - Sigstore transparency entry: 2194646386
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type:
File details
Details for the file betula_cluster-0.4.0-cp311-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: betula_cluster-0.4.0-cp311-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.11+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c83f9f1aa74ba2191a241f6282ff93a426814b678dd7cc8606c278420163ef6b
|
|
| MD5 |
0c1de8030a3c8fe3e2456043eab13d48
|
|
| BLAKE2b-256 |
7bc03db4ce767269fd724fc14a56754ad06d8c28e76918ddee1fc8a4558190c0
|
Provenance
The following attestation bundles were made for betula_cluster-0.4.0-cp311-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on ilgrad/betula-cluster
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
betula_cluster-0.4.0-cp311-abi3-macosx_10_12_x86_64.whl -
Subject digest:
c83f9f1aa74ba2191a241f6282ff93a426814b678dd7cc8606c278420163ef6b - Sigstore transparency entry: 2194646382
- Sigstore integration time:
-
Permalink:
ilgrad/betula-cluster@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/ilgrad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8b1f5e855e362f5799e10eeafb80fae0d097ac2f -
Trigger Event:
push
-
Statement type: