fix(patch): bump jsonpatch to pick up recursive list-order-ignoring compare#424
Merged
Merged
Conversation
…ompare With the recursive-set-compare fix in jsonpatch, reapplying an unchanged forma no longer spuriously replaces resources whose stored state has nested lists in a different order than the PKL-evaluated desired state (e.g. AWS returning an ECS task definition's Environment or PortMappings lists in a canonicalised order that differs from the forma). Adds three integration tests in the patch package covering the Environment reorder, PortMappings reorder, and the negative case where a real content change inside a nested list still correctly trips needsReplacement.
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.
Summary
Pulls in the recursive-set-compare fix from
platform-engineering-labs/jsonpatch(merged asfb6f96b1) so that reapplying an unchanged forma no longer spuriously replaces resources whose stored state has nested lists in a different order than the PKL-evaluated desired state.Root cause (recap)
jsonpatch.matchesValue'signoreArrayOrder=truebranch compared list elements byjson.Marshalbytes.json.Marshalsorts map keys but preserves array order, so a reordered nested list inside a container-shaped element produced a different byte string at the outer level — even when the nested content was semantically identical. This propagated up as a false positive on the outer list's set-compare, which (under acreateOnlyfield likeContainerDefinitions) trippedneedsReplacement=trueand destroyed-and-recreated the resource on every reapply.The upstream fix replaces the byte-string multiset with a pairing algorithm that matches elements recursively via
matchesValueitself. O(n*m) worst case, correct for arbitrary nesting depth.Change here
go.mod/go.sum: bumpgithub.com/platform-engineering-labs/jsonpatchtov0.0.0-20260421221004-fb6f96b174b5.internal/metastructure/patch/patch_document_test.go: three new integration tests againstgeneratePatchthat cover the formae-side symptom end-to-end:TestGeneratePatch_NestedListOrderingInsideArrayElement_NoReplace— the exact Grafana-style reproducer (Environmentreordered inside aContainerDefinitionunder acreateOnlyContainerDefinitionslist). Fails against the unpatched jsonpatch, passes after the bump.TestGeneratePatch_NestedPortMappingsOrderInsideArrayElement_NoReplace— the tempo-container variant (PortMappingsreordered).TestGeneratePatch_NestedListContentChange_StillReplaces— negative guard: a real content change inside a nested list must still produce a replace.All three were written failing-first against the current
maindep, watched fail for the right reason, then passed after pointing at the patched jsonpatch.Impact
Unblocks idempotent reapply for ECS Services referencing Task Definitions with multi-container shapes (and any similar pattern with nested canonicalised lists). Combined with the two earlier fixes on
main(hasProviderDefaultrecursive stripping +PortMapping.hostPortannotation in the AWS plugin), reapplying an unchanged forma with an ECS Service should now be a true no-op.