> For the complete documentation index, see [llms.txt](https://docs.flxbl.io/flxbl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flxbl.io/flxbl/sfp/building-artifacts/automated-package-versioning.md).

# Automated Package Versioning (Limited Preview)

{% hint style="warning" %}
**This feature is in limited preview** — it is available to selected customers only, and behaviour and commands may change based on feedback. Reach out to the flxbl team if you would like early access.
{% endhint %}

{% hint style="info" %}
This feature is available in **sfp-pro** and requires an sfp server, as the server keeps track of the last published version of each package per branch.
{% endhint %}

Version numbers in `sfdx-project.json` are a constant source of friction in team development. Every pull request that touches a package potentially fights over the `versionNumber` field, developers forget to bump versions (or bump them incorrectly), and there is no structured way to express whether a change is a patch, a minor or a major.

Automated package versioning takes the version number out of the day-to-day workflow. Packages you opt in are marked with the sentinel version `0.0.0.NEXT` in `sfdx-project.json`, and the version of every artifact is computed at build time from:

* The **last published version** of the package, tracked by the sfp server per branch
* The **intent** of the changes since then — derived from your conventional commit messages, explicit `version:` commit footers, or `/version` comments on pull requests

```
// sfdx-project.json — a server-managed package
{
  "path": "src/sales",
  "package": "sales",
  "versionNumber": "0.0.0.NEXT"
}
```

With this in place, merging a pull request titled `feat(sales): add discount calculation` and building produces the next **minor** version of `sales` automatically — if the last published version was `2.4.1`, the new artifact is `2.5.0.<build>`. The version field stays constant in source control, so pull requests no longer conflict on it.

### How a version is computed

For every package that is part of a build, the version pipeline runs the following stages:

1. **User override** — if the package's `versionNumber` is anything other than `0.0.0.NEXT`, that version is used verbatim (with the build number substituted into the fourth segment) and all other stages are skipped. This is what keeps packages you have *not* opted in behaving exactly as before.
2. **Explicit intent** — a `/version` comment on a merged pull request, or a `version:` footer in a commit message, declares the bump explicitly. Explicit intent always wins over inference.
3. **Smart defaults** — the conventional commit prefixes of the commits since the last published version decide the bump: `feat:` is a minor, `fix:` (and everything else) is a patch, and `feat!:` or a `BREAKING CHANGE:` footer is a major. Across multiple commits, the highest intent wins.
4. **Dependents expansion** — when a change declares `dependents:<intent>`, the direct dependents of the changed packages are also given a version bump and added to the build.
5. **Promoted version guard** — for unlocked packages, if the current version series has already been promoted, a patch is automatically escalated to a minor, since Salesforce does not allow patching a promoted series.
6. **Compute** — the intent is applied on top of the last published version.

A few examples, assuming `sales` was last published as `2.4.1`:

| Changes since last publish                               | Computed version               |
| -------------------------------------------------------- | ------------------------------ |
| `fix(sales): correct rounding on totals`                 | `2.4.2.<build>`                |
| `feat(sales): add discount calculation`                  | `2.5.0.<build>`                |
| `feat(sales)!: rework pricing API`                       | `3.0.0.<build>`                |
| `fix(sales): small fix` *and* `feat(sales): new feature` | `2.5.0.<build>` (highest wins) |
| `chore: update labels` (no recognised prefix)            | `2.4.2.<build>`                |
| Merged PR carrying the comment `/version sales:major`    | `3.0.0.<build>`                |

The computed versions are displayed during every build:

```
Computed Versions:
┌──────────────┬───────────┬─────────────┬────────┬─────────────────────┐
│ Package      │ Previous  │ New Version │ Intent │ Source              │
├──────────────┼───────────┼─────────────┼────────┼─────────────────────┤
│ sales        │ 2.4.1.45  │ 2.5.0.46    │ minor  │ conventional-commit │
├──────────────┼───────────┼─────────────┼────────┼─────────────────────┤
│ sales-ui     │ 1.2.0.45  │ 1.2.1.46    │ patch  │ default             │
└──────────────┴───────────┴─────────────┴────────┴─────────────────────┘
```

After a successful publish, the new version is recorded on the server and becomes the base for the next build's computation.

### What does not change

* **Packages you have not opted in are untouched.** Any package with an explicit version (`2.4.1.NEXT`) keeps its classic behaviour — its version is used as-is, and a manual version bump still triggers a rebuild. You can run a project with a mix of managed and manual packages indefinitely.
* **Builds never fail because of versioning.** Invalid intents are skipped with a warning, and if the server is temporarily unreachable, the build falls back to the versions recorded in your git tags.

### How dependencies are treated

* **A bump never propagates on its own.** Changing `core-crm` does not bump the packages that depend on it. Dependent packages are only bumped when a change explicitly asks for it with `dependents:<intent>` (in a commit footer or a `/version` comment).
* **Expansion is single-level.** `dependents:patch` on `core-crm` bumps the packages that directly depend on `core-crm` — not their dependents in turn. A package reachable through several dependency paths is bumped once, from its own last published version.
* **Bumped dependents are built.** A dependent that receives a version bump is added to the build so an artifact exists for the new version, even though its own source did not change.
* **Dependency version references are not rewritten.** Entries in a package's `dependencies` array (for example `"versionNumber": "1.0.0.LATEST"`) are left for you to manage; unlocked package dependencies use minimum-version matching, so a bump in a dependency does not invalidate them. Raising a reference after a major change in a dependency remains a deliberate, manual decision.

### Where to go next

* [Adopting automated versioning](/flxbl/sfp/building-artifacts/automated-package-versioning/adopting-automated-versioning.md) — enabling the feature and onboarding your packages
* [Expressing version intent](/flxbl/sfp/building-artifacts/automated-package-versioning/expressing-version-intent.md) — conventional commits, `version:` footers and `/version` PR comments, with examples
* [Versioning across branches](/flxbl/sfp/building-artifacts/automated-package-versioning/versioning-across-branches.md) — how parallel branches, merges and release lines behave


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp/building-artifacts/automated-package-versioning.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
