feat(yaml)!: add createmissingkey and appendtoarray to the yaml resource - #10193
Conversation
* Add parameter "createmissingkey" to create a new key value if it doesn't exist when using the yaml plugin * Add parameter "appendtoarray" to appen a value to an array when using the yaml plugin Signed-off-by: Olblak <me@olblak.com>
There was a problem hiding this comment.
🟡 Changes recommended
The missing E2E fixture and incorrect multi-match handling must be fixed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds YAML target support for creating missing keys and idempotently appending values to arrays.
Changes:
- Adds
createmissingkeyandappendtoarrayoptions. - Implements AST-based creation and appending for the go-yaml engine.
- Adds validation, unit tests, and E2E coverage.
File summaries
| File | Review |
|---|---|
pkg/plugins/resources/yaml/utils.go |
Adds reusable comment attachment. No issues found. |
pkg/plugins/resources/yaml/target_yamlpath.go |
Corrects multi-document result accounting. No issues found. |
pkg/plugins/resources/yaml/target_goyaml.go |
Integrates creation and append operations. Moderate: wildcard missing-key creation and multi-match array appending can falsely report changes without modifying the YAML. |
pkg/plugins/resources/yaml/target_create_test.go |
Tests target behavior and regressions. No issues found. |
pkg/plugins/resources/yaml/main.go |
Defines and validates new options. Nits: misleading existing-key documentation and imprecise unsupported-option errors. |
pkg/plugins/resources/yaml/main_test.go |
Tests option validation. No issues found. |
pkg/plugins/resources/yaml/create.go |
Implements path creation and sequence appending. No issues found. |
pkg/plugins/resources/yaml/create_test.go |
Tests YAML-path parsing helpers. No issues found. |
e2e/updatecli.d/success.d/yaml/createandappend.yaml |
Adds E2E scenarios. Critical: references a missing e2e/testdata/yaml/values.yaml fixture, so the scenario fails before exercising the targets. |
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 5
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
|
Tick the box to add this pull request to the merge queue (same as
|
There was a problem hiding this comment.
🟡 Changes recommended
Moderate issues remain in indentation detection, validation, documentation, and out-of-range document-index handling.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
pkg/plugins/resources/yaml/main.go:184
- This statement contradicts the implemented and tested behavior: with
createmissingkey: true, an existing key holding another value is updated normally (target_create_test.go:150-161). Saying it is left untouched will cause generated resource documentation to mislead users.
// * the key is only created, never removed, and existing keys are left untouched.
pkg/plugins/resources/yaml/main.go:84
- This rule is only implemented by the default go-yaml engine.
goYamlPathTargetdeliberately succeeds when a key is present in at least one document (foundAny) and ignores documents without matches, as also described by this PR's yamlpath breaking change. Qualify this paragraph by engine so yamlpath users are not told that partial document matches fail.
// * as a target, a key that a document does not hold is an error, so that a
// manifest never reports a success for an update it did not make. The same
// rule applies to a wildcard such as `$.agents[*].name`: every position it
// selects must hold the key, otherwise the target fails rather than updating
// only some of them. Set "searchpattern" to update the positions holding the
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Balanced
Signed-off-by: Olblak <me@olblak.com>
Fix #60
Add two attributes to the
yamlresource, so that a target can write a key thatdoes not exist yet, and can grow a sequence instead of replacing it.
createmissingkeycreates the key when the document does not hold it,building the missing intermediate keys as nested maps and matching the
indentation of the surrounding document.
appendtoarray appends the value as a new entry of the sequence addressed by
key. It is idempotent: appending a value the sequence already holds reports no
change. Combined with createmissingkey, a missing sequence is created holding
the value as its sole entry.
Both are supported by the default go-yaml engine only, and are rejected at$.agents[*].tag, $ ..tag),
validation time when engine: yamlpath is set. createmissingkey also rejects a
key holding a wildcard or a recursive selector (
since there is no way to create the key under each selected position.
Getting there surfaced a handful of pre-existing defects in the shared code
paths, fixed in their own commits: a key selecting several nodes resolves to a
detached wrapper rather than to the matched node itself, which was mistaken for a
key present everywhere; and the yamlpath engine counted processed keys per
document, which left its missing-key check unreachable.
Both affect the yaml resource used as a target, and both apply to manifests
that do not use the new attributes.
A key such as $.agents[*].tag used to update the entries carrying tag and
report a success, silently leaving the others untouched:
It now fails instead, so a target never reports a success for an update it only
partially made. This matches the rule already applied to documents: a key missing
from one document of a multi-document file has always been an error.
Set searchpattern: true to keep the previous behaviour and update the positions
holding the key.
A recursive selector ($..tag) is unaffected: it searches for the key itself, so
it only ever selects positions already holding it and cannot match partially.
The check existed but was unreachable, so the target was silently reported as
skipped. It now errors, as the default go-yaml engine already did. Set
searchpattern: true to ignore files that do not carry the key.
Test
To test this pull request, you can run the following commands:
An end to end manifest covering both attributes is added in
e2e/updatecli.d/success.d/yaml/createandappend.yaml.
Additional Information
Checklist
Tradeoff
createmissingkey creates the key in every document of a multi-document file
when documentindex is not set, and in every file matched by file/files when
searchpattern is set. This follows the existing rule that a target evaluate
documents, but it means a key can land on documents that were never meant t
it. Set documentindex to narrow it down.
A missing sequence index ($.agents[0].name) is not created: materialising e
N of a sequence that does not have one has no sensible answer.
Potential improvement
Rejecting createmissingkey combined with searchpattern at validation time,
since the combination turns every glob match into a write rather than a sea