Skip to content

Move to yaml.v3 and preserve comments, multiline strings, anchors in helm values #1055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 7, 2025

Conversation

bewinsnw
Copy link
Contributor

@bewinsnw bewinsnw commented Mar 3, 2025

Similar to #1039 (and conflicts with it). In our codefresh install developers have complained that various parts of the original yaml aren't preserved:

  • comments
  • multiline string formatting for parameters like scripts
  • anchors (the current code resolves all anchors and writes back with no anchors, resulting in duplicative config)

In particular we have cases where multiple jobs are defined in a chart which use the same images, which should all be updated via a single reference. yaml.v2 doesn't support this, but yaml.v3 does; the Node structure preserves pre-, post- and end-of-line comments, keeps the string formatting marker with the string for marshalling, and allows us to navigate aliases without losing them.

In this PR, I first switched to yaml.v3, then, like #1039, simplified the test cases for this code to not use the internal structures we unmarshal to but instead do yaml-to-yaml comparisons; this is easier to read and maintain and less code. Finally I added tests for the features described above.

I've only supported one level of aliasing; you can have multiple aliases through the path as you navigate the document but you can't have a mapping which is an alias for a mapping which is an alias for a mapping. Supporting that may mean the code could get stuck in a loop, and it doesn't seem like a sensible document structure anyway, just make the direct reference?

I don't currently support or set tags in the yaml, eg !!str. This would be an issue if you try to set a field which is not tagged as a string.

Unlike #1039, this does not also update the path syntax used for updates.

@codecov-commenter
Copy link

codecov-commenter commented Mar 3, 2025

Codecov Report

Attention: Patch coverage is 88.23529% with 12 lines in your changes missing coverage. Please review.

Project coverage is 63.37%. Comparing base (3d44f28) to head (b43859d).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
pkg/argocd/update.go 88.23% 9 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1055      +/-   ##
==========================================
+ Coverage   62.89%   63.37%   +0.47%     
==========================================
  Files          15       15              
  Lines        2269     2326      +57     
==========================================
+ Hits         1427     1474      +47     
- Misses        753      760       +7     
- Partials       89       92       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

bewinsnw added 4 commits March 3, 2025 15:40
In order to support round-tripping of files with multiline yaml
and anchors, move to yaml.v3. This lower-level interface
preserves comments and doesn't follow aliases by default.

Support for aliases in Helm values files is fairly minimal
and I need to add tests to demonstrate that this works;
it only follows one level of alias to avoid getting stuck
in loops.

A lot of tests needed updated because it seems yaml.v3 switched to
four spaces instead of two when marshalling by default.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
This change makes for less verbose code, also what we care about
is the transformation of the yaml, not the internal representation.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
When round-tripping helm yaml, we want comments to be preserved.
Multiline strings should retain their formatting (this is to allow
for, for example, scripts in k8s commands). Aliases should be preserved,
and followed, both for mappings and scalars.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
When yaml.v3 parses yaml, string scalars are tagged "!!str". It is
possible that we could parse a values file which sets the version to
eg 1.23 (a float), so that when we later update the value to "v2.4"
it can't be serialized. To protect against this, set the tag whenever
we create or update scalars that are explicitly intended to be strings.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
@jannfis
Copy link
Contributor

jannfis commented Mar 4, 2025

Given this PR seems simpler than #1039, doesn't introduce a new dependency (just a version bump) and that there was no feedback on the review comments for about two weeks, I'd be fine to go with this one instead of #1039 for now.

@chengfang WDYT?

@chengfang
Copy link
Collaborator

Looks promising. I'll take a closer look.

yaml.v3 changed the default indent to 4 spaces, see:
go-yaml/yaml@3c39489

in order to avoid unnecessary whitespace changes in code previously formatted
with argo_image_updater, use a 2-space indent instead.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
It's possible to preserve the indent in the original yaml when
we Unmarshal to a yaml.Node, and the structure of the original
yaml allows us to guess the indent.

The two easiest cases are when we have a nested block-style mapping,
or a sequence inside a mapping and the sequence is indented. For
those, the node tells us the parsed column (starting at 1) and we
use that indent.

However: if we parse to some other data structure (as we do with
Kustomize) or the original yaml has some structure where the indentation
is unclear, eg:

    root:
    - unguessable indent
    - deeper:
        guessable: but requires deeper traversal

... then we just guess '2'.

This should generate _fewer_ useless whitespace changes, but cannot
prevent them all.

Signed-off-by: Brian Ewins <bewins@nerdwallet.com>
@chengfang chengfang merged commit 74a3001 into argoproj-labs:master Mar 7, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants