CVM - Crate Version Manager
A powerful command-line tool for managing semantic versioning of Rust crates in both single-crate and workspace projects.
Features
- ๐ Interactive Version Bumping: Select crates and bump types (major, minor, patch) interactively
- ๐ฆ Workspace Support: Manage multiple crates in a Cargo workspace
- ๐ Change Queue System: Stage version changes and apply them all at once
- ๐งช Prerelease Mode: Built-in support for canary/alpha/beta releases with automatic prerelease numbering
- ๐ Change Summaries: Require descriptions for all version changes
- ๐ฏ Semantic Versioning: Full compliance with SemVer specification
Installation
Or build from source:
Quick Start
Initialize CVM in your project
This creates:
.cvm/config.toml- Configuration file.cvm/changes/- Directory for pending version changes.cvm/README.md- Information about CVM
Basic Workflow
-
Initialize CVM (first time only):
-
Stage a version change (interactive mode):
This will prompt you to select crates and bump types (major, minor, or patch).
-
Apply all staged changes:
By default, this creates git tags. Configure in
.cvm/config.tomlor use--no-git-tagsto disable.
Prerelease Workflow
-
Start prerelease mode:
This saves the current version as the base and enables prerelease mode.
-
Stage and apply changes (they will be prerelease versions):
-
Exit prerelease mode when ready for production:
How It Works
Change Queue
When you run cvm without arguments, it creates timestamped change files in .cvm/changes/. Each file contains:
- A summary of the change
- Which crates to bump (major, minor, or patch)
- Whether it was created in prerelease mode
Running cvm apply processes all change files in chronological order and updates the Cargo.toml files accordingly.
Prerelease Mode
Prerelease mode intelligently handles version bumps:
Example flow starting from 0.1.0:
Then applying changes sequentially:
patchโ0.1.0-canary.0(first prerelease of this base)patchโ0.1.0-canary.1(increments prerelease number)minorโ0.2.0-canary.0(new base: 0.1.0 + minor = 0.2.0)patchโ0.2.0-canary.1(same base, increment number)minorโ0.2.0-canary.2(base 0.1.0 + minor = 0.2.0, same as current)majorโ1.0.0-canary.0(new base: 0.1.0 + major = 1.0.0)
Rules:
- PATCH in prerelease: Always keeps the current base version, increments prerelease number
- MINOR/MAJOR in prerelease: Calculates new base from stored base version
- If different from current base: applies bump and resets to
.0 - If same as current base: increments prerelease number
- If different from current base: applies bump and resets to
Commands
cvm setup
Initialize CVM in the current project. Creates configuration files and directories.
Example:
Output:
โ
CVM initialized successfully!
Configuration file created at: .cvm/config.toml
Change files will be stored in: .cvm/changes/
Next steps:
1. Run 'cvm' to create version changes interactively
2. Run 'cvm apply' to apply pending changes
3. Run 'cvm status' to check for pending changes
cvm (no arguments)
Interactive mode to select crates and bump types. Creates a change file in .cvm/changes/.
Example:
# Select crates for major bump: [none]
# Select crates for minor bump: [my-crate]
# Select crates for patch bump: [none]
# Summary: Add new feature X
cvm apply
Applies all pending changes in chronological order.
Example:
# Applying update: Add new feature X
# my-crate minor โ 0.2.0
# All updates applied successfully!
cvm pre start [identifier]
Enables prerelease mode with the specified identifier (e.g., canary, alpha, beta, rc).
Examples:
cvm pre exit
Disables prerelease mode and clears stored base versions.
Example:
# Prerelease mode exited.
File Structure
your-project/
โโโ .cvm/
โ โโโ config.toml # CVM configuration
โ โโโ changes/ # Pending version changes
โ โ โโโ 1234567890.toml
โ โ โโโ 1234567891.toml
โ โโโ README.md # Auto-generated info
โโโ Cargo.toml
โโโ src/
.cvm/config.toml
Stores CVM configuration:
# CVM Configuration
[]
# Automatically create git tags when applying version changes
= true
[]
= true
= "canary"
[]
= "0.1.0"
.cvm/changes/1234567890.toml
[]
= "Add new feature X"
= []
= ["my-crate"]
= []
= false
Use Cases
Single Crate Project
Perfect for managing versions of a single library or binary crate.
Workspace Project
Manage multiple related crates with independent versioning:
- Select which crates to bump
- Different bump types for different crates
- Apply all changes atomically
Continuous Deployment
- Developers stage changes with
cvmas they work - CI/CD applies changes with
cvm applybefore publishing - Prerelease mode for canary deployments
Release Management
- Use prerelease mode for beta testing
- Stage multiple changes before release
- Apply all changes at once when ready
CI/CD Integration
CVM is designed to work seamlessly in CI/CD pipelines. Here's a typical workflow:
Checking for Pending Changes
Use cvm status to check if there are pending version changes:
- Exit code 0: No pending changes
- Exit code 1: There are pending changes (useful for CI conditionals)
Dry Run
Preview what would be applied without making changes:
Example GitHub Actions Workflow
name: Version Management
on:
push:
branches:
jobs:
apply-versions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install CVM
run: cargo install cvm
- name: Check for pending changes
id: check
run: |
if ! cvm status; then
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
- name: Apply version changes
if: steps.check.outputs.has_changes == 'true'
run: cvm apply
- name: Commit changes
if: steps.check.outputs.has_changes == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Cargo.toml */Cargo.toml
git commit -m "chore: apply version bumps"
git push
See .github-workflows-example.yml for more complete examples including:
- Creating PRs for version bumps
- Canary releases with prerelease mode
- Multi-crate workspace handling
Typical CI/CD Flow
-
Development Branch (
canary):- Developers create changes:
cvmโ select crates โ add summary - Commit changes to
.cvm/changes/directory - Push to canary branch
- Developers create changes:
-
CI Pipeline Runs:
- Check for pending changes:
cvm status - Apply changes:
cvm apply - Run tests with new versions
- Create PR to main or commit directly
- Check for pending changes:
-
Production Branch (
main):- Merge PR with version bumps
- Tag release
- Publish to crates.io
Best Practices
- Always add meaningful summaries: They serve as a changelog for your version bumps
- Use prerelease mode for testing: Test breaking changes with canary releases
- Commit
.cvm/to version control: Share pending changes with your team - Apply changes before publishing: Run
cvm applybeforecargo publish - Use
--dry-runin CI: Preview changes before applying them - Check status in pipelines: Use
cvm statusexit codes for conditional logic
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Authors
- BlitzForge
- Lucas Arch luketsx@icloud.com