Changeset Format
Changesets are Markdown files stored in .contractual/changesets/. Each changeset declares which contracts are changing and at what semver level, and provides human-readable context about the change.
File structure
Section titled “File structure”A changeset file has two parts: a YAML frontmatter block and a Markdown body.
--- “orders-api”: major “order-schema”: minor ---
## orders-apiRemoved the
## order-schemaGET /orders/{id}/detailsendpoint. Consumers using this endpoint must migrate toGET /orders/{id}?include=detailsbefore upgrading.Added optional
shipping_addressfield to the Order object. Consumers do not need to make any changes. The field is not required and existing responses remain valid.
Frontmatter
Section titled “Frontmatter”The frontmatter is a YAML block delimited by ---. Each line declares one contract and its bump level.
Format
Section titled “Format”---"contract-name": major | minor | patch---- The key is the contract
nameas defined incontractual.yaml, enclosed in double quotes. - The value is one of
major,minor, orpatch. - Multiple contracts can appear in the same changeset.
- Order does not matter.
Valid examples
Section titled “Valid examples”Single contract, single bump:
--- “orders-api”: major ---
Multiple contracts with different bump levels:
--- “orders-api”: major “order-schema”: minor “payment-schema”: patch ---
The body is free-form Markdown. It is appended directly to CHANGELOG.md under the version heading when contractual version runs.
Recommended structure: One ## heading per contract, followed by a description of what changed and any migration steps.
## orders-apiRemoved the
## order-schemalegacy_idfield from the Order response object. This field was deprecated in v2.1.0. Consumers relying onorder.legacy_idshould useorder.idinstead.Added
billing_addressas an optional field. No migration required.
The body can be empty if there is nothing to add beyond the structural diff output. Contractual will still generate a minimal changelog entry from the detected changes.
Naming convention
Section titled “Naming convention”Changeset files use an adjective-noun-verb.md naming pattern. This produces human-readable names that are easy to distinguish in pull request file trees.
Examples:
gentle-tigers-fly.mdangry-lions-jump.mdlucky-foxes-swim.md
Contractual generates names using a dictionary of common adjectives, animals, and verbs. The combination is random and has no semantic meaning. The content of the file is what matters.
How auto-generation works
Section titled “How auto-generation works”When the GitHub Action runs in pr-check mode and detects spec changes, it generates a changeset automatically:
- Contractual runs
contractual breakingto produce the structural diff. - Each detected change is classified according to the Classifications rules.
- The highest classification across all changes for each contract becomes the frontmatter bump level.
- A changeset body is generated describing each detected change.
- The file is committed to the PR branch with an auto-generated name.
The auto-generated file is a starting point. Review and edit the classification or body before the PR merges if the auto-detection is wrong.
Editing auto-generated classifications
Section titled “Editing auto-generated classifications”If auto-detection classifies a change incorrectly, edit the frontmatter directly:
Before (auto-generated):
--- “orders-api”: major ---
Removed field
internal_trace_idfrom Order response.
After (corrected):
--- “orders-api”: patch # was: major; field removed but unused ---
Removed the internal
internal_trace_idfield from the Order response. This field was never documented, never included in the published schema, and no external consumers reference it. No migration required.
Contractual uses the value in the file at contractual version time. It does not re-run detection or override edits.
Creating a changeset manually
Section titled “Creating a changeset manually”Use the contractual changeset command to create a changeset interactively:
contractual changesetOr skip the prompt and specify everything inline:
contractual changeset --contract orders-api --bump major --no-interactiveTo create one by hand, create a .md file in .contractual/changesets/ with the correct frontmatter:
touch .contractual/changesets/my-change.mdThen open it in an editor and write the frontmatter and body.
Where changesets live
Section titled “Where changesets live”.contractual/ changesets/ gentle-tigers-fly.md # created on PR #42 lucky-foxes-swim.md # created on PR #43 snapshots/ orders-api/ 1.2.0.yaml 1.3.0.yaml versions.jsonAll files in .contractual/changesets/ are consumed and deleted when contractual version runs. The directory is empty between releases.