For the complete documentation index, see llms.txt. This page is also available as Markdown.

Expressing version intent

The version pipeline reads your intent from three sources. From highest to lowest priority:

  1. /version comments on merged pull requests

  2. version: footers in commit messages

  3. Conventional commit prefixes (smart defaults)

If none of them apply, the change is treated as a patch — the pipeline never over-bumps on its own.

Conventional commits (the everyday path)

If your team already writes Conventional Commits, you get sensible versions with zero extra effort:

Commit message
Intent

fix(sales): correct rounding on invoice totals

patch

feat(sales): add multi-currency support

minor

feat(sales)!: rework the pricing API

major

perf(sales): cache exchange rates (any other prefix)

patch

update invoice layout (no recognised prefix)

patch

A BREAKING CHANGE: footer also marks a major:

feat(sales): rework the pricing API

BREAKING CHANGE: PricingService.calculate now requires a currency code

Scoping matters when a commit touches several packages. A scoped commit applies its intent only to the named package; other packages touched by the same commit get a patch:

sales gets a minor; if the commit also modified files in sales-ui, sales-ui gets a patch.

An unscoped commit applies its intent to every package it touches:

→ both sales and sales-ui get a minor.

When several commits land between builds, each package takes the highest intent seen across the commits that affect it. Merge commits are parsed like any other commit.

For explicit control, add a version: footer to any commit in the range. Entries can be separated by spaces, commas or semicolons.

Bump specific packages:

One intent for everything the build touches:

Mixed — a global intent with per-package overrides:

→ every impacted package gets a minor, except sales, which gets a major.

Bump the dependents of what you changed:

core-crm resolves from its own commits (a minor here), and every package that directly depends on core-crm is bumped a patch and included in the build — even if its own source did not change. Dependents expansion is single-level (dependents of dependents are not pulled in) and only ever happens when you ask for it; a plain feat: never expands the build.

Invalid entries are skipped with a warning rather than failing the build — version: sales:enormous simply falls through to the conventional-commit default.

/version comments on pull requests

Reviewers and authors can settle the version question on the pull request itself, without touching the commits. Add a comment to the PR before or after merging:

When the merged PR falls into the range of the next build, the comment is picked up and outranks every other source.

Per-package form — applies to the named package unconditionally:

Global form — applies to the packages that this PR changed (and only those):

The global form of a PR comment is deliberately scoped to its own pull request's files. Two PRs merged in the same build range never leak intents onto each other — a /version minor on PR A cannot bump a package that only PR B touched. Commit footers behave differently: a global version: minor footer applies to every package impacted by the build.

Dependents form — same semantics as the commit footer:

Later /version comments win. Unlike conventional commits, where the highest intent across the range wins, /version comments resolve last-wins: when a package has more than one /version comment across the PRs in a build range, the most recent comment for that package is used. This lets a later comment correct an earlier one — /version sales:patch after an earlier /version sales:major downgrades the bump to a patch, and /version sales:none cancels a bump entirely. Comments with no timestamp (as on some providers) fall back to the order in which they were read; two intents in the very same comment resolve to the stronger of the two.

AI-suggested intent (addon)

AI Version Assist is an opt-in addon that reads a pull request's diff and posts a /version comment authored by the app. Its comment is marker-tagged and resolves in a separate, lower tier: it sits below every human /version comment and version: footer, and above the conventional-commit defaults. A human /version comment for a package always overrides the assist's directive for that package. The addon is off by default; see AI Assisted Version Intent to enable it.

When one pull request changes several packages

A single PR often touches more than one package. What each package receives depends on how the intent is expressed:

Say a PR modifies files in sales, sales-ui and core-crm, with sales last published as 2.4.1, sales-ui as 1.2.0 and core-crm as 3.1.0:

How the PR expresses intent
sales
sales-ui
core-crm

Title/commit feat(sales): ... (scoped)

2.5.0 minor

1.2.1 patch

3.1.1 patch

Title/commit feat: ... (unscoped)

2.5.0 minor

1.3.0 minor

3.2.0 minor

Comment /version minor (global, scoped to this PR)

2.5.0 minor

1.3.0 minor

3.2.0 minor

Comment /version sales:major

3.0.0 major

1.2.1 patch

3.1.1 patch

Footer version: minor core-crm:major

2.5.0 minor

1.3.0 minor

4.0.0 major

The rules behind the table:

  • A scoped conventional prefix applies only to the named package; the other packages the PR touched fall back to a patch.

  • An unscoped prefix and the global forms apply to every package the change touched.

  • Per-package entries always win over global ones for their package.

  • Every package is versioned from its own last published version — packages in the same PR do not share a version line.

Each package is then built and published with its own computed version; a PR spanning three packages produces three independently versioned artifacts.

Putting it together

A typical sprint on a sales package last published as 2.4.1:

  1. Monday — PR merges with fix(sales): correct tax rounding → pending intent: patch

  2. Wednesday — PR merges with feat(sales): support payment plans → pending intent: minor (higher wins)

  3. Thursday — a reviewer realises the payment-plan change breaks an integration contract and comments /version sales:major on the merged PR

  4. Friday — the release build runs: sales is built as 3.0.0.<build> (PR comment outranks commits), published, and 3.0.0 becomes the base for next sprint

Unlocked packages: the promoted version guard

Salesforce does not allow a new patch version on a promoted (released) unlocked package series. When the pipeline resolves a patch for an unlocked package whose current series is already promoted, it automatically escalates the bump to a minor and logs a warning — saving the build from a late rejection by the platform. The guard requires DevHub access during the build and is skipped without it.

Last updated

Was this helpful?