Added changelog command and API endpoint#1118
Merged
jschoedl merged 11 commits intodatacontract:mainfrom Apr 8, 2026
Merged
Conversation
7968019 to
e139e55
Compare
4 tasks
jochenchrist
reviewed
Apr 3, 2026
Contributor
|
Just the one remark. rest is OK. |
… report Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
e139e55 to
7019c1a
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bab986f to
eb719af
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jochenchrist
reviewed
Apr 6, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Author
All comments should be addressed now |
jschoedl
approved these changes
Apr 8, 2026
Contributor
Author
|
@jschoedl Looking at the build failure - this is strange - also there should have been no need to run ruff again .. |
jschoedl
requested changes
Apr 8, 2026
The integration fixtures (changelog_integration_v1.yaml / v2.yaml) gained explicit version fields in a prior commit but the golden file wasn't updated, causing test_golden_output to fail. Regenerated golden_changelog_text.txt to reflect the new version Updated entry in both the summary badge count and the details table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n error message tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(changelog): semantic changelog for ODCS data contracts with text report
Note
This PR replaces #1112, and implements change requests from the original PR review.
It has a narrower scope, and does not implement the text and html renderers.
The functionality is exposed as
changelograther thandiff. The changelog output and associated code are more closely aligned to the existing code base.Summary
Reintroducing the much loved
changelogfunctionality (#1016), with a wider capability including semantic diff with field level granularity. This PR adds adatacontract changelogcommand that produces a semantic changelog of two data contract YAML files, with a plain-text report format.Note: Breaking change classification (which changes are breaking vs non-breaking) is out of scope for this PR and will follow in a subsequent one.
# Plain-text changelog to stdout datacontract changelog v1.odcs.yaml v2.odcs.yamlA
POST /changelogendpoint is also added to the API server, accepting the two contracts as YAML strings in the request body.Motivation
When evolving a data contract, understanding what changed between two versions is a prerequisite to assessing impact. This provides a structured, human-readable changelog rather than a raw YAML text diff, with changes grouped by field path and presented at both a summary (rolled-up) and detail (leaf) level.
Screenshot
How it works
The diff engine normalises both contracts before diffing — converting named lists (e.g.
schema[],customProperties[],authoritativeDefinitions[]) from positional arrays to dicts keyed by their natural identifier.This eliminates false positives from list reordering and produces stable, meaningful field paths in the output e.g.
schema.orders.properties.order_id.logicalType Changedrather than
schema[0].properties[1].logicalType ChangedNatural key limitation and upstream path - Future Considerations
This section provides context around the current semantic / natural key implementation and envisaged improvements.
The natural key for each named list — the field used to key items when converting arrays to dicts before diffing — is currently hardcoded in
normalize.py. Each entry in the table below was determined by inspecting therequiredarray in the ODCS v3 JSON Schema and selecting the field that acts as the stable semantic identifier:SchemaObjectnamerequired: [name]in JSON schemaSchemaPropertynamerequired: [name]in JSON schemaServerserverrequired: [server, type]—serverchosen as identifierSLAPropertypropertyrequired: [property, value]—propertychosen as identifierCustomPropertypropertyrequired: [property, value]—propertychosen as identifierRolerolerequired: [role]in JSON schemaSupportItemchannelrequired: [channel]in JSON schemaTeamMemberusernamerequired: [username]in JSON schemaDataQualitynamerequiredin JSON schema —nameinferred; positional fallback if absentThe
DataQualitycase illustrates the root problem: the JSON schema does not declare any field asrequiredfor that object, so there is no machine-readable source of truth from which the natural key can be derived. The key must instead be inferred from domain knowledge and hardcoded with a fallback.The correct long-term fix is for the natural key to be declared in the spec itself — specifically, by ensuring that each named-list entity type in
odcs-json-schema-v3.1.0.jsonhas arequiredarray whose first entry is unambiguously its stable identifier. That metadata would then flow through to the Pydantic model package as a non-optional field, allowingnormalize.pyto derive the natural key table dynamically by reflecting overmodel_fieldsrather than maintaining it by hand.If this PR is merged, the author intends to raise issues and submit PRs to both upstream projects —
bitol-io/open-data-contract-standardto add the missingrequireddeclarations to the JSON schema, anddatacontract/open-data-contract-standard-pythonto surface those as non-optional Pydantic fields — which would allow a follow-up PR here to replace the hardcoded key table with fully derived logic.Changes
datacontract/changelog/changelog.py— ODCS semantic diff and changelog builderdatacontract/changelog/normalize.py— pre-diff normalization (named lists → keyed dicts)datacontract/output/text_changelog_results.py— plain-text rendererdatacontract/model/changelog.py—ChangelogResultandChangelogEntrymodelsdatacontract/data_contract.py—DataContract.changelog()methoddatacontract/api.py—POST /changelogendpointdatacontract/cli.py—datacontract changelogcommandtests/test_changelog*.py— comprehensive test suite covering diff engine, normalization, rendering, and APItests/fixtures/changelog/*— fixture files for ODCS changelog testingtests/fixtures/breaking/*— removed leftover fixture files from the DCS-based implementationAPI.md— changelog endpoint documentationCHANGELOG.md— unreleased entryREADME.md— updated with new changelog functionalitypyproject.toml— dependency updatesTesting
pytest tests/test_changelog*.py tests/test_cli.py tests/test_api.py199 tests, all passing.