mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 07:50:47 +00:00
be13c9f5f7
* 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.
380 lines
12 KiB
TypeScript
380 lines
12 KiB
TypeScript
import { codeBlock } from 'common-tags';
|
|
import { Fixtures } from '~test/fixtures.ts';
|
|
import { partial } from '~test/util.ts';
|
|
import type { ExtractConfig } from '../types.ts';
|
|
import { extractPackageFile } from './index.ts';
|
|
|
|
const validFleetYaml = Fixtures.get('valid_fleet.yaml');
|
|
const inValidFleetYaml = Fixtures.get('invalid_fleet.yaml');
|
|
|
|
const validGitRepoYaml = Fixtures.get('valid_gitrepo.yaml');
|
|
const invalidGitRepoYaml = Fixtures.get('invalid_gitrepo.yaml');
|
|
|
|
const configMapYaml = Fixtures.get('configmap.yaml', '../kubernetes');
|
|
|
|
describe('modules/manager/fleet/extract', () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('extractPackageFile()', () => {
|
|
it('should return null if empty content', () => {
|
|
const result = extractPackageFile('', 'fleet.yaml', {});
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('should return null if a unknown manifest is supplied', () => {
|
|
const result = extractPackageFile(configMapYaml, 'fleet.yaml', {});
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
describe('fleet.yaml', () => {
|
|
it('should return null if content is a malformed YAML', () => {
|
|
const result = extractPackageFile(
|
|
`apiVersion: v1
|
|
kind: Fleet
|
|
< `,
|
|
'fleet.yaml',
|
|
{},
|
|
);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('should parse valid configuration', () => {
|
|
const result = extractPackageFile(validFleetYaml, 'fleet.yaml', {});
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: '3.17.7',
|
|
datasource: 'helm',
|
|
depName: 'logging-operator',
|
|
registryUrls: ['https://kubernetes-charts.banzaicloud.com'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: '25.19.1',
|
|
datasource: 'helm',
|
|
depName: 'prometheus',
|
|
registryUrls: [
|
|
'https://prometheus-community.github.io/helm-charts',
|
|
],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: '7.1.2',
|
|
datasource: 'docker',
|
|
depName: 'registry-1.docker.io/bitnamicharts/external-dns',
|
|
packageName: 'registry-1.docker.io/bitnamicharts/external-dns',
|
|
depType: 'fleet',
|
|
pinDigests: false,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should support registryAlias configuration', () => {
|
|
const result = extractPackageFile(
|
|
codeBlock`
|
|
defaultNamespace: cert-manager
|
|
helm:
|
|
chart: cert-manager
|
|
repo: https://registry.com/jetstack
|
|
releaseName: cert-manager
|
|
version: v1.8.0
|
|
---
|
|
defaultNamespace: external-dns
|
|
helm:
|
|
chart: oci://registry.com/docker-io/bitnamicharts/external-dns
|
|
version: 7.1.2
|
|
`,
|
|
'fleet.yaml',
|
|
partial<ExtractConfig>({
|
|
registryAliases: {
|
|
'https://registry.com/jetstack': 'https://charts.jetstack.io',
|
|
'registry.com/docker-io': 'registry-1.docker.io',
|
|
},
|
|
}),
|
|
);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: '7.1.2',
|
|
datasource: 'docker',
|
|
depName: 'registry.com/docker-io/bitnamicharts/external-dns',
|
|
packageName: 'registry-1.docker.io/bitnamicharts/external-dns',
|
|
depType: 'fleet',
|
|
pinDigests: false,
|
|
},
|
|
]);
|
|
});
|
|
it('should skip OCI charts without version', () => {
|
|
const result = extractPackageFile(
|
|
codeBlock`
|
|
defaultNamespace: external-dns
|
|
helm:
|
|
chart: oci://registry-1.docker.io/bitnamicharts/external-dns
|
|
`,
|
|
'fleet.yaml',
|
|
{},
|
|
);
|
|
|
|
expect(result?.deps).toEqual([
|
|
{
|
|
datasource: 'docker',
|
|
depName: 'registry-1.docker.io/bitnamicharts/external-dns',
|
|
depType: 'fleet',
|
|
packageName: 'registry-1.docker.io/bitnamicharts/external-dns',
|
|
pinDigests: false,
|
|
skipReason: 'unspecified-version',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should parse valid configuration with target customization', () => {
|
|
const validFleetYamlWithCustom = codeBlock`
|
|
# This should generate two dependencies with different versions
|
|
# one with v1.8.0 and one with v1.9.2
|
|
defaultNamespace: cert-manager
|
|
helm:
|
|
chart: cert-manager
|
|
repo: https://charts.jetstack.io
|
|
releaseName: cert-manager
|
|
version: v1.8.0
|
|
values:
|
|
installCRDs: true
|
|
targetCustomizations:
|
|
- name: rke2
|
|
helm:
|
|
version: "v1.9.2"
|
|
---
|
|
# This should generate two dependencies with different repos
|
|
# one with https://charts.jetstack.io and one with https://charts.example.com
|
|
defaultNamespace: cert-manager
|
|
helm:
|
|
chart: cert-manager
|
|
repo: https://charts.jetstack.io
|
|
releaseName: custom-cert-manager
|
|
version: v1.8.0
|
|
values:
|
|
installCRDs: true
|
|
targetCustomizations:
|
|
- name: cluster1
|
|
helm:
|
|
version: "v1.8.2"
|
|
repo: https://charts.example.com
|
|
|
|
---
|
|
# This should generate one dependency and a skipped dependency, as there is no version
|
|
defaultNamespace: cert-manager
|
|
helm:
|
|
chart: cert-manager
|
|
repo: https://charts.jetstack.io
|
|
releaseName: custom-cert-manager
|
|
version: v1.8.0
|
|
values:
|
|
installCRDs: true
|
|
targetCustomizations:
|
|
- name: cluster1
|
|
values:
|
|
some: customization
|
|
|
|
---
|
|
# This is a valid target customization with no name
|
|
# It should generate one valid dependency, and one skipped dependency, like the one above
|
|
defaultNamespace: cert-manager
|
|
helm:
|
|
chart: cert-manager
|
|
repo: https://charts.jetstack.io
|
|
releaseName: custom-cert-manager
|
|
version: v1.8.0
|
|
values:
|
|
installCRDs: true
|
|
targetCustomizations:
|
|
- values:
|
|
some: customization
|
|
`;
|
|
const result = extractPackageFile(
|
|
validFleetYamlWithCustom,
|
|
'fleet.yaml',
|
|
{},
|
|
);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: 'v1.9.2',
|
|
datasource: 'helm',
|
|
depName: 'rke2',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: 'v1.8.2',
|
|
datasource: 'helm',
|
|
depName: 'cluster1',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.example.com'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
datasource: 'helm',
|
|
depName: 'cluster1',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
skipReason: 'unspecified-version',
|
|
},
|
|
{
|
|
currentValue: 'v1.8.0',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
datasource: 'helm',
|
|
depName: 'targetCustomization[0]',
|
|
packageName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
skipReason: 'unspecified-version',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should parse parse invalid configurations', () => {
|
|
const result = extractPackageFile(inValidFleetYaml, 'fleet.yaml', {});
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
skipReason: 'unspecified-version',
|
|
datasource: 'helm',
|
|
depName: 'cert-manager',
|
|
registryUrls: ['https://charts.jetstack.io'],
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
datasource: 'helm',
|
|
depName: 'logging-operator',
|
|
skipReason: 'no-repository',
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
datasource: 'helm',
|
|
skipReason: 'missing-depname',
|
|
depType: 'fleet',
|
|
},
|
|
{
|
|
datasource: 'helm',
|
|
depName: './charts/example',
|
|
skipReason: 'local-chart',
|
|
depType: 'fleet',
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('GitRepo', () => {
|
|
it('should return null if content is a malformed YAML', () => {
|
|
const result = extractPackageFile(
|
|
`apiVersion: v1
|
|
kind: GitRepo
|
|
< `,
|
|
'test.yaml',
|
|
{},
|
|
);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('should parse valid configuration', () => {
|
|
const result = extractPackageFile(validGitRepoYaml, 'test.yaml', {});
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
currentValue: 'v0.3.0',
|
|
datasource: 'git-tags',
|
|
depName: 'https://github.com/rancher/fleet-examples',
|
|
depType: 'git_repo',
|
|
sourceUrl: 'https://github.com/rancher/fleet-examples',
|
|
},
|
|
{
|
|
currentValue: '32.89.2',
|
|
datasource: 'git-tags',
|
|
depName: 'https://github.com/renovatebot/renovate',
|
|
depType: 'git_repo',
|
|
sourceUrl: 'https://github.com/renovatebot/renovate',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should parse invalid configuration', () => {
|
|
const result = extractPackageFile(invalidGitRepoYaml, 'test.yaml', {});
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.deps).toMatchObject([
|
|
{
|
|
datasource: 'git-tags',
|
|
depType: 'git_repo',
|
|
skipReason: 'missing-depname',
|
|
},
|
|
{
|
|
datasource: 'git-tags',
|
|
depName: 'https://github.com/rancher/rancher',
|
|
depType: 'git_repo',
|
|
skipReason: 'unspecified-version',
|
|
sourceUrl: 'https://github.com/rancher/rancher',
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
});
|