From 30f0c4230f6eafde9f141ed1bc6b0786df4411a3 Mon Sep 17 00:00:00 2001 From: Gabriel Melillo Date: Sun, 2 Feb 2020 08:35:26 +0100 Subject: [PATCH] feat: helmfile manager (#5257) --- docs/usage/configuration-options.md | 2 + lib/config/definitions.ts | 15 ++ lib/constants/managers.ts | 1 + lib/manager/helmfile/extract.ts | 85 +++++++++ lib/manager/helmfile/index.ts | 2 + lib/manager/helmfile/update.ts | 74 ++++++++ lib/manager/index.ts | 2 + renovate-schema.json | 12 ++ .../__snapshots__/validation.spec.ts.snap | 2 +- .../__snapshots__/extract.spec.ts.snap | 104 +++++++++++ .../__snapshots__/update.spec.ts.snap | 46 +++++ test/manager/helmfile/extract.spec.ts | 171 ++++++++++++++++++ test/manager/helmfile/update.spec.ts | 137 ++++++++++++++ .../extract/__snapshots__/index.spec.ts.snap | 3 + 14 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 lib/manager/helmfile/extract.ts create mode 100644 lib/manager/helmfile/index.ts create mode 100644 lib/manager/helmfile/update.ts create mode 100644 test/manager/helmfile/__snapshots__/extract.spec.ts.snap create mode 100644 test/manager/helmfile/__snapshots__/update.spec.ts.snap create mode 100644 test/manager/helmfile/extract.spec.ts create mode 100644 test/manager/helmfile/update.spec.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 7d8f9a4f79d0eb..a4fd039f83a0de 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -483,6 +483,8 @@ Note: you shouldn't usually need to configure this unless you really care about Renovate supports updating Helm Chart references within `requirements.yaml` files. If your Helm charts make use of Aliases then you will need to configure an `aliases` object in your config to tell Renovate where to look for them. +## helmfile + ## homebrew ## hostRules diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 1409b3c9d2b4da..9bf118b65f501f 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1714,6 +1714,21 @@ const options: RenovateOptions[] = [ mergeable: true, cli: false, }, + { + name: 'helmfile', + description: 'Configuration object for helmfile helmfile.yaml files.', + stage: 'package', + type: 'object', + default: { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + commitMessageTopic: 'helm chart {{depName}}', + fileMatch: ['(^|/)helmfile.yaml$'], + }, + mergeable: true, + cli: false, + }, { name: 'circleci', description: diff --git a/lib/constants/managers.ts b/lib/constants/managers.ts index 8a9855d402e9cb..557a15706568c0 100644 --- a/lib/constants/managers.ts +++ b/lib/constants/managers.ts @@ -18,6 +18,7 @@ export const MANAGER_GO_MOD = 'gomod'; export const MANAGER_GRADLE = 'gradle'; export const MANAGER_GRADLE_WRAPPER = 'gradle-wrapper'; export const MANAGER_HELM_REQUIREMENTS = 'helm-requirements'; +export const MANAGER_HELMFILE = 'helmfile'; export const MANAGER_HOMEBREW = 'homebrew'; export const MANAGER_KUBERNETES = 'kubernetes'; export const MANAGER_LEININGEN = 'leiningen'; diff --git a/lib/manager/helmfile/extract.ts b/lib/manager/helmfile/extract.ts new file mode 100644 index 00000000000000..efc02a4a2e95ea --- /dev/null +++ b/lib/manager/helmfile/extract.ts @@ -0,0 +1,85 @@ +import is from '@sindresorhus/is'; +import yaml from 'js-yaml'; + +import { logger } from '../../logger'; +import { PackageFile, PackageDependency, ExtractConfig } from '../common'; + +const isValidChartName = (name: string): boolean => { + return name.match(/[!@#$%^&*(),.?":{}/|<>A-Z]/) === null; +}; + +export function extractPackageFile( + content: string, + fileName: string, + config: ExtractConfig +): PackageFile { + let deps = []; + let doc; + const aliases: Record = {}; + try { + doc = yaml.safeLoad(content, { json: true }); + } catch (err) { + logger.debug({ err, fileName }, 'Failed to parse helmfile helmfile.yaml'); + return null; + } + if (!(doc && is.array(doc.releases))) { + logger.debug({ fileName }, 'helmfile.yaml has no releases'); + return null; + } + + if (doc.repositories) { + for (let i = 0; i < doc.repositories.length; i += 1) { + aliases[doc.repositories[i].name] = doc.repositories[i].url; + } + } + logger.debug({ aliases }, 'repositories discovered.'); + + deps = doc.releases.map(dep => { + let depName = dep.chart; + let repoName = null; + + // If starts with ./ is for sure a local path + if (dep.chart.startsWith('./')) { + return { + depName, + skipReason: 'local-chart', + } as PackageDependency; + } + + if (dep.chart.includes('/')) { + const v = dep.chart.split('/'); + repoName = v.shift(); + depName = v.join('/'); + } else { + repoName = dep.chart; + } + + const res: PackageDependency = { + depName, + currentValue: dep.version, + registryUrls: [aliases[repoName]] + .concat([config.aliases[repoName]]) + .filter(Boolean), + }; + + // If version is null is probably a local chart + if (!res.currentValue) { + res.skipReason = 'local-chart'; + } + + // By definition on helm the chart name should be lowecase letter + number + - + // However helmfile support templating of that field + if (!isValidChartName(res.depName)) { + res.skipReason = 'unsupported-chart-type'; + } + + // Skip in case we cannot locate the registry + if (is.emptyArray(res.registryUrls)) { + res.skipReason = 'unknown-registry'; + } + + return res; + }); + + return { deps, datasource: 'helm' } as PackageFile; +} diff --git a/lib/manager/helmfile/index.ts b/lib/manager/helmfile/index.ts new file mode 100644 index 00000000000000..730b5b60ba42a3 --- /dev/null +++ b/lib/manager/helmfile/index.ts @@ -0,0 +1,2 @@ +export { extractPackageFile } from './extract'; +export { updateDependency } from './update'; diff --git a/lib/manager/helmfile/update.ts b/lib/manager/helmfile/update.ts new file mode 100644 index 00000000000000..a62e3f2134a1b3 --- /dev/null +++ b/lib/manager/helmfile/update.ts @@ -0,0 +1,74 @@ +import _ from 'lodash'; +import yaml from 'js-yaml'; +import is from '@sindresorhus/is'; + +import { logger } from '../../logger'; +import { Upgrade } from '../common'; + +// Return true if the match string is found at index in content +function matchAt(content: string, index: number, match: string): boolean { + return content.substring(index, index + match.length) === match; +} + +// Replace oldString with newString at location index of content +function replaceAt( + content: string, + index: number, + oldString: string, + newString: string +): string { + logger.debug(`Replacing ${oldString} with ${newString} at index ${index}`); + return ( + content.substr(0, index) + + newString + + content.substr(index + oldString.length) + ); +} + +export function updateDependency( + fileContent: string, + upgrade: Upgrade +): string | null { + logger.trace({ config: upgrade }, 'updateDependency()'); + if (!upgrade || !upgrade.depName || !upgrade.newValue) { + logger.debug('Failed to update dependency, invalid upgrade'); + return fileContent; + } + const doc = yaml.safeLoad(fileContent, { json: true }); + if (!doc || !is.array(doc.releases)) { + logger.debug('Failed to update dependency, invalid helmfile.yaml file'); + return fileContent; + } + const { depName, newValue } = upgrade; + const oldVersion = doc.releases.filter( + dep => dep.chart.split('/')[1] === depName + )[0].version; + doc.releases = doc.releases.map(dep => + dep.chart.split('/')[1] === depName ? { ...dep, version: newValue } : dep + ); + const searchString = `${oldVersion}`; + const newString = `${newValue}`; + let newFileContent = fileContent; + + let searchIndex = newFileContent.indexOf('releases') + 'releases'.length; + for (; searchIndex < newFileContent.length; searchIndex += 1) { + // First check if we have a hit for the old version + if (matchAt(newFileContent, searchIndex, searchString)) { + logger.trace(`Found match at index ${searchIndex}`); + // Now test if the result matches + newFileContent = replaceAt( + newFileContent, + searchIndex, + searchString, + newString + ); + } + } + // Compare the parsed yaml structure of old and new + if (!_.isEqual(doc, yaml.safeLoad(newFileContent, { json: true }))) { + logger.trace(`Mismatched replace: ${newFileContent}`); + newFileContent = fileContent; + } + + return newFileContent; +} diff --git a/lib/manager/index.ts b/lib/manager/index.ts index b67aa180aab7bd..c64b9ce80aaa5d 100644 --- a/lib/manager/index.ts +++ b/lib/manager/index.ts @@ -42,6 +42,7 @@ import { MANAGER_GRADLE, MANAGER_GRADLE_WRAPPER, MANAGER_HELM_REQUIREMENTS, + MANAGER_HELMFILE, MANAGER_HOMEBREW, MANAGER_KUBERNETES, MANAGER_LEININGEN, @@ -84,6 +85,7 @@ const managerList = [ MANAGER_GRADLE, MANAGER_GRADLE_WRAPPER, MANAGER_HELM_REQUIREMENTS, + MANAGER_HELMFILE, MANAGER_HOMEBREW, MANAGER_KUBERNETES, MANAGER_LEININGEN, diff --git a/renovate-schema.json b/renovate-schema.json index 751aa482480b1c..4a952be5df9b3b 100644 --- a/renovate-schema.json +++ b/renovate-schema.json @@ -1123,6 +1123,18 @@ }, "$ref": "#" }, + "helmfile": { + "description": "Configuration object for helmfile helmfile.yaml files.", + "type": "object", + "default": { + "aliases": { + "stable": "https://kubernetes-charts.storage.googleapis.com/" + }, + "commitMessageTopic": "helm chart {{depName}}", + "fileMatch": ["(^|/)helmfile.yaml$"] + }, + "$ref": "#" + }, "circleci": { "description": "Configuration object for CircleCI yml renovation. Also inherits settings from `docker` object.", "type": "object", diff --git a/test/config/__snapshots__/validation.spec.ts.snap b/test/config/__snapshots__/validation.spec.ts.snap index 0b0e95f72df03a..b8f36dbfb948f2 100644 --- a/test/config/__snapshots__/validation.spec.ts.snap +++ b/test/config/__snapshots__/validation.spec.ts.snap @@ -96,7 +96,7 @@ Array [ "depName": "Configuration Error", "message": "packageRules: You have included an unsupported manager in a package rule. Your list: foo. - Supported managers are: (ansible, bazel, buildkite, bundler, cargo, cdnurl, circleci, composer, deps-edn, docker-compose, dockerfile, droneci, git-submodules, github-actions, gitlabci, gitlabci-include, gomod, gradle, gradle-wrapper, helm-requirements, homebrew, kubernetes, leiningen, maven, meteor, mix, npm, nuget, nvm, pip_requirements, pip_setup, pipenv, poetry, pub, sbt, swift, terraform, travis, ruby-version).", + Supported managers are: (ansible, bazel, buildkite, bundler, cargo, cdnurl, circleci, composer, deps-edn, docker-compose, dockerfile, droneci, git-submodules, github-actions, gitlabci, gitlabci-include, gomod, gradle, gradle-wrapper, helm-requirements, helmfile, homebrew, kubernetes, leiningen, maven, meteor, mix, npm, nuget, nvm, pip_requirements, pip_setup, pipenv, poetry, pub, sbt, swift, terraform, travis, ruby-version).", }, ] `; diff --git a/test/manager/helmfile/__snapshots__/extract.spec.ts.snap b/test/manager/helmfile/__snapshots__/extract.spec.ts.snap new file mode 100644 index 00000000000000..5a093a75ea2afb --- /dev/null +++ b/test/manager/helmfile/__snapshots__/extract.spec.ts.snap @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lib/manager/helmfile/extract extractPackageFile() skip chart that does not have specified version 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "currentValue": undefined, + "depName": "example", + "registryUrls": Array [ + "https://kubernetes-charts.storage.googleapis.com/", + ], + "skipReason": "local-chart", + }, + ], +} +`; + +exports[`lib/manager/helmfile/extract extractPackageFile() skip chart with special character in the name 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "currentValue": "1.0.0", + "depName": "example/example", + "registryUrls": Array [ + "https://kiwigrid.github.io", + ], + "skipReason": "unsupported-chart-type", + }, + Object { + "currentValue": "1.0.0", + "depName": "example?example", + "registryUrls": Array [ + "https://kiwigrid.github.io", + ], + "skipReason": "unsupported-chart-type", + }, + ], +} +`; + +exports[`lib/manager/helmfile/extract extractPackageFile() skip chart with unknown repository 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "currentValue": "1.0.0", + "depName": "example", + "registryUrls": Array [], + "skipReason": "unknown-registry", + }, + ], +} +`; + +exports[`lib/manager/helmfile/extract extractPackageFile() skip if repository details are not specified 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "currentValue": "1.0.0", + "depName": "example", + "registryUrls": Array [], + "skipReason": "unknown-registry", + }, + ], +} +`; + +exports[`lib/manager/helmfile/extract extractPackageFile() skip local charts 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "depName": "./charts/example", + "skipReason": "local-chart", + }, + ], +} +`; + +exports[`lib/manager/helmfile/extract extractPackageFile() skip templetized release with invalid characters 1`] = ` +Object { + "datasource": "helm", + "deps": Array [ + Object { + "currentValue": "1.0.0", + "depName": "{{\`{{ .Release.Name }}\`}}", + "registryUrls": Array [ + "https://kubernetes-charts.storage.googleapis.com/", + ], + "skipReason": "unsupported-chart-type", + }, + Object { + "currentValue": "1.0.0", + "depName": "example", + "registryUrls": Array [ + "https://kubernetes-charts.storage.googleapis.com/", + ], + }, + ], +} +`; diff --git a/test/manager/helmfile/__snapshots__/update.spec.ts.snap b/test/manager/helmfile/__snapshots__/update.spec.ts.snap new file mode 100644 index 00000000000000..5336665539859d --- /dev/null +++ b/test/manager/helmfile/__snapshots__/update.spec.ts.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lib/manager/helmfile/extract updateDependency() upgrades dependency if chart is repeated 1`] = ` +" + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + + releases: + - name: fluentd-elasticsearch-internal + version: 5.3.1 + chart: kiwigrid/fluentd-elasticsearch + + - name: nginx-ingress + version: 1.3.0 + chart: stable/nginx-ingress + + - name: fluentd-elasticsearch-external + version: 5.3.1 + chart: kiwigrid/fluentd-elasticsearch + " +`; + +exports[`lib/manager/helmfile/extract updateDependency() upgrades dependency if valid upgrade 1`] = ` +" + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: fluentd-elasticsearch + version: 5.3.1 + chart: kiwigrid/fluentd-elasticsearch + " +`; + +exports[`lib/manager/helmfile/extract updateDependency() upgrades dependency if version field comes before name field 1`] = ` +" + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - version: 5.3.1 + name: fluentd-elasticsearch + chart: kiwigrid/fluentd-elasticsearch + " +`; diff --git a/test/manager/helmfile/extract.spec.ts b/test/manager/helmfile/extract.spec.ts new file mode 100644 index 00000000000000..1360aa8a9f1480 --- /dev/null +++ b/test/manager/helmfile/extract.spec.ts @@ -0,0 +1,171 @@ +import { extractPackageFile } from '../../../lib/manager/helmfile/extract'; + +describe('lib/manager/helmfile/extract', () => { + describe('extractPackageFile()', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('returns null if no releases', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).toBeNull(); + }); + + it('do not crash on invalid helmfile.yaml', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + + releases: [ + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).toBeNull(); + }); + + it('skip if repository details are not specified', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + version: 1.0.0 + chart: experimental/example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + expect(result.deps.every(dep => dep.skipReason)); + }); + + it('skip templetized release with invalid characters', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + version: 1.0.0 + chart: stable/{{\`{{ .Release.Name }}\`}} + - name: example-internal + version: 1.0.0 + chart: stable/example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + }); + + it('skip local charts', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + version: 1.0.0 + chart: ./charts/example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + expect(result.deps.every(dep => dep.skipReason)); + }); + + it('skip chart with unknown repository', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + version: 1.0.0 + chart: example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + expect(result.deps.every(dep => dep.skipReason)); + }); + + it('skip chart with special character in the name', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + version: 1.0.0 + chart: kiwigrid/example/example + - name: example2 + version: 1.0.0 + chart: kiwigrid/example?example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + expect(result.deps.every(dep => dep.skipReason)); + }); + + it('skip chart that does not have specified version', async () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: example + chart: stable/example + `; + const fileName = 'helmfile.yaml'; + const result = await extractPackageFile(content, fileName, { + aliases: { + stable: 'https://kubernetes-charts.storage.googleapis.com/', + }, + }); + expect(result).not.toBeNull(); + expect(result).toMatchSnapshot(); + expect(result.deps.every(dep => dep.skipReason)); + }); + }); +}); diff --git a/test/manager/helmfile/update.spec.ts b/test/manager/helmfile/update.spec.ts new file mode 100644 index 00000000000000..06cd8df1c5abab --- /dev/null +++ b/test/manager/helmfile/update.spec.ts @@ -0,0 +1,137 @@ +import { updateDependency } from '../../../lib/manager/helmfile/update'; + +describe('lib/manager/helmfile/extract', () => { + describe('updateDependency()', () => { + it('returns the same fileContent for undefined upgrade', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: fluentd-elasticsearch + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = undefined; + + expect(updateDependency(content, upgrade)).toBe(content); + }); + + it('returns the same fileContent for invalid helmfile.yaml file', () => { + const content = ` + Invalid helmfile.yaml content. + `; + const upgrade = { + depName: 'fluentd-elasticsearch', + newValue: '5.3.0', + repository: 'https://kiwigrid.github.io', + }; + expect(updateDependency(content, upgrade)).toBe(content); + }); + + it('returns the same fileContent for empty upgrade', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: fluentd-elasticsearch + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = {}; + expect(updateDependency(content, upgrade)).toBe(content); + }); + + it('upgrades dependency if valid upgrade', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - name: fluentd-elasticsearch + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = { + depName: 'fluentd-elasticsearch', + newValue: '5.3.1', + repository: 'https://kiwigrid.github.io', + }; + expect(updateDependency(content, upgrade)).not.toBe(content); + expect(updateDependency(content, upgrade)).toMatchSnapshot(); + }); + + it('upgrades dependency if version field comes before name field', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + releases: + - version: 5.3.0 + name: fluentd-elasticsearch + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = { + depName: 'fluentd-elasticsearch', + newValue: '5.3.1', + repository: 'https://kiwigrid.github.io', + }; + expect(updateDependency(content, upgrade)).not.toBe(content); + expect(updateDependency(content, upgrade)).toMatchSnapshot(); + }); + + it('upgrades dependency if chart is repeated', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + + releases: + - name: fluentd-elasticsearch-internal + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + + - name: nginx-ingress + version: 1.3.0 + chart: stable/nginx-ingress + + - name: fluentd-elasticsearch-external + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = { + depName: 'fluentd-elasticsearch', + newValue: '5.3.1', + repository: 'https://kiwigrid.github.io', + }; + expect(updateDependency(content, upgrade)).not.toBe(content); + expect(updateDependency(content, upgrade)).toMatchSnapshot(); + }); + + it('Not fail if same version in multiple package', () => { + const content = ` + repositories: + - name: kiwigrid + url: https://kiwigrid.github.io + + releases: + - name: fluentd-elasticsearch-internal + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + - name: nginx-ingress + version: 5.3.0 + chart: stable/nginx-ingress + - name: fluentd-elasticsearch-external + version: 5.3.0 + chart: kiwigrid/fluentd-elasticsearch + `; + const upgrade = { + depName: 'fluentd-elasticsearch', + newValue: '5.3.1', + repository: 'https://kiwigrid.github.io', + }; + expect(updateDependency(content, upgrade)).toBe(content); + }); + }); +}); diff --git a/test/workers/repository/extract/__snapshots__/index.spec.ts.snap b/test/workers/repository/extract/__snapshots__/index.spec.ts.snap index d693641f9ea4ff..d63407073d8d62 100644 --- a/test/workers/repository/extract/__snapshots__/index.spec.ts.snap +++ b/test/workers/repository/extract/__snapshots__/index.spec.ts.snap @@ -62,6 +62,9 @@ Object { "helm-requirements": Array [ Object {}, ], + "helmfile": Array [ + Object {}, + ], "homebrew": Array [ Object {}, ],