diff --git a/pkg/argocd/git.go b/pkg/argocd/git.go index b2cd8991..2bc08f42 100644 --- a/pkg/argocd/git.go +++ b/pkg/argocd/git.go @@ -329,40 +329,51 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi return err, false } - if err = updateKustomizeFile(filterFunc, kustFile); err != nil { - return err, false - } - - return nil, false + return updateKustomizeFile(filterFunc, kustFile) } // 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 { +func updateKustomizeFile(filter kyaml.Filter, path string) (error, bool) { // Read the yaml y, err := kyaml.ReadFile(path) if err != nil { - return err + return err, false + } + + originalData, err := y.String() + if err != nil { + return err, false } // Update the yaml yCpy := y.Copy() if err := yCpy.PipeE(filter); err != nil { - return err + return err, false } // Preserve the original order of fields if err := order.SyncOrder(y, yCpy); err != nil { - return err + return err, false + } + + override, err := yCpy.String() + if err != nil { + return err, false + } + + if originalData == override { + log.Debugf("target parameter file and marshaled data are the same, skipping commit.") + return nil, true } // Write the yaml - if err := kyaml.WriteFile(yCpy, path); err != nil { - return err + if err := os.WriteFile(path, []byte(override), 0600); err != nil { + return err, false } - return nil + return nil, false } func imagesFilter(images v1alpha1.KustomizeImages) (kyaml.Filter, error) { diff --git a/pkg/argocd/git_test.go b/pkg/argocd/git_test.go index 2b6ce2c3..22b26b74 100644 --- a/pkg/argocd/git_test.go +++ b/pkg/argocd/git_test.go @@ -270,19 +270,49 @@ func Test_updateKustomizeFile(t *testing.T) { `, filter: filter, }, + { + name: "no-change", + content: `images: +- name: foo + digest: sha23456 +`, + wantContent: "", + filter: filter, + }, + { + name: "invalid-path", + content: `images: +- name: foo + digest: sha12345 +`, + wantContent: "", + filter: filter, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - path := makeTmpKustomization(t, []byte(tt.content)) - err := updateKustomizeFile(tt.filter, path) + var path string + if tt.wantErr { + path = "/invalid-path" + } else { + path = makeTmpKustomization(t, []byte(tt.content)) + } + + err, skip := updateKustomizeFile(tt.filter, path) if tt.wantErr { assert.Error(t, err) + assert.False(t, skip) + } else if tt.name == "no-change" { + assert.Nil(t, err) + assert.True(t, skip) } else { got, err := os.ReadFile(path) if err != nil { t.Fatal(err) } assert.Equal(t, tt.wantContent, string(got)) + assert.False(t, skip) } }) }