From 2867021b573910cbdbfd28713fb00edcbf1e58d3 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 30 Sep 2024 18:08:02 +0200 Subject: [PATCH 1/2] fix(helmfile): lock update for multidoc YAML Fixes #31651 Update Helmfile manager to handle multidoc YAMLs correctly. * Replace `parseSingleYaml` with `parseYaml` in `lib/modules/manager/helmfile/artifacts.ts` to handle multiple YAML documents. * Update the `doc` variable to handle multiple documents in the `updateArtifacts` function. * Add a test case in `lib/modules/manager/helmfile/artifacts.spec.ts` for updating the lockfile with a multidoc YAML. * Mock the `parseYaml` function to handle multiple documents in the test case. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/renovatebot/renovate/issues/31651?shareId=XXXX-XXXX-XXXX-XXXX). --- .../manager/helmfile/artifacts.spec.ts | 90 +++++++++++++++++++ lib/modules/manager/helmfile/artifacts.ts | 24 ++--- 2 files changed, 103 insertions(+), 11 deletions(-) diff --git a/lib/modules/manager/helmfile/artifacts.spec.ts b/lib/modules/manager/helmfile/artifacts.spec.ts index a6796903f6babe..ba5e7e6b5c6435 100644 --- a/lib/modules/manager/helmfile/artifacts.spec.ts +++ b/lib/modules/manager/helmfile/artifacts.spec.ts @@ -418,4 +418,94 @@ describe('modules/manager/helmfile/artifacts', () => { }, ]); }); + + it('updates lockfile with multidoc YAML', async () => { + const multidocYaml = codeBlock` + 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 + `; + const lockFileMultidoc = codeBlock` + version: 0.151.0 + dependencies: + - name: metallb + repository: https://metallb.github.io/metallb + version: 0.13.9 + digest: sha256:e284706b71f37b757a536703da4cb148d67901afbf1ab431f7d60a9852ca6eef + generated: "2023-03-08T21:32:06.122276997+01:00" + `; + const lockFileMultidocUpdated = codeBlock` + version: 0.151.0 + dependencies: + - name: metallb + repository: https://metallb.github.io/metallb + version: 0.13.10 + digest: sha256:9d83889176d005effb86041d30c20361625561cbfb439cbd16d7243225bac17c + generated: "2023-03-08T21:30:48.273709455+01:00" + `; + + git.getFile.mockResolvedValueOnce(lockFileMultidoc as never); + fs.getSiblingFileName.mockReturnValueOnce('helmfile.lock'); + const execSnapshots = mockExecAll(); + fs.readLocalFile.mockResolvedValueOnce(lockFileMultidocUpdated as never); + fs.privateCacheDir.mockReturnValue( + '/tmp/renovate/cache/__renovate-private-cache', + ); + fs.getParentDir.mockReturnValue(''); + const updatedDeps = [{ depName: 'metallb' }]; + expect( + await helmfile.updateArtifacts({ + packageFileName: 'helmfile.yaml', + updatedDeps, + newPackageFileContent: multidocYaml, + config, + }), + ).toEqual([ + { + file: { + type: 'addition', + path: 'helmfile.lock', + contents: lockFileMultidocUpdated, + }, + }, + ]); + expect(execSnapshots).toMatchObject([ + { cmd: 'helmfile deps -f helmfile.yaml' }, + ]); + }); }); diff --git a/lib/modules/manager/helmfile/artifacts.ts b/lib/modules/manager/helmfile/artifacts.ts index 21bcec72e6023e..b4661834aa901b 100644 --- a/lib/modules/manager/helmfile/artifacts.ts +++ b/lib/modules/manager/helmfile/artifacts.ts @@ -13,7 +13,7 @@ import { import { getFile } from '../../../util/git'; import { regEx } from '../../../util/regex'; import { Result } from '../../../util/result'; -import { parseSingleYaml } from '../../../util/yaml'; +import { parseYaml } from '../../../util/yaml'; import { generateHelmEnvs } from '../helmv3/common'; import type { UpdateArtifact, UpdateArtifactsResult } from '../types'; import { Doc, LockVersion } from './schema'; @@ -70,21 +70,23 @@ export async function updateArtifacts({ } const cmd: string[] = []; - const doc = parseSingleYaml(newPackageFileContent, { + const docs = parseYaml(newPackageFileContent, { removeTemplates: true, customSchema: Doc, }); - for (const value of coerceArray(doc.repositories).filter(isOCIRegistry)) { - const loginCmd = await generateRegistryLoginCmd( - value.name, - `https://${value.url}`, - // this extracts the hostname from url like format ghcr.ip/helm-charts - value.url.replace(regEx(/\/.*/), ''), - ); + for (const doc of docs) { + for (const value of coerceArray(doc.repositories).filter(isOCIRegistry)) { + const loginCmd = await generateRegistryLoginCmd( + value.name, + `https://${value.url}`, + // this extracts the hostname from url like format ghcr.ip/helm-charts + value.url.replace(regEx(/\/.*/), ''), + ); - if (loginCmd) { - cmd.push(loginCmd); + if (loginCmd) { + cmd.push(loginCmd); + } } } From cc97c82dd98492f640276304917db720145a274e Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 3 Oct 2024 09:34:34 +0200 Subject: [PATCH 2/2] filter --- lib/modules/manager/helmfile/artifacts.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/modules/manager/helmfile/artifacts.ts b/lib/modules/manager/helmfile/artifacts.ts index b4661834aa901b..745ee835e9f629 100644 --- a/lib/modules/manager/helmfile/artifacts.ts +++ b/lib/modules/manager/helmfile/artifacts.ts @@ -73,6 +73,7 @@ export async function updateArtifacts({ const docs = parseYaml(newPackageFileContent, { removeTemplates: true, customSchema: Doc, + failureBehaviour: 'filter', }); for (const doc of docs) {