Skip to content

Configuration ​

Versionary reads configuration from versionary.jsonc (preferred) or versionary.json at the repository root. These are the only supported filenames. The schema is strict—unknown keys are rejected.

Editor support ​

Add a $schema reference for autocomplete and validation:

jsonc
{
  "$schema": "https://raw.githubusercontent.com/jolars/versionary/main/schemas/config.json",
  "version": 1,
  "release-type": "node"
}

The published schema is generated from Versionary's internal Zod schema, which is the single source of truth for the config shape.

Top-level keys ​

KeyTypeDefaultDescription
version1— (required)Config-format version. Must be 1.
$schemastring—JSON Schema URL for editor support.
release-typestring | string[]"simple"The strategy (or array of strategies) used to read/write versions.
review-mode"direct" | "pr""pr"Release style. pr opens a release PR; direct commits to the triggering branch and publishes in one run. See workflows.
release-pr-checks"run" | "skip""run"Whether the CI integration runs checks on Versionary release PRs. Requires workflow integration.
release-mode"versionary" | "external""versionary"Who creates tags and release metadata. external emits the merged commit and notes, then waits for downstream tags. See Julia packages.
version-filestringstrategy-specificPath to the primary version source. Default depends on release-type (see table below).
changelog-filestringCHANGELOG.md / NEWS.mdPath to the changelog. Defaults to NEWS.md for the R strategy, CHANGELOG.md otherwise.
changelog-format"markdown-changelog" | "r-news"strategy-specificChangelog format. Defaults to r-news for the R strategy, markdown-changelog otherwise.
release-branchstring"versionary/release"Branch used for the release PR/commit and prefix for separate package PRs. See selective CI.
separate-release-prsbooleanfalseOpen an independent release PR for each releasable package or coupled package cohort. See monorepos.
baseline-filestring".versionary-manifest.json"File tracking the baseline SHA for deterministic commit ranges.
bootstrap-shastring—First-run baseline commit when adopting Versionary on existing history.
release-draftbooleanfalsePublish GitHub Releases as drafts.
release-latestbooleantrue for root; false otherwiseRequest GitHub Latest promotion for new releases. See inheritance.
release-reference-comments"off" | "best-effort" | "strict""off"Whether to comment on linked issues/PRs when released. See below.
monorepo-mode"independent" | "fixed"—Enables monorepo planning.
packagesobject—Per-package configuration (see packages).
allow-stable-majorbooleanfalseAllow a breaking 0.y.z release to become 1.0.0. See pre-1.0 policy.
exclude-pathsstring[]—Glob/path prefixes whose changes don't, on their own, count toward a bump. Applies repo-wide and to every package.
commit-overridesobject—Exclusions or replacement messages keyed by full commit SHA. See commit overrides.
include-commit-authorsboolean—Accepted by the schema; not yet wired into changelog rendering.

release-pr-checks ​

Set "skip" to let Versionary's CI integration skip expensive checks on its release PRs. The default, "run", keeps checks enabled. This is a repository-wide policy shared by combined release PRs and separate package or cohort PRs.

The setting takes effect through versionary ci --json or the Action's command: ci mode. Wire build, test, and lint jobs to the decision's run_checks output using the workflow recipe. Adding the setting alone does not change GitHub's workflow rules.

Versionary skips checks only when the event identifies a release branch in the same repository. Ordinary PRs, fork PRs, pushes after merging, and unknown event contexts keep checks enabled. Direct release mode always runs checks. Invalid configuration fails the decision command rather than producing a skip result.

commit-overrides ​

Correct release metadata for commits that have already landed without rewriting Git history. Each key is a full, lowercase commit SHA. Each value contains either skip: true or a message, plus an optional reason:

jsonc
{
  "version": 1,
  "commit-overrides": {
    "0123456789abcdef0123456789abcdef01234567": {
      "skip": true,
      "reason": "Fixes a regression introduced after the previous release"
    },
    "89abcdef0123456789abcdef0123456789abcdef": {
      "message": "perf: cache commit lookups",
      "reason": "The original commit was incorrectly labeled feat"
    }
  }
}

