After committing the next change:

August 3, 2026 · View on GitHub

vmn

Restorable release state across Git repositories.

Language-agnostic version management for products that span repositories.
Record a release once. Restore its source state later with one command.

PyPI version Supported Python versions MIT license

pipx install vmn

vmn stamp -r patch my_app       # 0.0.1

# Restore the application and every configured dependency repository.
vmn goto -v 0.0.1 my_app

vmn stores release metadata as readable YAML in annotated Git tags. Each tag records the application revision, dependency revisions, previous version, and release context. There is no vmn server and no external metadata database.

Developed continuously since 2019, vmn is used in daily production workflows by teams at large companies managing multi-repository products. vmn versions its own releases. The repository contains more than 400 tests, including Docker-backed multi-repository, recovery, and compatibility scenarios.

Quick start · Why vmn · Multi-repository recovery · Operations · Commands · Documentation

Why vmn

RequirementWhat vmn provides
Recover a recorded multi-repository source statevmn goto restores the application and its configured dependencies to their recorded Git revisions.
Keep release data inspectableAnnotated tags contain readable YAML and use the namespaced form <app>_<version>.
Version mixed technology stacksvmn operates on Git repositories, not a language-specific package manager or build system.
Release services independentlyRoot apps group independently versioned services under a monotonic composition version.
Work without a hosted control planeA standard Git remote is enough; internal and air-gapped Git servers are supported.
Adopt without replacing build toolingVersion backends update npm, Cargo, Poetry, PEP 621, Jinja2, or regex-selected files.

vmn treats a version as a handle to recorded source state, not only as a string. The same model supports releases, working snapshots, and measured runs:

StateCommandCaptures
Releasevmn stampvmn gotoCommitted application and dependency revisions
Workingvmn snapshotRelease state plus local commits, tracked changes, and untracked files
Measuredvmn expWorking state plus metrics, parameters, artifacts, and run history

Scope: vmn restores recorded source revisions. It does not rebuild artifacts, capture toolchains or runtime infrastructure, sign tags, or deploy software. Keep those responsibilities in your build, signing, and deployment pipeline.

Quick start

Requirements

  • Python 3.8 or newer
  • Git 2.10 or newer; Git 2.17+ is recommended
  • A Git repository with at least one commit and a writable remote

Install vmn as an isolated command-line tool:

pipx install vmn
# Alternative: uv tool install vmn

vmn --completion-install   # bash/zsh/fish/tcsh; auto-detects shell

Inside any Git repository:

vmn stamp -r patch my_app       # 0.0.1; initializes on first use
vmn show my_app                 # 0.0.1

# After committing the next change:
vmn stamp -r minor my_app       # 0.1.0

# After committing another change:
vmn stamp -r patch --pr rc my_app  # 0.1.1-rc.1
vmn release my_app              # 0.1.1

A successful stamp creates a version commit, creates annotated tags, and pushes the branch and tags. Use --dry-run to inspect the operation first. Repeated stamping of an already-versioned state is idempotent.

Inspect the source of truth directly:

git tag --list 'my_app_*'
git cat-file -p my_app_0.1.0
vmn show --verbose my_app

No separate vmn init is required. Explicit init and init-app commands remain available for migrations and non-default starting versions.

Multi-repository recovery

Your product spans 4 repos. Production broke after the 2.1.0 deploy last Tuesday. You need the exact source state — not just one repo, all of them — to reproduce and fix the bug. One command:

vmn goto -v 2.1.0 my_platform

Every configured dependency is restored to its recorded revision, cloning any that are missing locally. No container archaeology, no CI log diving.

Setup

Declare sibling dependency repositories in .vmn/my_app/conf.yml:

conf:
  deps:
    ../:
      lib_core:
        vcs_type: git
      service_api:
        vcs_type: git

Stamping records the exact revision and remote for every dependency:

vmn stamp -r minor my_app

# Later, from any other revision:
vmn goto -v 1.4.0 my_app

goto restores all recorded repositories and can clone a missing dependency. Use --pull when the requested refs are not available locally, or --deps-only to leave the application repository unchanged.

Do not embed credentials in Git remote URLs: dependency remotes are part of release metadata. Use SSH, a Git credential helper, or vmn's per-command push credentials instead.

Release models

vmn supports SemVer-based release and prerelease workflows plus explicit vmn extensions:

1.6.0                         release
1.6.0-rc.23                   prerelease
1.6.7.4                       optional fourth hotfix segment
1.6.0-rc.23+build01           build metadata
1.6.0-dev.a1b2c3d.e4f5g6h     working-state snapshot

Enable Conventional Commits, changelog generation, GitHub Releases, branch policy, and version embedding in the app configuration:

