Skip to content

Configuration reference

Verso reads verso.toml from the current directory unless --config <PATH> or --group <NAME> is supplied. --config accepts a relative or absolute file path, while --group core selects verso.core.toml. The selected file's directory becomes the release root: package patterns, manifests, changelog, hooks, and Git commands all resolve from there.

Unknown tables and keys are rejected. Paths and patterns written inside verso.toml must be relative to the release root, use forward slashes, and cannot contain parent-directory (..) segments.

Default configuration

tomlverso.toml
[version]root_package = "package.json"require_consistent_versions = truecargo_manifest_paths = [][workspaces]patterns = []include_root = trueignore = []use_gitignore = true[changelog]enabled = falseinfile = "CHANGELOG.md"preset = "angular"[git]require_clean_worktree = truecommit_message = "chore(release): release v${version}"tag_name = "v${version}"push = "atomic"[hooks]# before_version = "pnpm test"# after_version = "pnpm build"# before_commit = "pnpm lint"# after_commit = "node scripts/verify-release.mjs"# before_tag = "pnpm pack"# after_tag = "node scripts/record-tag.mjs"# before_push = "pnpm check"# after_push = "node scripts/notify.mjs"

Every table and key is optional. When the default config path is absent and a root package manifest exists, Verso uses these values without creating a file. An explicitly supplied missing config is always an error.

Workspace discovery

When workspaces.patterns is empty, Verso first reads packages from pnpm-workspace.yaml, then the root manifest's workspaces field. If neither defines patterns, only the root package is used.

KeyDefaultBehavior
patterns[]Include globs; supports *, **, ?, character classes, braces, and leading ! exclusions
include_roottrueInclude the manifest selected by version.root_package
ignore[]Exclude matching paths; a plain segment such as fixtures excludes that directory name anywhere
use_gitignoretrueHonor root and nested .gitignore files while walking

node_modules and .git are always excluded. If include_root = false, patterns must be explicit and nonempty; inferred workspace patterns are not accepted for that combination.

Set include_root = false when the root manifest only describes the workspace and should not share the release group's version.

Each matched directory contributes the first existing manifest in this order: package.json, package.json5, package.yaml, package.yml. Verso changes only the top-level version scalar and preserves the rest of the file's formatting.

Version sources

KeyDefaultBehavior
root_packagepackage.jsonProvides the current version and joins the update when include_root is enabled
require_consistent_versionstrueMust remain true; rejects members whose versions differ so the group has one current version
cargo_manifest_paths[]Updates each manifest's [package].version and its nearest ancestor Cargo.lock, when present

When the default root_package does not exist, Verso may resolve another supported manifest in the release root. A custom root_package is used exactly as configured.

Release groups

One config defines one release group. Every package and configured Cargo manifest discovered by that config receives the same target version. version.require_consistent_versions must remain true; setting it to false is rejected because it would make the group's current version ambiguous.

Use separate configs for independently versioned groups and run one group at a time:

text
verso.core.toml  -> verso --group core bump minorverso.ui.toml    -> verso --group ui --version 2.0.0 --yes

For a named group, the default v${version} template is automatically scoped with the group name: core-v1.2.3, ui-v1.2.3, and so on. An explicitly different git.tag_name is used unchanged.

--group <NAME> and --config <PATH> are mutually exclusive. Group names start with an ASCII letter or digit and may otherwise contain ASCII letters, digits, -, and _.

Changelog

Set changelog.enabled = true to add a release entry to changelog.infile. changelog.preset accepts angular and keep-a-changelog. Changelog generation runs only for a full release; verso bump leaves the file unchanged.

For either preset, Verso finds the highest reachable SemVer tag matching git.tag_name, reads non-merge commits after it, and classifies Conventional Commit subjects. The angular preset uses:

  • fix -> Bug Fixes
  • feat -> Features
  • perf -> Performance Improvements
  • ! or a BREAKING CHANGE: footer -> BREAKING CHANGES
  • other conventional types -> a type-specific Other Changes section
  • non-conventional commits -> omitted

GitHub compare, commit, and issue links are added when the origin remote is a recognized GitHub SSH or HTTPS URL. An empty classified set produces No classifiable changes.

The keep-a-changelog preset inserts each release immediately after ## [Unreleased] and maps feat to Added, fix to Fixed, and performance, breaking, and other conventional changes to Changed. It also updates the [Unreleased] and release link definitions when a GitHub origin is available.

Git policy

KeyDefaultBehavior
require_clean_worktreetrueRequires git status --porcelain to be empty before writes
commit_messagechore(release): release v${version}Replaces every ${version} placeholder with the target
tag_namev${version}Must contain ${version}; named groups scope this default with the group name
pushatomicPushes the current upstream branch and exact release tag in one atomic command

With require_clean_worktree = false, unrelated unstaged files are allowed, but the index and every release file must still be clean. No non-atomic push mode exists.

Hooks are trusted shell commands

Hooks run from the release root through sh -c on macOS/Linux and cmd /C on Windows. Empty strings are treated as disabled. A nonzero exit stops the release at that stage.

verso bump runs only before_version and after_version; commit, tag, and push hooks belong to a full release.

Copyright © 2026 白熱.