Release process
QMBED has one version across four distribution surfaces:
- the
qmbedRust crate; - the
qmbedPython distribution; - the
QMBEDJulia package; and - the shared
qmbed-capinative library.
python ci/check_versions.py rejects a release if those versions diverge.
The Python and Julia layers package the same C ABI; neither owns a second
solver implementation.
One-time registry setup
Before creating the first public registry release:
- After the one-time bootstrap publish, configure the crates.io trusted
publisher for
matrixlab-research/QMBED, workflowrelease.yml, and revoke the bootstrap token. The release job exchanges GitHub OIDC for a short-lived token and stores no crates.io secret. - Configure a PyPI trusted publisher for
matrixlab-research/QMBED, workflowrelease.yml, environmentpypi. The release job uses GitHub OIDC and does not store a PyPI password. - Install the JuliaRegistrator GitHub App for the repository.
The GitHub pypi environment should be limited to tagged releases and may
require a maintainer approval if desired.
1. Prepare native artifacts
Run Prepare Julia native artifacts on main with the intended version,
without a leading v.
The workflow builds the shared library on five architecture-native GitHub
runners. Linux linking occurs inside a manylinux2014 container so the
artifact does not inherit Ubuntu 24.04's newer glibc requirement:
| Platform | Architecture |
|---|---|
| Linux glibc | x86_64, aarch64 |
| macOS | x86_64, aarch64 |
| Windows | x86_64 |
It packages deterministic archives, publishes the versioned
artifacts-vX.Y.Z prerelease, computes both SHA-256 and Julia artifact tree
hashes, and opens a PR containing bindings/julia/Artifacts.toml.
Merge that PR only after the preparatory workflow's artifact-backed Julia test and the repository's normal branch checks pass. Do not create the final version tag before this PR is merged.
2. Create the synchronized release
From the fully green main commit:
The release workflow then:
- repeats the Rust, C ABI, Python, and artifact-backed Julia gates;
- builds and tests CPython 3.10–3.14 wheels on the supported platforms (Intel macOS stops at CPython 3.13 because Numba no longer ships newer Intel Mac binaries);
- publishes the Rust crate to crates.io and the wheels to PyPI; and
- creates the GitHub release with the same wheels attached.
Any registry failure prevents the GitHub release from presenting a partially published version as complete.
3. Register the Julia subpackage
After the tagged workflow succeeds, comment on the tagged commit:
Follow the JuliaRegistrator PR through General registry CI. The source tree already contains the platform artifact hashes, so General installs do not require a Rust compiler or a QMBED source checkout.
QMBED is an acronym-only package name. Current General auto-merge naming
rules expect at least one lowercase letter, so the initial registration is
expected to need a registry maintainer's manual review. Keep the public name
unless the project intentionally chooses a Julia-specific spelling; this is a
review gate, not a reason to fork the implementation.
4. Verify from clean environments
Verify the public registries rather than the repository checkout:
cargo add qmbed@X.Y.Z
python -m pip install "qmbed==X.Y.Z"
julia -e 'using Pkg; Pkg.add(name="QMBED", version="X.Y.Z")'
Run one eigensolve through each interface and confirm that Python resolves its
library inside site-packages/qmbed and Julia resolves it inside the artifact
store.