conf:
  conventional_commits: true
  default_release_mode: optional
  changelog:
    path: CHANGELOG.md
  github_release:
    draft: true
  policies:
    whitelist_release_branches: [main]
  version_backends:
    pep621:
      path: pyproject.toml

With conventional_commits enabled, fix: selects patch, feat: selects minor, and a type!: header selects major. GitHub Release creation requires the gh CLI and GITHUB_TOKEN or GH_TOKEN; it is best-effort and warns rather than failing an otherwise successful stamp.

For independently deployed services, use a root app:

vmn stamp -r patch platform/auth       # auth 0.0.1; platform 1
vmn stamp -r minor platform/billing    # billing 0.1.0; platform 2
vmn show --root platform               # 2

Branch-specific configuration

Integration branches can override dep pinning without touching the main config:

vmn config gen my_app --branch                  # create branch conf for current branch
vmn config gen my_app --branch --sync-dep-branches  # auto-pin deps to their checked-out branches
vmn config my_app --branch                      # edit interactively

Branch confs are resolved automatically at stamp time. The canonical layout is .vmn/<app>/branch_conf/<branch>/conf.yml (branch slashes become directories).

Production operation

vmn is designed for release automation where failure must be visible and recoverable:

  • --dry-run previews a stamp without committing or tagging.
  • Dirty, detached, outgoing, and dependency states are checked before release.
  • A per-repository lock prevents concurrent local vmn operations.
  • Release-branch allowlists restrict stable stamps to configured branches.
  • --pull fetches remote state and retries version conflicts.
  • vmn rolls back newly created local release state when publication fails.
  • Release metadata remains readable with standard Git and YAML tooling.
  • No internet access is required when an internal or local Git remote is used.

For GitHub Actions, use the official vmn-action:

steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: 0

  - id: vmn
    uses: progovoy/vmn-action@latest
    with:
      app-name: my_app
      do-stamp: true
      stamp-mode: patch
    env:
      GITHUB_TOKEN: ${{ github.token }}

  - run: echo "Stamped ${{ steps.vmn.outputs.verstr }}"

For other CI systems, fetch complete history and tags, serialize stamps for the same app, and provide write access to the remote:

pip install vmn
vmn stamp --pull -r patch my_app

Start an established migration with --dry-run; then add branch policy before enabling automatic stamps.

Working-state snapshots

Between releases, capture and restore your exact working state — uncommitted changes, local commits, and untracked files — as a named version:

vmn snapshot create my_app --note "parser refactor"
vmn snapshot restore my_app --latest

Snapshots extend the same state-recovery model as goto to uncommitted work. Local-first experiment tracking (vmn exp) builds on snapshots to capture metrics alongside code state; see docs/experiments.md.

Install vmn[ui] for a local web dashboard with stamp-tree views and snapshot comparison.

Islands (parallel worktrees)

Create isolated development environments — git worktrees for your repo and every dependency — pinned to a known-good state:

vmn worktrees create my_app --island-name feature-auth
vmn worktrees create my_app --island-name feature-perf
vmn worktrees list
vmn worktrees remove feature-auth

Each island gets its own branch, an island.json manifest with paths and dependency hashes, and full stamping capability. Use --no-stamp for read-only islands. Works well with AI coding agents — each agent gets its own island and cannot touch other agents' files.

AI agent integration

vmn ai gives AI coding agents the context they need to use vmn correctly:

vmn ai skill --install                  # .claude/skills/vmn/SKILL.md
vmn ai skill --install --target cursor  # .cursorrules
vmn ai skill --install --target agents  # AGENTS.md

# Composable development methodology rules
vmn ai methodology --tdd --minimal-diffs --install
vmn ai methodology --testability --worktrees --errors --install --target cursor

vmn ai skill outputs CLI usage instructions. vmn ai methodology outputs opinionated development rules — pick only what applies to your team: --tdd, --testability, --boyscout, --worktrees, --communication, --minimal-diffs, --errors.

The legacy vmn skill command remains as an alias for vmn ai skill. Re-running --install updates vmn's section and leaves the rest of your instructions untouched.

Command map

CommandPurpose
vmn stampCompute, create, and publish a version
vmn releasePromote a prerelease to a final release
vmn showRead version, status, or effective configuration
vmn gotoRestore recorded application and dependency revisions
vmn snapshotCapture, inspect, compare, export, or restore working state
vmn expTrack experiments built on working-state snapshots
vmn worktreesCreate, list, or remove isolated parallel development islands
vmn aiOutput or install AI agent skill blocks and methodology rules
vmn addAttach build metadata to an existing version
vmn genRender a file from a Jinja2 template
vmn configList or edit global, app, root-app, and branch configuration
vmn uiRun the optional web dashboard

Run vmn --help or vmn <command> --help for the authoritative flag reference.

Documentation

Project

vmn is open source under the MIT License. Issues, questions, and pull requests are welcome; see the contributing guide and the issue tracker.