Skip to content

Pre-release Versioning

Pre-release mode lets you publish alpha, beta, or release candidate versions before a stable release. Version bumps during pre-release mode produce versions like 2.0.0-beta.0, 2.0.0-beta.1, etc.


  1. Enter pre-release - contractual pre enter beta
  2. Make changes - Create changesets as normal
  3. Version - contractual version produces -beta.N versions
  4. Exit pre-release - contractual pre exit
  5. Finalize - contractual version produces stable versions

Enter pre-release mode with a tag.

Terminal window
contractual pre enter <tag>

Common tags: alpha, beta, rc, next

terminal
$ contractual pre enter beta

Entering pre-release mode: beta

Created: .contractual/pre.json

Current versions will become:
orders-api: 1.2.0 → 1.3.0-beta.0 (on next version bump)
order-schema: 1.0.0 → 1.1.0-beta.0 (on next version bump)

Run `contractual pre exit` when ready for stable release.

When in pre-release mode:

  • contractual version appends the tag and increments the pre-release number
  • First bump: 1.2.01.3.0-beta.0
  • Second bump: 1.3.0-beta.01.3.0-beta.1
  • The base version (1.3.0) is determined by the changeset bump type

Exit pre-release mode and prepare for stable release.

Terminal window
contractual pre exit
terminal
$ contractual pre exit

Exiting pre-release mode.

Current pre-release versions:
orders-api: 2.0.0-beta.4
order-schema: 1.1.0-beta.2

Will become stable on next `contractual version`:
orders-api: 2.0.0
order-schema: 1.1.0

Updated: .contractual/pre.json (mode: exit)

Run `contractual version` to finalize stable release.

After pre exit, run contractual version to:

  • Strip the pre-release suffix
  • Create stable snapshots
  • Update changelog with stable version heading

Show current pre-release state.

Terminal window
contractual pre status
terminal
$ contractual pre status

Pre-release mode: beta
Entered: 2026-03-10T10:00:00Z
Changesets consumed: 3

Current versions:
orders-api: 2.0.0-beta.4
order-schema: 1.1.0-beta.2
terminal
$ contractual pre status

Not in pre-release mode.

Run `contractual pre enter <tag>` to start.

Pre-release state is stored in .contractual/pre.json:

{
"tag": "beta",
"mode": "pre",
"enteredAt": "2026-03-10T10:00:00Z",
"initialVersions": {
"orders-api": "1.2.0",
"order-schema": "1.0.0"
}
}
FieldDescription
tagPre-release identifier (alpha, beta, rc, etc.)
modeCurrent mode: pre (active) or exit (pending finalization)
enteredAtWhen pre-release mode was entered
initialVersionsVersions when pre-release started

Terminal window
# Start beta cycle
contractual pre enter beta
# Make changes and create changeset
# ... edit specs ...
contractual changeset
# Release beta.0
contractual version
# orders-api: 1.2.0 → 2.0.0-beta.0
# More changes, another changeset
contractual changeset
# Release beta.1
contractual version
# orders-api: 2.0.0-beta.0 → 2.0.0-beta.1
# Ready for stable release
contractual pre exit
contractual version
# orders-api: 2.0.0-beta.1 → 2.0.0

Use the pre-release-tag input to create pre-release versions in CI:

- uses: contractual-dev/action@v1
with:
mode: release
pre-release-tag: beta

This is equivalent to running contractual pre enter beta before versioning. The action:

  1. Creates versions like 2.0.0-beta.0
  2. Marks GitHub Releases as pre-release
  3. Increments the pre-release number on subsequent runs