Introduction
Monoverse is a tool for managing application version numbering using the CalVer versioning scheme. It is designed to be used with monorepos, but it can also be used with single projects.
The monoverse implementation of CalVer follows the YY.MM.MICRO format, where YY is the current year, MM is the current month, and MICRO is a monotonically increasing number that is reset to 0 at the beginning of each month.
Monoverse updates manifest files based on project type and uses git history to decide whether a new release is needed.
Installation
Cargo
Monoverse is written in Rust and requires the Rust toolchain. The easiest way to install Rust is with rustup.
Once Rust is installed, you can install the latest published release:
cargo install monoverse
You can also clone the repository and build the binary yourself:
cargo install --path .
Docker
Monoverse is available as a container image on GitHub Container Registry.
docker pull ghcr.io/jannekem/monoverse:latest
You can run the container against a local repository by mounting it to /repo:
docker run --rm -v /path/to/repository:/repo ghcr.io/jannekem/monoverse:latest release <project-name>
The container includes git, which makes it easier to integrate monoverse into CI/CD pipelines.
Quick start
Install monoverse first if you haven’t already. See Installation.
Create a monoverse.yaml file at the repository root, define your projects, then run a release.
Example:
projects:
server:
type: rust
path: server
client:
type: node
path: client
Release a project:
monoverse release server
Add the --commit and --tag flags if you want Monoverse to handle committing and tagging the changes.
Print the next version without editing files:
monoverse next server
List configured projects:
monoverse list
Configuration
Monoverse reads configuration from monoverse.{yaml,json,toml} at the repository root.
Project settings
Each project is defined in the projects map. The project key is the project name used in CLI commands.
| Key | Description | Notes |
|---|---|---|
type | The type of the project. | rust, node, helm, toml, versionfile, yaml |
path | The path to the project. | Defaults to repository root if omitted. |
manifest_path | The path to the manifest file of the project. | Overrides the default manifest path. |
tag_prefix | Prefix for tag creation. | Defaults to <project-name>-. |
selector | Selector for the version field. | Required for toml and yaml project types. |
dependents | Dependent files to update on release. | See Dependents. |
Project types
rust: A Rust project with aCargo.tomlmanifest file.node: A Node.js project with apackage.jsonmanifest file.helm: A Helm chart with aChart.yamlmanifest file. Usesversionfor release detection, updatesversionto the next CalVer, and updatesappVersionif present.toml: Any generic project with a TOML manifest file. Requiresmanifest_pathandselector.versionfile: Any generic project with a version file that only contains the version number. Requiresmanifest_path.yaml: Any generic project with a YAML manifest file. Requiresmanifest_pathandselector.
Examples
YAML:
projects:
server:
type: rust
path: server
client:
type: node
path: client
TOML:
[projects.server]
type = "rust"
path = "server"
[projects.client]
type = "node"
path = "client"
Selectors
Selectors point to the version field in yaml and toml projects and in yaml/helm dependents.
YAML selectors
- Dot-separated keys:
package.version - Sequence index:
dependencies[0].version - Sequence filter by key/value:
dependencies[name=common].version
Examples:
projects:
common:
type: yaml
manifest_path: charts/common/Chart.yaml
selector: version
dependents:
- type: helm
path: charts/laravel
selector: dependencies[name=common].version
Notes:
- The selector must resolve to a scalar value.
- Sequence filters return the first matching item.
- Keys containing
.or[are not supported by the selector syntax.
TOML selectors
Use dot-separated keys:
package.versiondependencies.serde.version
Helm workflows
Monoverse supports Helm charts both as projects and as dependents.
Helm projects
type: helm expects a chart with Chart.yaml and uses version for release detection. On release it updates:
versionto the next CalVerappVersionif present
The versioning is similar for both application and library charts.
Helm dependents
Use type: helm when a release should update a chart dependency version.
pathis the chart directory, notChart.yaml.- The selector targets the dependency entry in
Chart.yaml.
Example:
projects:
common:
type: yaml
manifest_path: charts/common/Chart.yaml
selector: version
dependents:
- type: helm
path: charts/laravel
selector: dependencies[name=common].version
Updating Chart.lock
monoverse can run helm dependency update when releasing to update Chart.lock and charts/*.tgz:
monoverse release common --helm-dependency-update
This requires Helm on PATH and may fetch dependencies.
Dependents
Dependents are files that are updated when a project is released.
Dependent settings
| Key | Description | Notes |
|---|---|---|
type | The type of the dependent. | regex, toml, yaml, helm |
path | The path to the dependent file. | For helm, use the chart directory. |
selector | Selector for the version number in the dependent file. | Required for toml, yaml, helm. |
replace | String to replace the selector match with. | Only for regex. |
Dependent types
regex
Uses a regex to replace a version string. The {{version}} special sequence will be replaced with the next version.
dependents:
- type: regex
path: README.md
selector: "nginx:.?\\d+\\.\\d+\\.\\d+"
replace: "nginx:{{version}}"
toml
dependents:
- type: toml
path: dependency.toml
selector: dependencies.server.version
yaml
dependents:
- type: yaml
path: deploy/config.yaml
selector: package.version
helm
dependents:
- type: helm
path: charts/laravel
selector: dependencies[name=common].version
If you need Chart.lock updates, use the --helm-dependency-update CLI option or run helm dependency update manually.
CLI
Usage: monoverse [OPTIONS] <COMMAND>
Commands:
release Release a project
next Print the next version for a project
list List projects
help Print this message or the help of the given subcommand(s)
Options:
--repo-path <REPO_PATH> Repository path [default: .]
-v, --verbose... Increase logging verbosity
-q, --quiet... Decrease logging verbosity
-h, --help Print help
-V, --version Print version
release
Create a new version for a project.
monoverse release <project>
Flags:
-f,--force: Force a release even if the project has no changes.--commit: Commit the changes to the repository.--tag: Create a tag, requires--commit.--helm-dependency-update: Runhelm dependency updateforhelmdependents.
next
Print the next version without modifying files:
monoverse next <project>
list
List all configured projects:
monoverse list
repo path
Use --repo-path to run from outside the repository root:
monoverse --repo-path /path/to/repo release server
Troubleshooting
“Key not found”
The selector did not resolve to a scalar value. Verify the selector path and ensure the key exists.
“Value is not a mapping” or “Value is not a sequence”
The selector expects a mapping or sequence but found a different YAML node type. Check the structure of the file.
Helm dependency update fails
- Ensure Helm is installed and available on
PATH. - The chart directory must be valid and contain
Chart.yaml. - If dependencies are remote, network access is required.
Version file modified
Monoverse refuses to release if the manifest file has uncommitted changes. Commit or stash the file, then retry.