Files
Miha Kralj 04d77964ba docs: refresh benchmarks, add stability and versioning docs
Updated benchmark tables for Wickra and Pearson Correlation; env bumped to .NET 10.0.12 / BenchmarkDotNet 0.15.3. Replaced Fair Warning with a stability statement; added SemVer + [Obsolete] deprecation policy.
2026-09-27 18:00:13 -07:00

3.1 KiB

Versioning

QuanTAlib follows Semantic Versioning 2.0.0 with a strict deprecation window: nothing is removed without first being marked [Obsolete] for at least one minor release.

SemVer

Version format is MAJOR.MINOR.PATCH (currently 0.8.12).

Change Bump Example
Bug fix, no API change PATCH 0.8.12 → 0.8.13
Additive API, or an [Obsolete] deprecation MINOR 0.8.13 → 0.9.0
Breaking change (removal, signature change) MAJOR 0.9.0 → 1.0.0

Pre-1.0, breaking changes bump MINOR instead of MAJOR (SemVer §4). QuanTAlib is still 0.x, so the "one minor-version deprecation window" is: deprecate in 0.x, remove in 0.x+1.

Deprecation window

When an API has to go away:

  1. Deprecate — tag it [Obsolete("Use X instead. Will be removed in 0.(x+1).", false)] and ship it in release 0.x.y. No breaking change, MINOR bump.
  2. Remove — delete it in the next minor release 0.x+1.0.

Removal without the window is a build error, not a policy suggestion. PublicAPI.Shipped.txt is frozen by Microsoft.CodeAnalysis.PublicApiAnalyzers, so deleting a public member fails the build (RS0017) until the removal is recorded in PublicAPI.Unshipped.txt with *REMOVED*. That record doubles as the audit trail that the deprecation window was honored.

Version source

The canonical version is lib/VERSION — one line, e.g. 0.8.12. Three language-agnostic consumers read it:

Consumer Reads via Result
.NET / NuGet Directory.Build.props → $(QtaVersionFile) Version, PackageVersion, InformationalVersion = the file; AssemblyVersion / FileVersion = {version}.0
Python python/pyproject.toml → ../lib/VERSION pip package version
CI .github/workflows/Release.yml release tag v{version} and dev-wheel stamping {version}.dev{run}

Bumping the version

  1. Edit lib/VERSION to the new value.
  2. Commit: chore: bump version to X.Y.Z.
  3. CI builds the NuGet package and pip wheel at that version.

Migrating off lib/VERSION

lib/VERSION exists because MSBuild, Python, and shell CI all need the same value and none of them can parse the others' config. Replacing it means one of:

  • Relocate it — move to a root-level VERSION (or version.txt). Update the path in Directory.Build.props (QtaVersionFile), python/pyproject.toml, and the four reads in Release.yml. Low risk, cosmetic.
  • Tag-derived versioning — MinVer for .NET (version = nearest git tag), plus CI writes the tag to a version.py/file for Python. Removes the file for .NET but not Python; the release pipeline changes shape.
  • Tool-managed file — Nerdbank.GitVersioning version.json replaces VERSION; its nbgv CLI stamps both .NET and Python. Structured, but adds a tool dependency.

Recommendation: keep a single plain-text version file — it is the correct pattern for three language-agnostic consumers. Move it out of lib/ only if its location bothers you; the policy above does not depend on where the file lives.