Files
renovate/lib/modules/manager/flux/extract.spec.ts
Sebastian Poxhofer be13c9f5f7 feat(manager): share OCI Helm chart resolution across managers (#45760)
* feat(manager): share OCI Helm chart resolution across managers

Add getOciChartDep() to helmv3/oci.ts and use it in argocd, fleet, flux,
helmfile, helmsman, helmv3, kustomize, sveltos, terraform and vendir.

- set pinDigests: false for OCI charts in all of them
- apply registryAliases to OCI charts in argocd, helmfile and helmsman
- keep the registry port in terraform helm_release repositories
- skip fleet OCI charts without a version instead of using 'undefined'

* docs(manager/helmv3): correct the OCI chart pinDigests rationale

* refactor(manager/helmfile): drop redundant OCI repository url guard

The repository schema already requires url to be a string, so the falsy
branch could not be reached by parsed input and left the patch partially
covered.
2026-09-09 13:51:30 +00:00

1828 lines
56 KiB
TypeScript

import { codeBlock } from 'common-tags';
import { Fixtures } from '~test/fixtures.ts';
import { GlobalConfig } from '../../../config/global.ts';
import type {
InternalGlobalConfigOptions,
RepoGlobalConfig,
} from '../../../config/types.ts';
import { compile } from '../../../util/template/index.ts';
import { BitbucketTagsDatasource } from '../../datasource/bitbucket-tags/index.ts';
import { DockerDatasource } from '../../datasource/docker/index.ts';
import { GitRefsDatasource } from '../../datasource/git-refs/index.ts';
import { GitTagsDatasource } from '../../datasource/git-tags/index.ts';
import { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';
import { GitlabTagsDatasource } from '../../datasource/gitlab-tags/index.ts';
import { HelmDatasource } from '../../datasource/helm/index.ts';
import type { ExtractConfig } from '../types.ts';
import { extractAllPackageFiles, extractPackageFile } from './index.ts';
const config: ExtractConfig = {};
const adminConfig: RepoGlobalConfig & InternalGlobalConfigOptions = {
localDir: '',
};
const fixtureHelmSource = Fixtures.get('helmSource.yaml');
const fixtureHelmChart = Fixtures.get('helmChart.yaml');
const fixtureHelmChartRefRelease = Fixtures.get('helmChartRefRelease.yaml');
describe('modules/manager/flux/extract', () => {
beforeEach(() => {
GlobalConfig.set(adminConfig);
});
describe('extractPackageFile()', () => {
it('extracts multiple resources', () => {
const result = extractPackageFile(
Fixtures.get('multidoc.yaml'),
'multidoc.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '1.7.0',
datasource: HelmDatasource.id,
depName: 'external-dns',
registryUrls: ['https://kubernetes-sigs.github.io/external-dns/'],
},
{
autoReplaceStringTemplate:
'{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v0.13.4',
datasource: DockerDatasource.id,
depName: 'k8s.gcr.io/external-dns/external-dns',
packageName: 'k8s.gcr.io/external-dns/external-dns',
replaceString: 'v0.13.4',
versioning: DockerDatasource.id,
},
{
currentValue: 'v11.35.4',
datasource: GithubTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: 'tag: v1.8.2',
},
],
});
const ociDep = result?.deps.find(
(dep) => dep.depName === 'ghcr.io/kyverno/manifests/kyverno',
);
expect(
compile(
ociDep!.autoReplaceStringTemplate!,
{ newValue: 'v2.0.0' },
false,
),
).toBe('tag: v2.0.0');
expect(
compile(
ociDep!.autoReplaceStringTemplate!,
{ newValue: 'v2.0.0', newDigest: 'sha256:abcd' },
false,
),
).toBe('tag: v2.0.0\n digest: sha256:abcd');
});
it('keeps HelmRelease values image replacement in inline tag@digest format', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmSource}
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: sealed-secrets
namespace: kube-system
spec:
chart:
spec:
chart: sealed-secrets
sourceRef:
kind: HelmRepository
name: sealed-secrets
version: "2.0.2"
values:
image:
repository: ghcr.io/example/app
tag: v1.2.3
`,
'test.yaml',
);
expect(result?.deps).toContainEqual(
expect.objectContaining({
depName: 'ghcr.io/example/app',
currentValue: 'v1.2.3',
autoReplaceStringTemplate:
'{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',
replaceString: 'v1.2.3',
}),
);
const imageDep = result?.deps.find(
(dep) => dep.depName === 'ghcr.io/example/app',
);
expect(
compile(
imageDep!.autoReplaceStringTemplate!,
{ newValue: 'v1.2.4', newDigest: 'sha256:abcd' },
false,
),
).toBe('v1.2.4@sha256:abcd');
});
it.each`
filepath
${'clusters/my-cluster/flux-system/gotk-components.yaml'}
${'clusters/my-cluster/flux-system/gotk-components.yml'}
${'clusters/my-cluster/gotk-components.yaml'}
${'clusters/my-cluster/gotk-components.yml'}
${'gotk-components.yaml'}
`(
'extracts version and components from system manifest at $filepath',
({ filepath }) => {
const result = extractPackageFile(
Fixtures.get('flux-system/gotk-components.yaml'),
filepath,
);
expect(result).toEqual({
deps: [
{
currentValue: 'v0.24.1',
datasource: 'github-releases',
depName: 'fluxcd/flux2',
managerData: {
components:
'source-controller,kustomize-controller,helm-controller,notification-controller',
},
},
],
});
},
);
it('considers components optional in system manifests', () => {
const result = extractPackageFile(
`# Flux Version: v0.27.0`,
'clusters/my-cluster/flux-system/gotk-components.yaml',
);
expect(result).not.toBeNull();
expect(result?.deps[0].managerData?.components).toBeUndefined();
});
it('ignores system manifests without a version', () => {
const result = extractPackageFile(
'not actually a system manifest!',
'clusters/my-cluster/flux-system/gotk-components.yaml',
);
expect(result).toBeNull();
});
it('extracts releases without repositories', () => {
const result = extractPackageFile(
Fixtures.get('helmRelease.yaml'),
'helmRelease.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: 'helm',
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('falls back to unknown-registry when registryAliases has no matching HelmRelease sourceRef name', () => {
const result = extractPackageFile(
Fixtures.get('helmRelease.yaml'),
'helmRelease.yaml',
{
registryAliases: {
'other-repo': 'https://example.com/charts',
},
},
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('uses registryAliases to resolve HelmRelease sourceRef name when repository is missing', () => {
const result = extractPackageFile(
Fixtures.get('helmRelease.yaml'),
'helmRelease.yaml',
{
registryAliases: {
'sealed-secrets': 'https://example.com/charts',
},
},
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://example.com/charts'],
},
],
});
});
it('uses registryAliases with an OCI URL for HelmRelease sourceRef name', () => {
const result = extractPackageFile(
Fixtures.get('helmRelease.yaml'),
'helmRelease.yaml',
{
registryAliases: {
'sealed-secrets': 'oci://ghcr.io/charts',
},
},
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: DockerDatasource.id,
depName: 'sealed-secrets',
packageName: 'ghcr.io/charts/sealed-secrets',
pinDigests: false,
},
],
});
});
it('ignores HelmRelease resources without an apiVersion', () => {
const result = extractPackageFile('kind: HelmRelease', 'test.yaml');
expect(result).toBeNull();
});
it('ignores HelmRepository resources without an apiVersion', () => {
const result = extractPackageFile('kind: HelmRepository', 'test.yaml');
expect(result).toBeNull();
});
it('ignores HelmRepository resources without metadata', () => {
const result = extractPackageFile(
codeBlock`
${Fixtures.get('helmRelease.yaml')}
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('ignores HelmRelease resources without any chart reference', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: sealed-secrets
namespace: kube-system
spec:
interval: 10m
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores HelmRelease resources without a chart name', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: sealed-secrets
namespace: kube-system
spec:
chart:
spec:
sourceRef:
kind: HelmRepository
name: sealed-secrets
version: "2.0.2"
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('skip HelmRelease with local chart', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: cert-manager-config
namespace: kube-system
spec:
chart:
spec:
chart: ./charts/cert-manager-config
sourceRef:
kind: GitRepository
name: chart-repo
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
depName: './charts/cert-manager-config',
skipReason: 'local-chart',
},
],
});
});
it('does not match HelmRelease resources without a namespace to HelmRepository resources without a namespace', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: sealed-secrets
spec:
url: https://bitnami-labs.github.io/sealed-secrets
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
spec:
chart:
spec:
chart: sealed-secrets
sourceRef:
kind: HelmRepository
name: sealed-secrets
version: "2.0.2"
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('does not match HelmRelease resources without a sourceRef', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmSource}
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: sealed-secrets
namespace: test
spec:
chart:
spec:
chart: sealed-secrets
version: "2.0.2"
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('does not match HelmRelease resources without a namespace', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmSource}
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
spec:
chart:
spec:
chart: sealed-secrets
sourceRef:
kind: HelmRepository
name: sealed-secrets
version: "2.0.2"
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores HelmRepository resources without a namespace', () => {
const result = extractPackageFile(
codeBlock`
${Fixtures.get('helmRelease.yaml')}
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: test
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('ignores HelmRepository resources without a URL', () => {
const result = extractPackageFile(
codeBlock`
${Fixtures.get('helmRelease.yaml')}
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: sealed-secrets
namespace: kube-system
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('ignores HelmRelease resources using an invalid chartRef', () => {
const result = extractPackageFile(
fixtureHelmChartRefRelease,
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores HelmRelease resources using a chartRef targetting a HelmChart', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmChartRefRelease}
---
${fixtureHelmChart}
---
${fixtureHelmSource}
`,
'test.yaml',
);
// HelmRelease is ignored, only HelmChart itself is processed (-> no duplicates expected)
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://bitnami-labs.github.io/sealed-secrets'],
},
],
});
});
it('ignores HelmRelease resources using a chartRef targetting an OCIRepository', () => {
const result = extractPackageFile(
codeBlock`
${Fixtures.get('ociSource.yaml')}
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kyverno-controller
namespace: kube-system
spec:
chartRef:
kind: OCIRepository
name: kyverno-controller
namespace: kube-system
`,
'test.yaml',
);
// HelmRelease is ignored, only OCIRepository itself is processed (-> no duplicates expected)
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
});
});
it('extracts HelmChart version', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmSource}
---
${fixtureHelmChart}
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://bitnami-labs.github.io/sealed-secrets'],
},
],
});
});
it('does not match HelmChart resources without a namespace', () => {
const result = extractPackageFile(
codeBlock`
${fixtureHelmSource}
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: sealed-secrets
spec:
interval: 10m
chart: sealed-secrets
sourceRef:
kind: HelmRepository
name: sealed-secrets
version: "2.0.2"
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('falls back to unknown-registry when registryAliases has no matching HelmChart sourceRef name', () => {
const result = extractPackageFile(
Fixtures.get('helmChart.yaml'),
'helmChart.yaml',
{
registryAliases: {
'other-repo': 'https://example.com/charts',
},
},
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
skipReason: 'unknown-registry',
},
],
});
});
it('uses registryAliases to resolve HelmChart sourceRef name when repository is missing', () => {
const result = extractPackageFile(
Fixtures.get('helmChart.yaml'),
'helmChart.yaml',
{
registryAliases: {
'sealed-secrets': 'https://example.com/charts',
},
},
);
expect(result).toEqual({
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://example.com/charts'],
},
],
});
});
it('ignores HelmChart resources using git sources', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: sealed-secrets
namespace: kube-system
spec:
interval: 10m
chart: ./helm/sealed-secrets
sourceRef:
kind: GitRepository
name: sealed-secrets
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores HelmChart resources using bucket sources', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1
kind: Bucket
metadata:
name: sealed-secrets
namespace: kube-system
spec:
interval: 5m0s
endpoint: sealed-secrets.example.com
bucketName: example
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: sealed-secrets
namespace: kube-system
spec:
interval: 10m
chart: ./helm/sealed-secrets
sourceRef:
kind: Bucket
name: sealed-secrets
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
depName: './helm/sealed-secrets',
skipReason: 'unsupported-datasource',
},
],
});
});
it('ignores GitRepository without a tag nor a commit', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
url: https://github.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{ depName: 'renovate-repo', skipReason: 'unversioned-reference' },
],
});
});
it('extracts GitRepository with a commit', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
commit: c93154b
url: https://github.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentDigest: 'c93154b',
datasource: GitRefsDatasource.id,
depName: 'renovate-repo',
packageName: 'https://github.com/renovatebot/renovate',
replaceString: 'c93154b',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with both commit and branch', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
commit: adf1fce
branch: hotfix/39.264.1
url: https://github.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentDigest: 'adf1fce',
currentValue: 'hotfix/39.264.1',
datasource: GitRefsDatasource.id,
depName: 'renovate-repo',
packageName: 'https://github.com/renovatebot/renovate',
replaceString: 'adf1fce',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with a tag from github with ssh', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
tag: v11.35.9
url: git@github.com:renovatebot/renovate.git
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: 'v11.35.9',
datasource: GithubTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with a tag from github', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
tag: v11.35.9
url: https://github.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: 'v11.35.9',
datasource: GithubTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with a tag from gitlab', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
tag: 1.2.3
url: https://gitlab.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '1.2.3',
datasource: GitlabTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://gitlab.com/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with a tag from bitbucket', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
tag: 2020.5.6+staging.ze
url: https://bitbucket.org/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '2020.5.6+staging.ze',
datasource: BitbucketTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://bitbucket.org/renovatebot/renovate',
},
],
});
});
it('extracts GitRepository with a tag from an unkown domain', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: renovate-repo
namespace: renovate-system
spec:
ref:
tag: "7.56.4_p1"
url: https://example.com/renovatebot/renovate
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentValue: '7.56.4_p1',
datasource: GitTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'https://example.com/renovatebot/renovate',
sourceUrl: 'https://example.com/renovatebot/renovate',
},
],
});
});
it('ignores OCIRepository with no tag and no digest', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentDigest: undefined,
currentValue: undefined,
datasource: 'docker',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
skipReason: 'unversioned-reference',
},
],
});
});
it('extracts OCIRepository with a tag', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
tag: v1.8.2
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
{
registryAliases: {
'ghcr.io': 'ghcr.proxy.test/some/path',
},
},
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentValue: 'v1.8.2',
currentDigest: undefined,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.proxy.test/some/path/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
});
});
it('extracts OCIRepository with a quoted tag', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
tag: "v1.8.2"
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: "{{newValue}}"{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: "v1.8.2"',
},
],
});
});
it('extracts OCIRepository with a tag and preserves 4-space ref indentation', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
tag: v1.8.2
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
});
});
it('extracts OCIRepository with a tag when ref is after url', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: v1.8.2
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
});
});
it('extracts OCIRepository with a tag and preserves CRLF newlines in replacement template', () => {
const result = extractPackageFile(
[
'apiVersion: source.toolkit.fluxcd.io/v1beta2',
'kind: OCIRepository',
'metadata:',
' name: kyverno-controller',
'spec:',
' url: oci://ghcr.io/kyverno/manifests/kyverno',
' ref:',
' tag: v1.8.2',
'',
].join('\r\n'),
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\r\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
});
});
it('extracts OCIRepository with a digest', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
},
],
});
});
it('repairs OCIRepository with a tag that contains an inline digest by emitting a separate digest line', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
tag: v1.8.2@sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString:
'tag: v1.8.2@sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
},
],
});
});
it('extracts OCIRepository with a digest and tag', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
tag: v1.8.2
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/digest: \{\{newDigest}}\n\s*tag: \{\{newValue}}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc\n\s*tag: v1\.8\.2/,
),
},
],
});
});
it('extracts OCIRepository with quoted digest and tag', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
ref:
tag: "v1.8.2"
digest: "sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc"
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: "{{newValue}}"\n\s*digest: "{{newDigest}}"/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: "v1\.8\.2"\n\s*digest: "sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc"/,
),
},
],
});
});
it('extracts OCIRepository with quoted keys', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
spec:
ref:
"tag": v1.8.2
"digest": sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
url: oci://ghcr.io/kyverno/manifests/kyverno
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'"tag": {{newValue}}\n "digest": {{newDigest}}',
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString:
'"tag": v1.8.2\n "digest": sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
},
],
});
});
it('extracts OCIRepository when ref key is quoted', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
"ref":
tag: v1.8.2
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: \{\{newValue\}\}\n\s*digest: \{\{newDigest\}\}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: v1\.8\.2\n\s*digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc/,
),
},
],
});
});
it('skips OCIRepository when tag value is a YAML alias', () => {
const result = extractPackageFile(
codeBlock`
x-tag: &mytag v1.8.2
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: *mytag
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
skipReason: 'invalid-value',
},
],
});
});
it('extracts OCIRepository with tag and digest preceded by other document types', () => {
const result = extractPackageFile(
codeBlock`
---
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
url: https://charts.bitnami.com/bitnami
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: other-oci
namespace: flux-system
spec:
url: oci://ghcr.io/other/repo
ref:
tag: v1.0.0
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: v1.8.2
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.0.0',
datasource: DockerDatasource.id,
depName: 'ghcr.io/other/repo',
packageName: 'ghcr.io/other/repo',
replaceString: 'tag: v1.0.0',
},
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: \{\{newValue\}\}\n\s*digest: \{\{newDigest\}\}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: v1\.8\.2\n\s*digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc/,
),
},
],
});
});
it('extracts OCIRepository with tag and digest when preceded by same-named resource with scalar ref', () => {
const result = extractPackageFile(
codeBlock`
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref: "not-a-map"
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: v1.8.2
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: \{\{newValue\}\}\n\s*digest: \{\{newDigest\}\}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: v1\.8\.2\n\s*digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc/,
),
},
],
});
});
it('extracts OCIRepository with tag and digest when preceded by same-named resource with scalar spec', () => {
const result = extractPackageFile(
codeBlock`
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec: "not-a-map"
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: v1.8.2
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: \{\{newValue\}\}\n\s*digest: \{\{newDigest\}\}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: v1\.8\.2\n\s*digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc/,
),
},
],
});
});
it('extracts OCIRepository with tag-only ref when tag value is a YAML alias without digest pinning', () => {
const result = extractPackageFile(
codeBlock`
x-tag: &mytag v1.8.2
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
tag: *mytag
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: '{{newValue}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: 'v1.8.2',
},
],
});
});
it('extracts OCIRepository with tag and digest when ref contains a non-scalar key', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: kyverno-controller
namespace: flux-system
spec:
url: oci://ghcr.io/kyverno/manifests/kyverno
ref:
? [seq-key]
: ignored
tag: v1.8.2
digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate: expect.stringMatching(
/tag: \{\{newValue\}\}\n\s*digest: \{\{newDigest\}\}/,
),
currentDigest:
'sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc',
currentValue: 'v1.8.2',
datasource: DockerDatasource.id,
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
replaceString: expect.stringMatching(
/tag: v1\.8\.2\n\s*digest: sha256:761c3189c482d0f1f0ad3735ca05c4c398cae201d2169f6645280c7b7b2ce6fc/,
),
},
],
});
});
it('extracts Kustomization', () => {
const result = extractPackageFile(
codeBlock`
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: podinfo
namespace: flux-system
spec:
images:
- name: podinfo
newName: my-registry/podinfo
newTag: v1
- name: podinfo
newTag: 1.8.0
- name: podinfo
newName: my-podinfo
- name: podinfo
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
`,
'test.yaml',
);
expect(result).toEqual({
deps: [
{
autoReplaceStringTemplate:
'{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1',
datasource: 'docker',
depName: 'my-registry/podinfo',
packageName: 'my-registry/podinfo',
replaceString: 'v1',
},
{
autoReplaceStringTemplate:
'{{newValue}}{{#if newDigest}}@{{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: '1.8.0',
datasource: 'docker',
depName: 'podinfo',
packageName: 'podinfo',
replaceString: '1.8.0',
},
{
currentDigest: undefined,
currentValue: undefined,
datasource: 'docker',
depName: 'my-podinfo',
packageName: 'my-podinfo',
replaceString: 'my-podinfo',
},
{
currentDigest:
'sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3',
currentValue: undefined,
datasource: 'docker',
depName: 'podinfo',
packageName: 'podinfo',
replaceString:
'sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3',
},
],
});
});
it('ignores resources of an unknown kind', () => {
const result = extractPackageFile(
codeBlock`
kind: SomethingElse
apiVersion: helm.toolkit.fluxcd.io/v2beta1
`,
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores resources without a kind', () => {
const result = extractPackageFile(
'apiVersion: helm.toolkit.fluxcd.io/v2beta1',
'test.yaml',
);
expect(result).toBeNull();
});
it('ignores bad manifests', () => {
const result = extractPackageFile('"bad YAML', 'test.yaml');
expect(result).toBeNull();
});
it('ignores null resources', () => {
const result = extractPackageFile('null', 'test.yaml');
expect(result).toBeNull();
});
});
describe('extractAllPackageFiles()', () => {
it('extracts multiple files', async () => {
const result = await extractAllPackageFiles(config, [
'lib/modules/manager/flux/__fixtures__/helmRelease.yaml',
'lib/modules/manager/flux/__fixtures__/helmSource.yaml',
'lib/modules/manager/flux/__fixtures__/gitSource.yaml',
'lib/modules/manager/flux/__fixtures__/ociSource.yaml',
'lib/modules/manager/flux/__fixtures__/flux-system/gotk-components.yaml',
]);
expect(result).toEqual([
{
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://bitnami-labs.github.io/sealed-secrets'],
},
],
packageFile: 'lib/modules/manager/flux/__fixtures__/helmRelease.yaml',
},
{
deps: [
{
currentValue: 'v11.35.4',
datasource: GithubTagsDatasource.id,
depName: 'renovate-repo',
packageName: 'renovatebot/renovate',
sourceUrl: 'https://github.com/renovatebot/renovate',
},
],
packageFile: 'lib/modules/manager/flux/__fixtures__/gitSource.yaml',
},
{
deps: [
{
autoReplaceStringTemplate:
'tag: {{newValue}}{{#if newDigest}}\n digest: {{newDigest}}{{/if}}',
currentDigest: undefined,
currentValue: 'v1.8.2',
depName: 'ghcr.io/kyverno/manifests/kyverno',
packageName: 'ghcr.io/kyverno/manifests/kyverno',
datasource: DockerDatasource.id,
replaceString: 'tag: v1.8.2',
},
],
packageFile: 'lib/modules/manager/flux/__fixtures__/ociSource.yaml',
},
{
deps: [
{
currentValue: 'v0.24.1',
datasource: 'github-releases',
depName: 'fluxcd/flux2',
managerData: {
components:
'source-controller,kustomize-controller,helm-controller,notification-controller',
},
},
],
packageFile:
'lib/modules/manager/flux/__fixtures__/flux-system/gotk-components.yaml',
},
]);
});
it('should handle HelmRepository with type OCI', async () => {
const result = await extractAllPackageFiles(
{
...config,
registryAliases: { 'ghcr.io': 'ghcr.proxy.test/some/path' },
},
[
'lib/modules/manager/flux/__fixtures__/helmOCISource.yaml',
'lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml',
],
);
expect(result).toEqual([
{
deps: [
{
currentValue: '0.4.0',
datasource: DockerDatasource.id,
depName: 'actions-runner-controller-charts/gha-runner-scale-set',
packageName:
'ghcr.proxy.test/some/path/actions/actions-runner-controller-charts/gha-runner-scale-set',
pinDigests: false,
},
],
packageFile:
'lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml',
},
]);
});
it('should handle HelmRepository w/o type oci and url starts with oci', async () => {
const result = await extractAllPackageFiles(config, [
'lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml',
'lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml',
]);
expect(result).toEqual([
{
deps: [
{
currentValue: '2.6.0',
datasource: DockerDatasource.id,
depName: 'kyverno',
packageName: 'ghcr.io/kyverno/charts/kyverno',
pinDigests: false,
},
],
packageFile:
'lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml',
},
]);
});
it('ignores files that do not exist', async () => {
const result = await extractAllPackageFiles(config, [
'lib/modules/manager/flux/__fixtures__/bogus.yaml',
]);
expect(result).toBeNull();
});
it('ignores system manifest files without valid Flux version header', async () => {
const result = await extractAllPackageFiles(config, [
'lib/modules/manager/flux/__fixtures__/flux-system-invalid/gotk-components.yaml',
]);
expect(result).toBeNull();
});
it('should pick correct package file when using HelmRepository with chartRef', async () => {
const result = await extractAllPackageFiles(config, [
'lib/modules/manager/flux/__fixtures__/helmChartRefRelease.yaml',
'lib/modules/manager/flux/__fixtures__/helmChart.yaml',
'lib/modules/manager/flux/__fixtures__/helmSource.yaml',
]);
expect(result).toEqual([
{
deps: [
{
currentValue: '2.0.2',
datasource: HelmDatasource.id,
depName: 'sealed-secrets',
registryUrls: ['https://bitnami-labs.github.io/sealed-secrets'],
},
],
packageFile: 'lib/modules/manager/flux/__fixtures__/helmChart.yaml',
},
]);
});
});
});