From 3983e33a356132bd42d6d82f942f52822791c167 Mon Sep 17 00:00:00 2001 From: secustor Date: Sun, 25 Feb 2024 13:14:57 +0100 Subject: [PATCH 1/2] refactor(manager/helmfile): use schema for yaml parsing --- .../__snapshots__/extract.spec.ts.snap | 44 ------------------- lib/modules/manager/helmfile/extract.spec.ts | 31 +++++++------ lib/modules/manager/helmfile/extract.ts | 28 +++--------- lib/modules/manager/helmfile/schema.ts | 13 ++++-- 4 files changed, 32 insertions(+), 84 deletions(-) diff --git a/lib/modules/manager/helmfile/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/helmfile/__snapshots__/extract.spec.ts.snap index a81b5d69302566..6f6a40faac0ed3 100644 --- a/lib/modules/manager/helmfile/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/helmfile/__snapshots__/extract.spec.ts.snap @@ -1,49 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`modules/manager/helmfile/extract extractPackageFile() parses multidoc yaml 1`] = ` -{ - "datasource": "helm", - "deps": [ - { - "depName": "manifests", - "skipReason": "local-chart", - }, - { - "currentValue": "7.4.3", - "depName": "rabbitmq", - "registryUrls": [ - "https://charts.bitnami.com/bitnami", - ], - }, - { - "currentValue": "13.7", - "depName": "kube-prometheus-stack", - "registryUrls": [ - "https://prometheus-community.github.io/helm-charts", - ], - }, - { - "depName": "invalid", - "skipReason": "invalid-name", - }, - { - "depName": "external-dns", - "skipReason": "invalid-version", - }, - { - "currentValue": "0.1.0", - "depName": "raw", - "registryUrls": [ - "https://charts.helm.sh/incubator/", - ], - }, - ], - "managerData": { - "needKustomize": true, - }, -} -`; - exports[`modules/manager/helmfile/extract extractPackageFile() skip chart that does not have specified version 1`] = ` { "datasource": "helm", diff --git a/lib/modules/manager/helmfile/extract.spec.ts b/lib/modules/manager/helmfile/extract.spec.ts index 315412754bccca..e2378baf3c38cc 100644 --- a/lib/modules/manager/helmfile/extract.spec.ts +++ b/lib/modules/manager/helmfile/extract.spec.ts @@ -212,15 +212,28 @@ describe('modules/manager/helmfile/extract', () => { }, }, ); - expect(result).toMatchSnapshot({ + expect(result).toMatchObject({ datasource: 'helm', deps: [ { depName: 'manifests', skipReason: 'local-chart' }, - { depName: 'rabbitmq', currentValue: '7.4.3' }, - { depName: 'kube-prometheus-stack', currentValue: '13.7' }, - { depName: 'invalid', skipReason: 'invalid-name' }, + { + depName: 'rabbitmq', + currentValue: '7.4.3', + registryUrls: ['https://charts.bitnami.com/bitnami'], + }, + { + depName: 'kube-prometheus-stack', + currentValue: '13.7', + registryUrls: [ + 'https://prometheus-community.github.io/helm-charts', + ], + }, { depName: 'external-dns', skipReason: 'invalid-version' }, - { depName: 'raw' }, + { + depName: 'raw', + currentValue: '0.1.0', + registryUrls: ['https://charts.helm.sh/incubator/'], + }, ], managerData: { needKustomize: true }, }); @@ -292,9 +305,6 @@ describe('modules/manager/helmfile/extract', () => { { skipReason: 'invalid-version', }, - { - skipReason: 'invalid-name', - }, { currentValue: '1.0.0', depName: 'example', @@ -380,10 +390,6 @@ describe('modules/manager/helmfile/extract', () => { depName: '', skipReason: 'local-chart', }, - { - depName: null, - skipReason: 'local-chart', - }, { depName: 'ingress-nginx', currentValue: '3.37.0', @@ -401,7 +407,6 @@ describe('modules/manager/helmfile/extract', () => { registryUrls: ['https://charts.helm.sh/stable'], }, { depName: 'kube-prometheus-stack', skipReason: 'invalid-version' }, - { depName: 'example-external', skipReason: 'invalid-name' }, { depName: 'external-dns', currentValue: '2.0.0', diff --git a/lib/modules/manager/helmfile/extract.ts b/lib/modules/manager/helmfile/extract.ts index fa34d53900d81a..9500571d29cf7c 100644 --- a/lib/modules/manager/helmfile/extract.ts +++ b/lib/modules/manager/helmfile/extract.ts @@ -1,5 +1,6 @@ import is from '@sindresorhus/is'; import { logger } from '../../../logger'; +import { coerceArray } from '../../../util/array'; import { regEx } from '../../../util/regex'; import { parseYaml } from '../../../util/yaml'; import { DockerDatasource } from '../../datasource/docker'; @@ -10,6 +11,7 @@ import type { PackageFileContent, } from '../types'; import type { Doc } from './schema'; +import { Doc as documentSchema } from './schema'; import { kustomizationsKeysUsed, localChartHasKustomizationsYaml, @@ -39,8 +41,9 @@ export async function extractPackageFile( // Record kustomization usage for all deps, since updating artifacts is run on the helmfile.yaml as a whole. let needKustomize = false; try { - // TODO: use schema (#9610) docs = parseYaml(content, null, { + customSchema: documentSchema, + failureBehaviour: 'filter', removeTemplates: true, json: true, }); @@ -52,10 +55,6 @@ export async function extractPackageFile( return null; } for (const doc of docs) { - if (!doc) { - continue; - } - // Always check for repositories in the current document and override the existing ones if any (as YAML does) if (doc.repositories) { registryAliases = {}; @@ -68,23 +67,10 @@ export async function extractPackageFile( ); } - // Skip extraction if the document contains no releases - if (!is.array(doc.releases)) { - continue; - } - - for (const dep of doc.releases) { + for (const dep of coerceArray(doc.releases)) { let depName = dep.chart; let repoName: string | null = null; - if (!is.string(dep.chart)) { - deps.push({ - depName: dep.name, - skipReason: 'invalid-name', - }); - continue; - } - // If it starts with ./ ../ or / then it's a local path if (isLocalPath(dep.chart)) { if ( @@ -100,10 +86,6 @@ export async function extractPackageFile( continue; } - if (is.number(dep.version)) { - dep.version = String(dep.version); - } - if (isOciUrl(dep.chart)) { const v = dep.chart.substring(6).split('/'); depName = v.pop()!; diff --git a/lib/modules/manager/helmfile/schema.ts b/lib/modules/manager/helmfile/schema.ts index a885e6265e7d94..48979ec3afd278 100644 --- a/lib/modules/manager/helmfile/schema.ts +++ b/lib/modules/manager/helmfile/schema.ts @@ -1,5 +1,5 @@ import { z } from 'zod'; -import { Yaml } from '../../../util/schema-utils'; +import { LooseArray, Yaml } from '../../../util/schema-utils'; export const HelmRepository = z.object({ name: z.string(), @@ -11,7 +11,12 @@ export type HelmRepository = z.infer; export const HelmRelease = z.object({ name: z.string(), chart: z.string(), - version: z.string(), + version: z + .string() + .or(z.number()) + .optional() + .nullable() + .transform((version) => (version ? String(version) : null)), strategicMergePatches: z.unknown().optional(), jsonPatches: z.unknown().optional(), transformers: z.unknown().optional(), @@ -19,8 +24,8 @@ export const HelmRelease = z.object({ export type HelmRelease = z.infer; export const Doc = z.object({ - releases: z.array(HelmRelease).optional(), - repositories: z.array(HelmRepository).optional(), + releases: LooseArray(HelmRelease).optional(), + repositories: LooseArray(HelmRepository).optional(), }); export type Doc = z.infer; From 17f543bf46af77890e9b068729832e2864637bba Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Sun, 25 Feb 2024 15:30:53 +0100 Subject: [PATCH 2/2] Update lib/modules/manager/helmfile/schema.ts Co-authored-by: Michael Kriese --- lib/modules/manager/helmfile/schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/manager/helmfile/schema.ts b/lib/modules/manager/helmfile/schema.ts index 48979ec3afd278..abfefc194ab169 100644 --- a/lib/modules/manager/helmfile/schema.ts +++ b/lib/modules/manager/helmfile/schema.ts @@ -16,7 +16,7 @@ export const HelmRelease = z.object({ .or(z.number()) .optional() .nullable() - .transform((version) => (version ? String(version) : null)), + .transform((version) => (version ? version.toString() : null)), strategicMergePatches: z.unknown().optional(), jsonPatches: z.unknown().optional(), transformers: z.unknown().optional(),