LPM CLI

lpm release

Plan, apply, and publish workspace releases in dependency order.

lpm release plan --affected --base main --bump patch

Coordinates releases across a workspace. lpm release plan computes the package/version/dependency update plan, lpm release apply writes it to manifests, and lpm release publish publishes selected members in dependency order.

lpm release is intentionally separate from lpm version: single-package version bumps stay simple, while workspace releases get explicit planning and publish orchestration.

Examples

lpm release plan --all --bump patch
lpm release plan --affected --base origin/main --bump minor --json
lpm release apply --filter core --bump major
lpm release apply --affected --base main --dry-run --json
lpm release publish --all --dry-run --json
lpm release publish --affected --base origin/main --npm -y
lpm release publish --all --lpm --otp 123456 --json

Planning

A release plan reads every selected workspace member's package.json, computes the new versions, and then checks workspace-internal dependents.

Dependency ranges are updated only when the new version no longer satisfies the existing range and the range is safely rewriteable:

Existing specExample update
exact old version1.2.3 -> 2.0.0
caret old version^1.2.3 -> ^2.0.0
tilde old version~1.2.3 -> ~2.0.0
explicit workspace rangeworkspace:^1.2.3 -> workspace:^2.0.0

Dynamic workspace specs such as workspace:*, workspace:^, and workspace:~ are left unchanged. catalog: specs are also left unchanged because the catalog owns the concrete version.

If any dependent has a range that would stop accepting a bumped internal package and LPM CLI cannot rewrite it safely, planning fails before anything is written.

Bump sources

Pass --bump <level> to use one bump for every selected package:

lpm release plan --affected --bump patch

Or add lightweight change files under .lpm/changes/. Each non-empty, non-comment line is:

<package-name> <bump>

Example:

core minor
app patch

Change-file bumps override the command's --bump fallback for matching packages. If a selected package has no change-file entry and no --bump, the command fails instead of guessing. Use --bump patch when you want the conservative patch fallback.

Selection

Every lpm release subcommand requires an explicit workspace selection:

Selection modes are mutually exclusive: --all cannot be combined with --affected, --filter, or --filter-prod.

FlagDescription
--allSelect every workspace member.
--affectedSelect packages changed since --base plus their transitive dependents.
--base <REF>Git base ref for --affected. Defaults to main.
--filter <EXPR>Select workspace members with the same filter grammar as lpm run --filter.
--filter-prod <EXPR>Like --filter, but dependency closures follow production edges only.
--changed-files-ignore-pattern <GLOB>Ignore matching changed files when evaluating affected packages.
--test-pattern <GLOB>Treat matching changed files as tests so affected fanout does not include dependents from them.
--fail-if-no-matchExit non-zero when the selection resolves to no members.

Subcommands

lpm release plan

Prints the release plan and never writes files.

lpm release plan --all --bump patch
lpm release plan --affected --base origin/main --bump minor --json

lpm release apply

Writes the plan to the selected package manifests and any workspace dependents that need range updates.

lpm release apply --filter core --bump major
lpm release apply --affected --bump patch --dry-run --json

LPM CLI records the original manifests before it replaces any file. It also coordinates these writes with installs, version changes, and publishing.

If the process stops during the write, run a mutating release apply, release publish, or version command. The command restores an incomplete update before it continues. If the original operation completed, an identical retry reports the completed operation without another version bump.

Read-only commands do not change recovery state. release plan, release apply --dry-run, and release publish --dry-run stop when an incomplete update exists. A concurrent install also stops instead of using a partially updated workspace.

lpm release publish

Publishes selected members in topological order, dependencies before dependents. Before the first upload it validates current workspace-internal ranges so a stale manifest fails before a partial publish.

release publish reuses the single-package lpm publish implementation for each member. It supports the same target flags that make sense for a workspace publish:

FlagDescription
--dry-runPrint publish order and skip decisions without uploading.
-y, --yesSkip per-package confirmation prompts.
--otp <CODE>Send a six-digit authenticator code for MFA-protected LPM.dev publishes.
--min-score <N>Require a minimum quality score.
--allow-secretsSkip the pre-publish secret scan.
--npmPublish to npm.
--lpmPublish to LPM.dev Registry.
--githubPublish to GitHub Packages.
--gitlabPublish to GitLab Packages.
--publish-registry <URL>Publish to a custom npm-compatible registry.
--provenanceRequire generated Sigstore provenance.
--no-provenanceDisable provenance for this run.
--provenance-file <PATH>Attach a pre-generated Sigstore bundle for npm-compatible targets.

For an LPM.dev workspace release, --otp supplies the same code to each selected package. Use a fresh code before it expires.

For LPM.dev Registry and npm targets, LPM CLI checks metadata before upload. If every checked target already has the selected version, the package is skipped. If only some checked targets already have it, the command fails before uploading so it does not partially publish.

Custom, GitHub, and GitLab targets are still validated for local target-name/config correctness, but remote version existence is left to the target publish response.

Workspace publishing is not transactional across packages. If a later package fails, LPM CLI does not remove earlier successful uploads.

Human output names the failed package and shows its preparation or upload error. JSON output reports each selected package with one of these states:

StatusMeaning
publishedEvery selected target for the package succeeded.
failedPreparation or at least one selected target failed.
not_attemptedAn earlier package failed, so this package did not start.
skippedThe checked targets already contain this version.
plannedA dry run prepared this package without an upload.

If a publish fails, keep the successful uploads. Then retry only the failed and not_attempted packages with a narrower selection.

JSON

--json is available on every subcommand. plan and apply emit the same envelope shape:

{
  "success": true,
  "dry_run": true,
  "packages": [],
  "dependency_updates": [],
  "files": []
}

publish --json emits:

{
  "success": true,
  "dry_run": true,
  "packages": 2,
  "results": []
}

On failure, success is false. The results array keeps completed, failed, and unattempted packages, and warning explains the retry boundary.

See also

  • lpm version — single-package version bumps
  • lpm publish — single-package publish behavior and provenance
  • lpm workspaces — workspace declarations, protocols, catalogs, and filters