skip: true excludes the commit from both version calculation and generated release notes, including any Release-As footer. Its code still ships. message replaces the complete message used for release analysis and notes, including the body and footers. Include any breaking markers or issue references that should remain. The replacement must be a valid Conventional Commit. Versionary preserves the original SHA and uses the original changed files to attribute the commit to packages. Existing suppression of revert pairs still uses the original commit relationships.

Overrides apply only within each package's unreleased commit window. They do not change earlier releases. Configured SHAs must resolve to commits in the current branch's history. versionary plan includes a commitOverrides array with the original messages, overrides, reasons, and package paths where they still apply. An empty packages array means the override has been consumed.

The exclude and correct commands accept short SHAs and write these entries while preserving JSONC comments. Commit the configuration change so local planning and CI use the same metadata. To undo an override before release, remove its entry.

Versionary removes consumed entries during a later release's preparation. In a monorepo, it retains an entry while any configured package still has the commit in its release window. Cleanup does not require unrelated package release PRs to merge together.

Deprecated: bump-minor-pre-major ​

bump-minor-pre-major remains accepted at the repository root and package level for compatibility with Versionary 1.3.0. Versionary warns when it is used and immediately normalizes it to allow-stable-major:

  • bump-minor-pre-major: true becomes allow-stable-major: false.
  • bump-minor-pre-major: false becomes allow-stable-major: true.

Replace the deprecated key with the corresponding canonical value. Do not configure both keys in the same object; Versionary rejects that ambiguity.

release-reference-comments ​

Controls comments posted on issues/PRs referenced by released commits:

  • off (default) — don't post comments.
  • best-effort — post comments, but continue if the API call fails (e.g. missing permissions).
  • strict — fail the release if a comment can't be posted.

Comments require issues: write permission and are authored by the account that owns the configured token. The comment body itself is signed by Versionary.

Default version files by strategy ​

release-typeDefault version-file
simpleversion.txt
cmakeCMakeLists.txt
nodepackage.json
rustCargo.toml
rDESCRIPTION
pythonpyproject.toml
juliaProject.toml
latexbuild.lua

See Strategies for the full behavior of each.

packages ​

A map keyed by package path ("." for the repository root). Used with monorepo-mode. Each entry inherits the top-level config and may override:

KeyTypeDescription
release-typestring | string[]Strategy for this package, overriding the top-level value.
package-namestringOverride the release/tag name (otherwise derived from the version file or path).
changelog-filestringPackage-specific changelog path (written under the package directory).
changelog-format"markdown-changelog" | "r-news"Package-specific changelog format.
allow-stable-majorbooleanOverride the pre-1.0 policy for this package's own bump.
exclude-pathsstring[]Paths (relative to the package) to exclude; unioned with the top-level list.
followsstring[]Source packages this package follows; see follows.
extra-filesartifact-rule[]Additional files to update with the new version (see below).
release-draftbooleanOverride whether this package's GitHub Release is created as a draft.
release-latestbooleanOverride whether this package's new GitHub Release requests Latest promotion.

See the monorepos guide for tag naming, follows, and filtering semantics.

release-draft ​

Package-level release-draft values override the top-level setting. Packages that omit the key inherit the top-level value; if neither level sets it, Versionary creates a non-draft release. An explicitly configured root package at "." follows the same rule.

This allows packages with different publication gates to share one monorepo configuration:

jsonc
{
  "version": 1,
  "release-type": "simple",
  "monorepo-mode": "independent",
  "separate-release-prs": true,
  "release-draft": false,
  "packages": {
    "packages/python": {
      "release-type": "python"
    },
    "packages/r": {
      "release-type": "r",
      "release-draft": true
    },
    "packages/julia": {
      "release-type": "julia",
      "release-draft": true
    }
  }
}

