Skip to content

feat(yaml)!: add createmissingkey and appendtoarray to the yaml resource - #10193

Merged
olblak merged 8 commits into
updatecli:mainfrom
olblak:issue/60
Sep 3, 2026
Merged

olblak merged 8 commits into
updatecli:mainfrom
olblak:issue/60

Conversation

@olblak

@olblak olblak commented Sep 3, 2026 •

Copy link
Copy Markdown
Member

Fix #60

Add two attributes to the yaml resource, so that a target can write a key that
does not exist yet, and can grow a sequence instead of replacing it.

createmissingkey creates 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.

targets:
  tag:
    kind: yaml
    spec:
      file: values.yaml
      key: $.image.tag
      createmissingkey: true

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.

targets:
  allowedTags:
    kind: yaml
    spec:
      file: values.yaml
      key: $.allowedTags
      appendtoarray: true

Both are supported by the default go-yaml engine only, and are rejected at
validation time when engine: yamlpath is set. createmissingkey also rejects a
key holding a wildcard or a recursive selector ($.agents[*].tag, $..tag),
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.

⚠️ Breaking changes

Both affect the yaml resource used as a target, and both apply to manifests
that do not use the new attributes.

  1. A wildcard key must now be held by every position it selects.

A key such as $.agents[*].tag used to update the entries carrying tag and
report a success, silently leaving the others untouched:

agents:
  - name: first
    tag: v1       # updated
  - name: second  # ignored, target reported success

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.

  1. engine: yamlpath now fails when the key is missing from every document.

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:

cd pkg/plugins/resources/yaml
go test

An end to end manifest covering both attributes is added in
e2e/updatecli.d/success.d/yaml/createandappend.yaml.

Additional Information

Checklist

  • I have updated the documentation via pull request om/updatecli/website) repository.
  • I have tested this pull request manually with a cuorks as expected.

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

* 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>
@olblak olblak added enhancement New feature or request resource-yaml Resource of kind YAML labels Sep 3, 2026
@olblak
olblak requested a balanced review from Copilot September 3, 2026 06:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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 createmissingkey and appendtoarray options.
  • 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.

Comment thread e2e/updatecli.d/success.d/yaml/createandappend.yaml
Comment thread pkg/plugins/resources/yaml/target_goyaml.go Outdated
Comment thread pkg/plugins/resources/yaml/target_goyaml.go Outdated
Comment thread pkg/plugins/resources/yaml/main.go
Comment thread pkg/plugins/resources/yaml/main.go Outdated
olblak and others added 6 commits September 3, 2026 08:50
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>
@olblak
olblak requested a balanced review from Copilot September 3, 2026 11:00
@mergify

mergify Bot commented Sep 3, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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. goYamlPathTarget deliberately 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

Comment thread pkg/plugins/resources/yaml/create.go
Comment thread pkg/plugins/resources/yaml/main.go
Comment thread pkg/plugins/resources/yaml/target_goyaml.go
@olblak olblak changed the title feat(yaml): Support new yaml key creation feat(yaml)!: add createmissingkey and appendtoarray to the yaml resource Sep 3, 2026
@olblak
olblak enabled auto-merge (squash) September 3, 2026 11:24
@olblak
olblak merged commit a5edf3c into updatecli:main Sep 3, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request resource-yaml Resource of kind YAML

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Yaml target should add key value if it doesn't exist

2 participants