Forward-only versioning for Trunk-Based Development
Project description
semver-ratchet (Python)
Python implementation of forward-only versioning for Trunk-Based Development.
Dynamic Versioning
semver-ratchet calculates versions dynamically from your git state. Use it as a build backend to inject versions at build time without maintaining version files.
Feature Branches: 0.{CRC32(branch_name)}.{GitDistance}
Feature branches get ephemeral versions. The minor component is a CRC32 hash of the branch name, and the patch is the commit distance from the trunk branch.
Main Branch: Major.Minor.Patch
The main branch follows Semantic Versioning 2.0.0. Bumps are determined by [MAJOR], [MINOR], or [PATCH] tags in commit messages.
Dynamic Version in pyproject.toml
Use semver-ratchet as your build backend for fully automatic versioning:
[build-system]
requires = ["semver-ratchet", "setuptools>=79.0.1"]
build-backend = "semver_ratchet.build"
[project]
name = "your-project"
dynamic = ["version"]
When setuptools builds your project, it calls semver_ratchet.build.get_version() which reads git state and returns the calculated version.
Alternative: Build-time Script
# setup.py or build script
import subprocess
def get_version():
result = subprocess.run(
["semver-ratchet", "version", "--no-verify"],
capture_output=True, text=True, check=True
)
return result.stdout.strip()
Installation
As a CLI Tool
uv pip install semver-ratchet
As a Library Dependency
# pyproject.toml
[project]
dependencies = ["semver-ratchet"]
As a Build Backend
[build-system]
requires = ["semver-ratchet", "setuptools>=79.0.1"]
build-backend = "semver_ratchet.build"
[project]
dynamic = ["version"]
Usage
CLI
# Get current version
semver-ratchet version
# With custom trunk name
semver-ratchet --trunk-name develop version
# Skip git history verification
semver-ratchet --no-verify version
# Display versioning info
semver-ratchet info
# Create and push tag
semver-ratchet tag --push
Module
python -m semver_ratchet version
Library API
import semver_ratchet
# Get current version
version = semver_ratchet.get_version()
print(version) # e.g., "1.0.0" or "0.12345678.5"
# With custom trunk name
version = semver_ratchet.get_version(trunk_name="develop")
# Get compatible versions for dependency pinning
compatible = semver_ratchet.get_compatible_versions("1.2.3")
print(compatible) # ["1.2.3", "1.2", "1"]
# Calculate CRC32 of a branch name
crc32 = semver_ratchet.calculate_crc32_unsigned("feature/login")
# Create a git tag (main branch only)
semver_ratchet.create_git_tag("1.0.0")
# Push tag to remote
semver_ratchet.push_git_tag("1.0.0")
# Verify git history
semver_ratchet.verify_git_history(50)
Configuration
Config Precedence Chain
CLI flag > Environment variable > pyproject.toml > Default
CLI Flags
| Flag | Description | Default |
|---|---|---|
--trunk-name <name> |
Trunk branch name | main |
--default-bump {major,minor,patch} |
Default bump type | patch |
--no-verify |
Skip git history verification | false |
Environment Variables
| Variable | Description | Default |
|---|---|---|
RATCHET_TRUNK_NAME |
Trunk branch name | main |
RATCHET_DEFAULT_BUMP |
Default bump type | minor |
RATCHET_GIT_PATH |
Custom git binary path | git |
RATCHET_VERIFY_MINDEPTH |
Minimum git history depth | 50 |
RATCHET_MANUAL_VERSION |
Manual version override | (none) |
RATCHET_OVERRIDE |
(deprecated) Same as above | (none) |
Config File (pyproject.toml)
[tool.semver-ratchet]
trunk-name = "main"
default-bump = "minor"
verify-mindepth = 50
git-path = "/usr/local/bin/git"
Keys accept both kebab-case and snake_case.
API Reference
get_version(default_bump=None, verify_history=True, trunk_name=None, adapter=None)
Get the appropriate version based on current branch.
- Parameters:
default_bump(str, optional): Default bump typeverify_history(bool): Verify sufficient git history (default:True)trunk_name(str, optional): Trunk branch name overrideadapter(GitAdapter, optional): Custom git adapter (for testing)
- Returns:
str— Version string
calculate_feature_version(verify_history=True, trunk_name=None, adapter=None)
Calculate version for a feature branch.
- Returns:
str— Version in format0.{CRC32}.{Distance}
calculate_main_version(default_bump="patch", verify_history=True, trunk_name=None, adapter=None)
Calculate version for main branch using SemVer.
- Returns:
str— Version in formatMajor.Minor.Patch
get_compatible_versions(version)
Generate compatible version strings for dependency pinning.
- Parameters:
version(str) — Full version string - Returns:
list[str]— Array of compatible versions
calculate_crc32_unsigned(s)
Calculate CRC32 checksum as unsigned 32-bit integer.
- Parameters:
s(str) — String to hash - Returns:
int— Unsigned 32-bit CRC32 value
get_current_branch(adapter=None)
Get the current Git branch name.
- Returns:
str
is_main_branch(trunk_name=None, adapter=None)
Check if current branch is the trunk branch.
- Returns:
bool
determine_version_bump(commit_messages, default_bump="patch")
Determine version bump from commit messages.
- Returns:
str—"major","minor", or"patch"
create_git_tag(version, force=False)
Create a Git tag for the given version.
- Returns:
bool
push_git_tag(version, remote="origin")
Push a Git tag to remote repository.
- Returns:
bool
verify_git_history(fetch_depth=50)
Verify sufficient git history is available.
- Raises:
RuntimeErrorif insufficient history
parse_semver(version)
Parse a SemVer string into components.
- Returns:
tuple[int, int, int]—(major, minor, patch)
compare_semver(v1, v2)
Compare two SemVer versions.
- Returns:
int—-1if v1 < v2,0if equal,1if v1 > v2
Testing
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=semver_ratchet
# Type checking
uvx ty check
# Linting
uvx ruff check .
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 semver_ratchet-1.3.2.tar.gz.
File metadata
- Download URL: semver_ratchet-1.3.2.tar.gz
- Upload date:
- Size: 31.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8595beaad7ba1407d8a30fc5ca164ef93dc6169242be7793ea2bf2de25a4a58
|
|
| MD5 |
cac622d75beb5c804e2fea095b100aba
|
|
| BLAKE2b-256 |
36490fb6a86f877f69a82fcbce9c4fc2b6a55688eeaa6f7c2c32475c13d507d0
|
File details
Details for the file semver_ratchet-1.3.2-py3-none-any.whl.
File metadata
- Download URL: semver_ratchet-1.3.2-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed2bc06168b7a128012a656a3aee316c4920adde5b34b788cd335a6c3b486670
|
|
| MD5 |
e8c5478355f82a8a3a44531758245f72
|
|
| BLAKE2b-256 |
eff3972516e66a696f1484156ae64fb00638c2a3e214d1e82bee93cdc5951b66
|