Skip to content

Harden $create-changelog and improve artifact-diff fidelity#1039

Merged
c-schuler merged 2 commits into
mainfrom
enhancement/artifact-diff-create-changelog
May 28, 2026
Merged

Harden $create-changelog and improve artifact-diff fidelity#1039
c-schuler merged 2 commits into
mainfrom
enhancement/artifact-diff-create-changelog

Conversation

@c-schuler
Copy link
Copy Markdown
Contributor

Summary

Makes the $create-changelog operation (and the shared $artifact-diff engine it builds on) robust against real-world manifests and produces a cleaner, less noisy diff. Two threads of work: a series of null-safety fixes that were each blocking the operation on progressively more complex inputs, and diff-quality improvements that remove spurious and redundant entries from the result.

Robustness (NPE fixes)

Each surfaced after the prior was unblocked, all on the diff/changelog path:

  1. HapiArtifactDiffProcessor.extensionEquals - dereferenced extension.getValue() unconditionally, NPE-ing on complex extensions that carry only nested sub-extensions and no top-level value (e.g. the package-source extension emitted by $data-requirements). Now null-guards both sides and falls back to Extension.equalsDeep.

  2. Page.addInsertOperation / addDeleteOperation / addReplaceOperation - dereferenced oldData/newData, which are legitimately null for pages representing a resource that exists on only one side of the diff (insert-only or delete-only). Now each side is guarded independently.

  3. Null parameter names - HAPI's Parameters.getParameter(String) NPEs when the list contains a component with a null name (which arises when a malformed canonical parses to null and is stored back on a component). Added a null-safe hasParameterNamed helper and switched the remaining .getName().equals(...) / .equalsIgnoreCase(...) call sites in both processors to literal-first form.

Diff fidelity

  1. Set-match contained expansion parameters - the contained Parameters.parameter[] array is order-independent, but FhirPatch.diff compares arrays positionally, so a reordered manifest produced a cascade of meaningless replace ops pairing unrelated entries by index. Extended the existing match-and-reorder machinery (already used for relatedArtifact, compose.include, expansion.contains) to expansion parameters, matching by name + version-stripped URL. A pure reorder now produces no ops; a genuine version bump produces a single replace; add/remove produce clean insert/delete.

  2. Skip unchanged dependencies - handleSourceMatches recursed into and re-fetched every matched dependency even when the source and target referenced the identical version-pinned canonical (the same immutable artifact). Now short-circuits when the full canonicals are equal — no wasted fetch, no spurious sub-diff entry.

  3. Suppress futile retrieval-failure placeholders - when a recursive sub-diff couldn't resolve a side (commonly external code systems like LOINC/SNOMED/ICD/CPT that are never stored as full resources), the processor baked a "Target/Source could not be retrieved" string into the diff payload. These were both futile (external systems can't be content-diffed) and redundant (any reference-level change is already reported as a relatedArtifact operation). Now logged at debug instead of polluting the output.

@c-schuler c-schuler requested a review from Chris0296 May 28, 2026 18:43
@github-actions
Copy link
Copy Markdown

Formatting check succeeded!

@c-schuler c-schuler self-assigned this May 28, 2026
@c-schuler c-schuler added the enhancement New feature or request label May 28, 2026
Copy link
Copy Markdown
Collaborator

@Chris0296 Chris0296 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great improvements - nice work Chris!

@sonarqubecloud
Copy link
Copy Markdown

@c-schuler c-schuler merged commit 5bac08f into main May 28, 2026
9 checks passed
@c-schuler c-schuler deleted the enhancement/artifact-diff-create-changelog branch May 28, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants