API Versioning & History
Relevant source files
The following files were used as context for generating this wiki page:
Crucible manages API evolution through a structured system of releases, migrations, and automated documentation. It tracks changes between versions to ensure that clients can transition safely while maintaining access to older, supported releases. The system generates comprehensive history logs and upgrade guides that describe exactly how an API has changed over time.
The versioning architecture relies on a central release chain. Each release in this chain documents its relationship to the previous version, its sunset date, and specific changes to operations or data types. Versioned services require clients to specify a target release, usually through a dedicated HTTP header, allowing the service to route requests to the appropriate logic or data transformations.
Sources: crates/crucible-codegen-docs/src/markdown.rs:904-907, crates/crucible-codegen-docs/src/markdown.rs:65-68
Release Management and Identification
Crucible identifies the current and documented releases within its metadata. A versioned service typically uses a "carrier" header, such as Crucible-Version, to communicate the requested release. If a request lacks this header, the service selects a default unversioned release, which may be an older version.
Key Release Indicators
- Current Release: The most recent version of the service.
- Documented Release: The specific version described in a given set of documentation.
- Sunset Date: The date after which an older release may no longer be supported or served.
Sources: crates/crucible-codegen-docs/src/markdown.rs:20-41, crates/crucible-codegen-docs/src/markdown.rs:65-68
The diagram shows how Crucible determines which API version to use for a given request.
Sources: crates/crucible-codegen-docs/src/markdown.rs:65-68, crates/crucible-codegen-docs/src/markdown.rs:18-19
The Release Chain and History
The system records the API history in structured files like changes.json and releases.md. These files describe every supported release, starting from the oldest. Each entry in the history identifies which release it follows and lists the specific changes introduced.
Component Descriptions
| Component | Description |
|---|---|
releases.md | A Markdown page listing every supported release, its follows relationship, sunset date, and change count. |
changes.json | A machine-readable JSON representation of the release chain and version metadata. |
History Metadata | Data structures tracking when shapes or operations were added, changed, or retired. |
Sources: crates/crucible-codegen-docs/src/markdown.rs:904-918, crates/crucible-build/tests/docs_outputs.rs:142-148
Automated Upgrade Guides
Crucible generates upgrade guides that compare two releases. These guides detail exactly what a client of an older release will meet when moving to a newer or current release. The generation logic ensures that guides are deterministic and accurately reflect internal vs. external audiences; for example, external guides omit internal API elements like secret members or internal-only operations.
Upgrade Guide Generation Logic
- Identify Pair: Select a "from" release and a "to" release (defaults to the current release).
- Validate Order: Ensure the "from" release is older than the "to" release.
- Diff Content: Identify added, removed, or modified operations and shapes.
- Audience Filtering: Filter out members and operations marked as
internalfor external documentation.
Sources: crates/crucible-codegen-docs/tests/upgrade.rs:43-46, crates/crucible-codegen-docs/tests/upgrade.rs:77-80, crates/crucible-codegen-docs/tests/upgrade.rs:88-91
The sequence shows the process of generating an upgrade guide from the Service IR.
Sources: crates/crucible-codegen-docs/tests/upgrade.rs:25-30, crates/crucible-codegen-docs/tests/upgrade.rs:43-46
Change Classifications
Crucible categorizes changes into specific types to provide clear documentation for clients. Each change type describes the impact on the wire protocol or the client's data model.
| Change Type | Behavior |
|---|---|
rename | Changes a member name; clients of the older version see the previous name. |
require | Makes a previously optional member required; often includes a default value for older clients. |
addEnumValue | Adds a value to an enum; older clients may receive a fallback value. |
addError | Introduces a new error code to an operation. |
move | Changes an operation's HTTP method or URI. |
reshape | Replaces members or definitions, often moving data into a new structure. |
retype | Changes the target type of a member, potentially involving a conversion hook. |
removeOperation | Retires an operation, though it may still be served for older clients until the sunset date. |
Sources: crates/crucible-codegen-docs/src/markdown.rs:973-1049
Retired Operations
An operation retired under an exception is not considered "no change". Retired operations are listed specifically in the release pages, noting that while the release after the current one may have dropped them, they remain served for the documented release and its predecessors.
Sources: crates/crucible-codegen-docs/tests/upgrade.rs:328-332, crates/crucible-codegen-docs/src/markdown.rs:939-943
Technical Implementation and File Paths
The documentation generator uses various file paths to organize versioning data.
src/releases.md: General overview of the release chain. Sources: markdown.rs:904src/releases/<release_name>.md: Detailed changelog for a specific version. Sources: markdown.rs:768src/upgrade/<from>_to_<to>.md: Specific upgrade instructions between two versions. Sources: upgrade.rs:163changes.json: The raw release chain data. Sources: markdown.rs:693
Citations:
crates/crucible-codegen-docs/src/markdown.rscrates/crucible-codegen-docs/tests/upgrade.rscrates/crucible-build/tests/docs_outputs.rscrates/crucible-codegen-docs/tests/golden/versioned-v2-external/llms.txtcrates/crucible-codegen-docs/tests/golden/history-internal/llms.txt
Crucible's versioning system ensures API longevity by treating history as a first-class citizen. By automating the generation of upgrade guides and changelogs, it reduces the manual effort required to maintain backward compatibility and client communication during API transitions.