diff options
| author | Jaye Doepke <jtdoepke@users.noreply.github.com> | 2024-07-17 14:57:15 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-17 15:57:15 -0400 |
| commit | 50360e994a8141fc0aeaafae126a74a9b833fe31 (patch) | |
| tree | 9dce663940778a13b9849d3a81ddf026bff6032e | |
| parent | 2bf4b0aee7680b93ced3c5ee14b27527f9a1920a (diff) | |
Preserve field order when updating kustomization.yaml file (#666)
Signed-off-by: Jaye Doepke <jdoepke@mintel.com>
| -rw-r--r-- | pkg/argocd/git.go | 34 | ||||
| -rw-r--r-- | pkg/argocd/git_test.go | 72 |
2 files changed, 104 insertions, 2 deletions
diff --git a/pkg/argocd/git.go b/pkg/argocd/git.go index d3216d9..f984790 100644 --- a/pkg/argocd/git.go +++ b/pkg/argocd/git.go @@ -12,6 +12,7 @@ import ( "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/order" kyaml "sigs.k8s.io/kustomize/kyaml/yaml" "github.com/argoproj-labs/argocd-image-updater/pkg/image" @@ -327,14 +328,43 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi if err != nil { return err, false } - err = kyaml.UpdateFile(filterFunc, kustFile) - if err != nil { + + if err = updateKustomizeFile(filterFunc, kustFile); err != nil { return err, false } return nil, false } +// updateKustomizeFile reads the kustomization file at path, applies the filter to it, and writes the result back +// to the file. This is the same behavior as kyaml.UpdateFile, but it preserves the original order +// of YAML fields to minimize git diffs. +func updateKustomizeFile(filter kyaml.Filter, path string) error { + // Read the yaml + y, err := kyaml.ReadFile(path) + if err != nil { + return err + } + + // Update the yaml + yCpy := y.Copy() + if err := yCpy.PipeE(filter); err != nil { + return err + } + + // Preserve the original order of fields + if err := order.SyncOrder(y, yCpy); err != nil { + return err + } + + // Write the yaml + if err := kyaml.WriteFile(yCpy, path); err != nil { + return err + } + + return nil +} + func imagesFilter(images v1alpha1.KustomizeImages) (kyaml.Filter, error) { var overrides []kyaml.Filter for _, img := range images { diff --git a/pkg/argocd/git_test.go b/pkg/argocd/git_test.go index 69f7027..2b6ce2c 100644 --- a/pkg/argocd/git_test.go +++ b/pkg/argocd/git_test.go @@ -1,6 +1,7 @@ package argocd import ( + "os" "testing" "text/template" "time" @@ -215,3 +216,74 @@ images: }) } } + +func Test_updateKustomizeFile(t *testing.T) { + makeTmpKustomization := func(t *testing.T, content []byte) string { + f, err := os.CreateTemp("", "kustomization-*.yaml") + if err != nil { + t.Fatal(err) + } + _, err = f.Write(content) + if err != nil { + t.Fatal(err) + } + f.Close() + t.Cleanup(func() { + os.Remove(f.Name()) + }) + return f.Name() + } + + filter, err := imagesFilter(v1alpha1.KustomizeImages{"foo@sha23456"}) + if err != nil { + t.Fatal(err) + } + + tests := []struct { + name string + content string + wantContent string + filter kyaml.Filter + wantErr bool + }{ + { + name: "sorted", + content: `images: +- digest: sha12345 + name: foo +`, + wantContent: `images: +- digest: sha23456 + name: foo +`, + filter: filter, + }, + { + name: "not-sorted", + content: `images: +- name: foo + digest: sha12345 +`, + wantContent: `images: +- name: foo + digest: sha23456 +`, + filter: filter, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + path := makeTmpKustomization(t, []byte(tt.content)) + err := updateKustomizeFile(tt.filter, path) + if tt.wantErr { + assert.Error(t, err) + } else { + got, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, tt.wantContent, string(got)) + } + }) + } +} |