Here, the Python package inherits false, while the R and Julia packages create draft GitHub Releases. Draft selection does not change package grouping or release PR planning.

release-latest ​

Controls whether a new GitHub Release requests Latest promotion. The setting applies in both PR and direct release workflows. Versionary resolves it for each release target in this order:

  1. The package's release-latest, including an explicit root package at ".".
  2. The top-level release-latest.
  3. true for the root package and false for other packages.

An explicit false overrides an inherited true. For example, this configuration promotes only the root package's releases:

jsonc
{
  "version": 1,
  "release-type": "node",
  "monorepo-mode": "independent",
  "release-latest": false,
  "packages": {
    ".": { "release-latest": true },
    "packages/helper": {}
  }
}

GitHub has one Latest release per repository. Setting the top-level value to true makes every inheriting package request promotion, so use package overrides when only one package should hold that designation. GitHub does not allow drafts or prereleases to become Latest.

For a maintenance branch, set release-latest: false to keep its releases from replacing the current line's Latest release. This setting does not change version calculation or mark a release as a prerelease. Registry publishing and website deployment use their own policies.

Retries apply the configured policy when creating missing release metadata. Existing GitHub Releases are reused without changing their metadata, so changing this setting does not retroactively promote or demote an existing release.

extra-files ​

extra-files (per package) updates additional files to the new version. Each rule is an artifact rule:

FieldTypeApplies toDescription
typeenumallOne of json, toml, yaml, nix, regex.
pathstringallPath to the file to update.
field-pathstringjson/toml/yaml/nixJSONPath-style locator of the version field (e.g. $.version). Required for these types.
patternstringregexRegex with a capturing group (or a named (?<version>…) group) around the version. Required for regex.
replacementstringregexOptional template for the substituted text. When set, the entire match is replaced with the rendered template.
expected-matchespositive integerregexExact number of occurrences the pattern must match. Defaults to 1.

Validation rules enforced by the schema:

  • json/toml/yaml/nix rules require field-path and must not use pattern or replacement.
  • regex rules require pattern and must not use field-path.
  • expected-matches is available only for regex rules and must be a positive integer.

Regex substitution ​

Without a replacement, the first capturing group is replaced with the full computed version, leaving the rest of the match intact. This keeps a full [email protected]-style reference in sync.

By default, the pattern must match exactly once. Set expected-matches when a file intentionally contains several occurrences. Versionary updates every match and aborts if the actual count differs, guarding against missing or overly broad matches.

With a replacement, the whole match is replaced by the rendered template. The following placeholders are available:

TokenValue
the full computed version (1.2.3)
the major component (1)
the minor component (2)
the patch component (3)
dot-joined prerelease identifiers
dot-joined build-metadata identifiers

This is useful for major-only references such as a moving @v1 tag, which should only advance on a major release:

jsonc
{
  "type": "regex",
  "path": "README.md",
  "pattern": "jolars/panache-action@v(\\d+)",
  "replacement": "jolars/panache-action@v{{major}}"
}

On a 2.0.0 release this rewrites @v1 to @v2 (not @v2.0.0).

Example — keep the action's pinned version in sync, plus a TOML manifest:

jsonc
{
  "version": 1,
  "release-type": "node",
  "packages": {
    ".": {
      "extra-files": [
        {
          "type": "yaml",
          "path": "action.yml",
          "field-path": "$.inputs.versionary-version.default"
        },
        {
          "type": "regex",
          "path": "README.md",
          "pattern": "versionary@(?<version>\\d+\\.\\d+\\.\\d+)"
        }
      ]
    }
  }
}

Validation errors ​

packages with follows are validated at load time. The following are configuration errors:

  • a package following itself
  • following an unknown package path
  • follows cycles (reported with the offending chain)
  • combining follows with monorepo-mode: "fixed"
  • enabling separate-release-prs without a non-empty packages map
  • combining separate-release-prs with monorepo-mode: "fixed" or review-mode: "direct"

Run versionary verify to check your config and version files before relying on them in CI.

Released under the MIT License.