Skip to content

feat(version): add optional fixed versioning mode - #1056

Draft
spydon wants to merge 3 commits into
mainfrom
feat/lockstep-versioning
Draft

feat(version): add optional fixed versioning mode#1056
spydon wants to merge 3 commits into
mainfrom
feat/lockstep-versioning

Conversation

@spydon

@spydon spydon commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds an optional fixed versioning mode (lockstep) to melos version, matching the "fixed" release mode of Nx and Lerna in the JavaScript ecosystem.

melos:
  command:
    version:
      mode: fixed  # defaults to: independent

When mode: fixed is enabled, every versioning run bumps all packages in the workspace to the same new version:

  • The new version is based on the highest current version in the workspace, incremented by the most significant change found in any package (a breaking change anywhere causes a major bump for all packages, a feature a minor bump, otherwise patch).
  • Packages with changes keep their regular conventional-commit changelog entries; packages without changes of their own get a changelog entry noting the bump keeps the workspace in lockstep, and are listed in a dedicated section of the workspace changelog.
  • A manually specified version (melos version <package> <version>) is applied to all packages. Relative manual bumps (patch/minor/major/build) are applied to the highest current version in the workspace, regardless of which package was named. Conflicting manual versions for different packages, or a manual version below a current package version, fail with a FixedVersioningException.
  • Packages already at the shared version are left untouched (no pubspec rewrite, no duplicate changelog entry).
  • Packages that depend on an ignored package with pending changes are skipped with a warning, mirroring independent mode's safeguard against broken releases.
  • Private packages are still skipped unless --all is passed, and dependency constraints on workspace packages are updated as usual. --no-dependent-versions has no effect in fixed mode and logs a warning.
  • Defaults to independent, so existing workspaces are unaffected.

Implementation notes

  • The independent per-package pending updates are computed as before and then unified into one update per package sharing a single version, so all existing behavior (graduation, prereleases, changelog rendering, tagging, dependent constraint updates) is reused.
  • New PackageUpdateReason.lockstep covers packages bumped only to stay in sync; it renders a dedicated changelog line and its own workspace changelog section.
  • The new VersioningMode enum (independent | fixed) is exported from the public API and leaves room for future modes (e.g. grouped/linked versioning).
  • Per-package git tags (foo-v1.2.3) are still created so change detection for future runs keeps working.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 📝 Documentation update (docs/commands/version.mdx, docs/configuration/overview.mdx, docs/guides/automated-releases.mdx, melos.yaml.schema.json)
  • ✅ Tests (config parsing/validation and 11 end-to-end fixed-mode versioning tests, including git-history-based bumps, manual versions, filters, and private packages)

Adds a new command/version/lockstep configuration option. When enabled,
every versioning run bumps all packages in the workspace to the same new
version, similar to the fixed release mode of tools like Nx and Lerna.

The lockstep version is the highest current version in the workspace,
incremented by the most significant change across all packages. Packages
without changes of their own are bumped too, with a changelog entry
noting that the bump keeps the workspace in lockstep. Manually specified
versions are applied to all packages, and conflicting or downgrading
manual versions are rejected.
@docs-page

docs-page Bot commented Jul 21, 2026

Copy link
Copy Markdown

To preview the documentation for this pull request, visit the following URL:

melos.invertase.dev/~1056

Documentation is deployed and generated using docs.page

spydon added 2 commits July 21, 2026 14:39
- Do not version packages that depend on an ignored package with
  pending changes, mirroring the skip logic of independent mode.
- Apply relative manual version changes (patch/minor/major/build) to
  the highest current version in the workspace instead of the named
  package's own version.
- Leave packages that are already at the lockstep version untouched
  instead of rewriting pubspecs and duplicating changelog entries.
- Warn that disabling dependent versioning has no effect in lockstep.
- Disable commit signing in the lockstep test git helper.
Aligns the configuration with the fixed/independent terminology used by
Nx and Lerna, and leaves room for future modes. The shared-version
behavior is still described as lockstep in changelogs and docs prose.
Also renames LockstepVersionException to FixedVersioningException and
exports the new VersioningMode enum.
@spydon spydon changed the title feat(version): add optional lockstep versioning feat(version): add optional fixed versioning mode Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant