Skip to content

Versioning & Release Policy

voiage uses semantic versioning and tag-driven releases. The Cargo workspace version is authoritative, Maturin exposes it as dynamic Python package metadata, and release tags are validated fail-closed against it. Polyglot manifests remain explicit and synchronized to the same version.

The normative policy is published in specs/v1/compatibility-policy.json. Breaking changes to stable Rust, Python, C ABI, binding, CLI, schema, or serialized-output contracts require a major release. Minor releases may add backward-compatible capabilities, while patch releases may only make backward-compatible fixes.

Provisional and experimental surfaces are excluded from these guarantees until promotion. Promotion requires a normative contract, executable compatibility fixtures, and a migration assessment.

A stable feature remains available for at least two minor releases and six months, whichever is longer. At v1, Python emits FutureWarning; all surfaces provide a stable diagnostic code, replacement path, and migration documentation. Removal is permitted only in the next major release and requires updated compatibility fixtures and release notes.

The 0.x raw-dictionary EVPPI compatibility alias emits FutureWarning with the stable deprecated_raw_dict_parameter_samples diagnostic code and points callers to ParameterSet. Its warning class, code, replacement, and migration documentation are executable v1 compatibility contracts.

The Python package declares a dynamic version in pyproject.toml. Maturin reads the authoritative Cargo workspace version when building package metadata. The version-sync validator compares external binding manifests to that version, and release validation rejects a v* tag that does not match it exactly.

Binding manifests are expected to match the canonical version exactly:

  • bindings/julia/Project.toml
  • rust/Cargo.toml
  • r-package/voiageR/DESCRIPTION

The repository keeps ecosystem-specific tag and registry conventions:

  • Python publishes from v* tags
  • Julia publishes from julia-v* tags
  • Rust workspace artifacts are released from rust-v* tags; no crates.io package is currently claimed
  • R publishes from r-v* tags

The version numbers in package manifests must align with the latest released Python tag. Tag prefixes and registry targets remain ecosystem-specific; only the version value is shared.

The repo-local validator checks the canonical version against binding manifests:

Terminal window
tox -e version-sync

Or equivalently:

Terminal window
uv run python scripts/validate_version_sync.py
  1. Update the Cargo workspace version and synchronized binding manifests
  2. Run the version-sync validator and fail-closed release-tag validation
  3. Cut the matching v<version> tag
  4. Let the tag workflow build and attest a private draft
  5. Review exact artifact digests, then dispatch TestPyPI publication
  6. Permit PyPI and the public GitHub Release only after the TestPyPI smoke gate