From 4297edba0e12933eb53495ada7013236a1da0d4f Mon Sep 17 00:00:00 2001
From: Robin Schneider <45321827+robinschneider@users.noreply.github.com>
Date: Mon, 4 Sep 2023 18:14:59 +0200
Subject: [PATCH] feat(manager/helm-values): Add multi document file support 
 (#24232)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 .../single_file_with_multiple_documents.yaml  | 38 +++++++++++++++++++
 .../manager/helm-values/extract.spec.ts       | 23 +++++++++++
 lib/modules/manager/helm-values/extract.ts    | 13 +++++--
 3 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 lib/modules/manager/helm-values/__fixtures__/single_file_with_multiple_documents.yaml

diff --git a/lib/modules/manager/helm-values/__fixtures__/single_file_with_multiple_documents.yaml b/lib/modules/manager/helm-values/__fixtures__/single_file_with_multiple_documents.yaml
new file mode 100644
index 0000000000..e7ec683ced
--- /dev/null
+++ b/lib/modules/manager/helm-values/__fixtures__/single_file_with_multiple_documents.yaml
@@ -0,0 +1,38 @@
+apiVersion: source.toolkit.fluxcd.io/v1beta2
+kind: HelmRepository
+metadata:
+  name: metallb
+  namespace: flux-system
+spec:
+  interval: 30m
+  url: https://metallb.github.io/metallb
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+  name: metallb
+  namespace: flux-system
+spec:
+  interval: 5m
+  install:
+    createNamespace: true
+  targetNamespace: metallb-system
+  chart:
+    spec:
+      chart: metallb
+      version: 0.13.10
+      sourceRef:
+        kind: HelmRepository
+        name: metallb
+        namespace: flux-system
+  values:
+    controller:
+      image:
+        repository: quay.io/metallb/controller
+        tag: v0.13.10
+    speaker:
+      image:
+        repository: quay.io/metallb/speaker
+        tag: v0.13.10
+      frr:
+        enabled: false
diff --git a/lib/modules/manager/helm-values/extract.spec.ts b/lib/modules/manager/helm-values/extract.spec.ts
index 933954c235..9798984a88 100644
--- a/lib/modules/manager/helm-values/extract.spec.ts
+++ b/lib/modules/manager/helm-values/extract.spec.ts
@@ -42,5 +42,28 @@ describe('modules/manager/helm-values/extract', () => {
       expect(result).toMatchSnapshot();
       expect(result?.deps).toHaveLength(5);
     });
+
+    it('extract data from file with multiple documents', () => {
+      const multiDocumentFile = Fixtures.get(
+        'single_file_with_multiple_documents.yaml'
+      );
+      const result = extractPackageFile(multiDocumentFile);
+      expect(result).toMatchObject({
+        deps: [
+          {
+            currentValue: 'v0.13.10',
+            depName: 'quay.io/metallb/controller',
+            datasource: 'docker',
+            versioning: 'docker',
+          },
+          {
+            currentValue: 'v0.13.10',
+            depName: 'quay.io/metallb/speaker',
+            datasource: 'docker',
+            versioning: 'docker',
+          },
+        ],
+      });
+    });
   });
 });
diff --git a/lib/modules/manager/helm-values/extract.ts b/lib/modules/manager/helm-values/extract.ts
index 719f47b564..ce0f929000 100644
--- a/lib/modules/manager/helm-values/extract.ts
+++ b/lib/modules/manager/helm-values/extract.ts
@@ -1,4 +1,4 @@
-import { load } from 'js-yaml';
+import { loadAll } from 'js-yaml';
 import { logger } from '../../../logger';
 import { id as dockerVersioning } from '../../versioning/docker';
 import { getDep } from '../dockerfile/extract';
@@ -61,18 +61,23 @@ export function extractPackageFile(
   content: string,
   packageFile?: string
 ): PackageFileContent | null {
-  let parsedContent: Record<string, unknown> | HelmDockerImageDependency;
+  let parsedContent: Record<string, unknown>[] | HelmDockerImageDependency[];
   try {
     // a parser that allows extracting line numbers would be preferable, with
     // the current approach we need to match anything we find again during the update
     // TODO: fix me (#9610)
-    parsedContent = load(content, { json: true }) as any;
+    parsedContent = loadAll(content, null, { json: true }) as any;
   } catch (err) {
     logger.debug({ err, packageFile }, 'Failed to parse helm-values YAML');
     return null;
   }
   try {
-    const deps = findDependencies(parsedContent, []);
+    const deps: PackageDependency<Record<string, any>>[] = [];
+
+    for (const con of parsedContent) {
+      deps.push(...findDependencies(con, []));
+    }
+
     if (deps.length) {
       return { deps };
     }
-- 
GitLab