Required by issue #151 — Contract versioning & deprecation policy. Treat this document as the source of truth for how we version, deprecate, and remove anything in this workspace (Soroban contracts, CLI, off-chain tools). It is referenced from
docs/versioning.md,CHANGELOG.md, and the version-bump template in PR descriptions.
| Bump | When | Code change required | CHANGELOG.md section |
|---|---|---|---|
| Patch (0.1.x) | Bug-fix only, no contract API change, no event-shape change, no storage-key change. | none | ### Fixed |
| Minor (0.x.0) | Backwards-compatible additions, new optional features, new #[deprecated] entries, no removal. |
opt-in features only | ### Added, ### Deprecated, ### Removed (planned) |
| Major (x.0.0) | Any breaking change: contract entrypoint signature, error-code renumbering, storage-key renumbering, on-chain event shape, removing a previously-deprecated symbol. | yes | ### Removed, ### Breaking |
The current contract version is 0.1.0 and lives in orbitchain_common::version::VERSION_STR — never hand-edit it; it is regenerated by the release script tracked in issue #151.
-
Patch (
0.1.0 → 0.1.1) is auto-eligible whenever:- the change does not touch any public Soroban contract entrypoint signature,
- the change does not add/remove/rename any
#[contracttype]variant,#[contracterror]discriminant, or storage key, - the change does not change the published shape of any event topic.
-
Minor (
0.1.x → 0.2.0) is auto-eligible whenever:- the change adds a brand-new contract entrypoint,
- the change adds new optional fields to a struct used only as a read-view response (e.g.
CampaignReport), - the change marks any symbol with
#[deprecated(since = "0.2.0", note = "...")], - the change introduces a new Soroban contract crate (e.g.
orbitchain-batch-donorin 0.2.0), - no previously-shipped symbol is removed or had its signature altered.
-
Major (
0.x.0 → 1.0.0) is required whenever any of the following happens:- a public contract entrypoint signature changes (added/removed/reordered param),
- a
#[contracterror]discriminant is renumbered or removed (we never renumber — unassigned slots stay frozen), - a storage key is removed or renamed,
- an on-chain event topic string is changed,
- a previously-deprecated symbol is removed.
-
Pre-1.0 caveat: while
VERSION_STRis0.x.y, we treat every minor bump as if it were a major bump for removal purposes only: a symbol marked#[deprecated(since = "0.2.0")]is removed no later than0.5.0rather than1.5.0, because Soroban contracts are not yet at semantic versioning 1.0.
The standard timeline for any #[deprecated] symbol is three minor releases between announcement and removal:
0.1.0 ─► ship the working symbol as-is.
0.2.0 ─► add `#[deprecated(since = "0.2.0", note = "use FOOBAR_V2 instead")]`
and ship the replacement under its new name. Update CHANGELOG.md
with `### Deprecated` (link to replacement) and `### Removed (planned)`
(target removal version).
0.3.0 ─► symbol still callable but warns on every invocation; ideally no
new code references it.
0.4.0 ─► symbol may be removed. Before removing, cross-reference
CHANGELOG.md to confirm every consumer has migrated.
0.5.0 ─► hard deadline: any `#[deprecated(since = "<=0.4.0")]` symbol MUST
be removed by this version, or extended with a fresh
`#[deprecated(since = "0.5.0", ...)]` annotation and an explicit
removal date beyond 0.8.0.
Stay shorter than this only when you wrote the symbol less than one minor release ago AND removing it would not break any in-flight Soroban instance that pinned the previous version (Soroban contracts are addressable by hash, so most consumers can be expected to upgrade within one minor release).
Here is the example that lives in campaign/src/lib.rs::CampaignContract::legacy_version_marker and is asserted by the host-target test versioning::tests::changelog_lists_all_deprecated_symbols:
// In campaign/src/lib.rs
#[deprecated(
since = "0.2.0",
note = "use CampaignContract::version_str() or \
orbitchain_common::version::VERSION_STR; \
will be removed in 0.4.0"
)]
pub fn legacy_version_marker(env: Env) -> soroban_sdk::Symbol {
soroban_sdk::Symbol::new(&env, "v0.1.0")
}And the matching entry in CHANGELOG.md under the ## [Unreleased] section:
### Deprecated
- `orbitchain-campaign::CampaignContract::legacy_version_marker`
(deprecated since 0.2.0; use `CampaignContract::version_str()`
or `orbitchain_common::version::VERSION_STR`).
Will be removed in 0.4.0.
### Removed (planned)
- `orbitchain-campaign::CampaignContract::legacy_version_marker`
is scheduled to be removed in 0.4.0.The CI test versioning::changelog_lists_all_deprecated_symbols parses
CHANGELOG.md and asserts that every #[deprecated(since = ..., note = ...)]
symbol in the workspace appears in the ### Deprecated and ### Removed (planned)
subsections of the ## [Unreleased] section. Failing this test blocks a
release — never merge a #[deprecated] PR without an accompanying CHANGELOG entry.
This single PR closes issue #131,
#147, and
#151 — the
document you are reading is the deliverable for #151. For #147 a new
orbitchain-batch-donor contract crate is introduced under
crates/contracts/batch-donor/; until 1.0.0 that is a minor bump (so
the workspace becomes 0.2.0 on the next release tag). For #131 a new
tutorial file docs/tutorials/js-quickstart.md is added; tutorials do not
trigger a version bump on their own.
-
cargo doc -p orbitchain-campaign --target wasm32v1-nonerendersCampaignContract::legacy_version_markerwith the deprecated marker and a strikethrough note containing the replacement symbol. -
cargo test -p orbitchain-common versioning::testspasses (CHANGELOG.md structure checked). -
cborabbit test --workspacepasses (no onchain behaviour changes in 0.1.x for the campaign contract aside from the#[deprecated]example). - At least one follow-up issue is filed before tagging
0.2.0to drive the actual bump (this PR ships the policy, not the bump itself).
docs/versioning.md— companion document; where theVERSIONconstants live and how downstream consumers read them.CHANGELOG.md— the canonical log of### Added,### Changed,### Fixed,### Deprecated,### Removed, owned by this process.CONTRIBUTING.md— how to format a PR so that it fits cleanly into the next release's CHANGELOG.