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.
Workflow
Section titled “Workflow”- Enter pre-release -
contractual pre enter beta - Make changes - Create changesets as normal
- Version -
contractual versionproduces-beta.Nversions - Exit pre-release -
contractual pre exit - Finalize -
contractual versionproduces stable versions
pre enter
Section titled “pre enter”Enter pre-release mode with a tag.
contractual pre enter <tag>Common tags: alpha, beta, rc, next
$ 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.
How it works
Section titled “How it works”When in pre-release mode:
contractual versionappends the tag and increments the pre-release number- First bump:
1.2.0→1.3.0-beta.0 - Second bump:
1.3.0-beta.0→1.3.0-beta.1 - The base version (1.3.0) is determined by the changeset bump type
pre exit
Section titled “pre exit”Exit pre-release mode and prepare for stable release.
contractual pre exit$ 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.
Finalizing the release
Section titled “Finalizing the release”After pre exit, run contractual version to:
- Strip the pre-release suffix
- Create stable snapshots
- Update changelog with stable version heading
pre status
Section titled “pre status”Show current pre-release state.
contractual pre statusIn pre-release mode
Section titled “In pre-release mode”$ 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 Not in pre-release
Section titled “Not in pre-release”$ contractual pre status Not in pre-release mode. Run `contractual pre enter <tag>` to start.
Pre-release file
Section titled “Pre-release file”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" }}| Field | Description |
|---|---|
tag | Pre-release identifier (alpha, beta, rc, etc.) |
mode | Current mode: pre (active) or exit (pending finalization) |
enteredAt | When pre-release mode was entered |
initialVersions | Versions when pre-release started |
Example: Beta release cycle
Section titled “Example: Beta release cycle”# Start beta cyclecontractual pre enter beta
# Make changes and create changeset# ... edit specs ...contractual changeset
# Release beta.0contractual version# orders-api: 1.2.0 → 2.0.0-beta.0
# More changes, another changesetcontractual changeset
# Release beta.1contractual version# orders-api: 2.0.0-beta.0 → 2.0.0-beta.1
# Ready for stable releasecontractual pre exitcontractual version# orders-api: 2.0.0-beta.1 → 2.0.0GitHub Action
Section titled “GitHub Action”Use the pre-release-tag input to create pre-release versions in CI:
- uses: contractual-dev/action@v1 with: mode: release pre-release-tag: betaThis is equivalent to running contractual pre enter beta before versioning. The action:
- Creates versions like
2.0.0-beta.0 - Marks GitHub Releases as pre-release
- Increments the pre-release number on subsequent runs
See also
Section titled “See also”- Versioning Usage - Version command reference
- Changeset Format - Changeset file structure
- GitHub Action Release - Release automation configuration