Versioning Rules
ContractHQ uses Semantic Versioning (SemVer) to communicate the impact of every contract change. Understanding these rules helps teams coordinate schema evolution safely without breaking downstream consumers.
SemVer for Data Contracts
Every contract has a version field in the format MAJOR.MINOR.PATCH:
Breaking change. Consumers must update their code before you deploy.
Backwards-compatible addition. New optional fields or relaxed constraints.
Non-functional fix. Documentation updates, description corrections.
Breaking vs Non-Breaking Changes
| Change | Type | Version bump |
|---|---|---|
| Remove a field | Breaking | MAJOR |
| Rename a field | Breaking | MAJOR |
| Change a field type (e.g. string → integer) | Breaking | MAJOR |
| Add not_null constraint to existing field | Breaking | MAJOR |
| Add a new required field | Breaking | MAJOR |
| Add a new optional field | Non-breaking | MINOR |
| Relax a constraint (e.g. remove unique) | Non-breaking | MINOR |
| Update field description or metadata | Non-functional | PATCH |
| Fix a typo in documentation | Non-functional | PATCH |
Bumping the Version
Manually update the version field in your contract file, or use the CLI helper:
contracthq version bump major contracts/user_signups.yml
# ✔ Bumped 1.2.3 → 2.0.0
contracthq version bump minor contracts/user_signups.yml
# ✔ Bumped 1.2.3 → 1.3.0Deprecation Notices
Before removing a field (MAJOR bump), it is best practice to mark it as deprecated for at least one release cycle. ContractHQ will surface deprecation warnings to consumers in the registry UI and via Slack/email:
- name: legacy_user_id
type: integer
deprecated: true
deprecation_note: "Use user_id (uuid) instead. Will be removed in v3.0.0."
removal_date: "2025-03-01"Migration Guides
For major version bumps, add a human-readable migration guide under migrations:
migrations:
- from: 1.x.x
to: 2.0.0
breaking_changes:
- field: legacy_user_id
action: removed
guide: "Join on user_id (uuid) from the users table."contracthq changelog contracts/user_signups.yml to see the full diff.