Skip to content

Release Flow

Contractual uses a two-PR pattern for releasing contract changes. This separates the work of making changes from the work of releasing them.


Your everyday work: spec changes plus a changeset file.

  1. Edit your spec files
  2. Run contractual diff to see the impact
  3. Run contractual changeset to describe the changes
  4. Commit spec + changeset files together
  5. Open a PR

The GitHub Action runs pr-check mode:

  • Validates specs with linters
  • Posts a diff table as a PR comment
  • Warns about breaking changes

When changesets accumulate on main, the Action creates a Version Contracts PR:

  • Consumes all pending changesets
  • Bumps versions according to changeset declarations
  • Updates versions.json and CHANGELOG.md
  • Creates new snapshots

Reviewers approve the Version PR to confirm the release is ready.

When the Version PR merges:

  • Git tags are created (e.g., orders-api@2.0.0)
  • GitHub Releases are created with changelogs
  • Spec files can be attached as release artifacts


TriggerWhat happens
PR opened/updatedAction runs pr-check: lint, diff, post comment
PR merged to mainChangesets added to main branch
Changesets exist on mainAction creates Version PR
Version PR mergedAction creates tags and releases

Version numbers are never bumped on Feature PRs. The Version PR is the only place where versions change:

FileWhen updated
contractual.yamlNever (versions not stored here)
.contractual/versions.jsonOn Version PR
.contractual/snapshots/*.yamlOn Version PR
CHANGELOG.mdOn Version PR

This keeps Feature PRs focused on the actual changes, not version numbers.


For alpha, beta, or release candidate versions:

  1. Enter pre-release: contractual pre enter beta
  2. Make changes and merge Feature PRs as normal
  3. Version PRs produce -beta.0, -beta.1, etc.
  4. Exit pre-release: contractual pre exit
  5. Final Version PR produces stable version

See Pre-release Versioning for details.