@@ -2242,6 +2242,82 @@ replicas: 1
22422242 assert .Error (t , err )
22432243 })
22442244
2245+ t .Run ("Multi-source application with Kustomize first and Helm values write-back" , func (t * testing.T ) {
2246+ // This reproduces issue #1289 where getApplicationSource returns the Kustomize source
2247+ // instead of the Helm source for multi-source applications
2248+ expected := `
2249+ # auto generated by argocd image updater
2250+
2251+ theme:
2252+ image:
2253+ tag: latest
2254+ name: docker.io/hello-world
2255+ `
2256+ app := v1alpha1.Application {
2257+ ObjectMeta : v1.ObjectMeta {
2258+ Name : "multi-source-app" ,
2259+ Annotations : map [string ]string {
2260+ "argocd-image-updater.argoproj.io/image-list" : "theme=docker.io/hello-world:latest" ,
2261+ "argocd-image-updater.argoproj.io/write-back-method" : "git" ,
2262+ "argocd-image-updater.argoproj.io/write-back-target" : "helmvalues:/apps/test/theme-version.yaml" ,
2263+ "argocd-image-updater.argoproj.io/theme.helm.image-name" : "theme.image.name" ,
2264+ "argocd-image-updater.argoproj.io/theme.helm.image-tag" : "theme.image.tag" ,
2265+ },
2266+ },
2267+ Spec : v1alpha1.ApplicationSpec {
2268+ Sources : []v1alpha1.ApplicationSource {
2269+ {
2270+ // First source: Kustomize (this gets picked up by getApplicationSource!)
2271+ Path : "apps/test/overlays/dev" ,
2272+ RepoURL : "https://example.com/gitops.git" ,
2273+ Kustomize : & v1alpha1.ApplicationSourceKustomize {
2274+ // Empty kustomize
2275+ },
2276+ },
2277+ {
2278+ // Second source: Helm chart (this is what we want!)
2279+ Chart : "my-chart" ,
2280+ RepoURL : "https://example.com/charts" ,
2281+ Helm : & v1alpha1.ApplicationSourceHelm {
2282+ Parameters : []v1alpha1.HelmParameter {
2283+ {
2284+ Name : "theme.image.name" ,
2285+ Value : "docker.io/hello-world" ,
2286+ ForceString : true ,
2287+ },
2288+ {
2289+ Name : "theme.image.tag" ,
2290+ Value : "latest" ,
2291+ ForceString : true ,
2292+ },
2293+ },
2294+ },
2295+ },
2296+ },
2297+ },
2298+ Status : v1alpha1.ApplicationStatus {
2299+ SourceTypes : []v1alpha1.ApplicationSourceType {
2300+ v1alpha1 .ApplicationSourceTypeKustomize ,
2301+ v1alpha1 .ApplicationSourceTypeHelm ,
2302+ },
2303+ Summary : v1alpha1.ApplicationSummary {
2304+ Images : []string {
2305+ "docker.io/hello-world:latest" ,
2306+ },
2307+ },
2308+ },
2309+ }
2310+
2311+ // Simulate creating a new file (nil originalData)
2312+ yamlOutput , err := marshalParamsOverride (& app , nil )
2313+ require .NoError (t , err )
2314+ assert .NotEmpty (t , yamlOutput , "output should not be empty" )
2315+
2316+ // The output should contain the helm values, not be empty
2317+ yamlStr := string (yamlOutput )
2318+ assert .Equal (t , strings .TrimSpace (strings .ReplaceAll (expected , "\t " , " " )), strings .TrimSpace (yamlStr ))
2319+ })
2320+
22452321 t .Run ("Whitespace only values file from helm source does not cause error" , func (t * testing.T ) {
22462322 expected := `
22472323# auto generated by argocd image updater
@@ -2302,10 +2378,22 @@ nginx:
23022378
23032379 originalData := []byte (`
23042380` )
2305- yaml , err := marshalParamsOverride (& app , originalData )
2381+ yamlOutput , err := marshalParamsOverride (& app , originalData )
23062382 require .NoError (t , err )
2307- assert .NotEmpty (t , yaml )
2308- assert .Equal (t , strings .TrimSpace (strings .ReplaceAll (expected , "\t " , " " )), strings .TrimSpace (string (yaml )))
2383+ assert .NotEmpty (t , yamlOutput )
2384+ assert .Equal (t , strings .TrimSpace (strings .ReplaceAll (expected , "\t " , " " )), strings .TrimSpace (string (yamlOutput )))
2385+
2386+ // Verify round-trip: marshal → unmarshal → marshal
2387+ // This ensures the generated YAML structure can be read back correctly
2388+ var roundTripNode yaml.Node
2389+ err = yaml .Unmarshal (yamlOutput , & roundTripNode )
2390+ require .NoError (t , err , "should be able to unmarshal the generated YAML" )
2391+
2392+ roundTripYaml , err := yaml .Marshal (& roundTripNode )
2393+ require .NoError (t , err , "should be able to re-marshal the unmarshaled YAML" )
2394+ assert .NotEmpty (t , roundTripYaml , "round-tripped YAML should not be empty" )
2395+
2396+ assert .YAMLEq (t , string (yamlOutput ), string (roundTripYaml ), "round-tripped YAML should be semantically equivalent" )
23092397 })
23102398}
23112399
0 commit comments