diff --git a/lib/modules/manager/vendir/__fixtures__/invalid-vendir.yaml b/lib/modules/manager/vendir/__fixtures__/invalid-vendir.yaml new file mode 100644 index 00000000000000..534ff2789703ec --- /dev/null +++ b/lib/modules/manager/vendir/__fixtures__/invalid-vendir.yaml @@ -0,0 +1,12 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: vendor + contents: + - path: github.com/cloudfoundry/cf-k8s-networking + test: + # http or ssh urls are supported (required) + url: https://github.com/cloudfoundry/cf-k8s-networking + # branch, tag, commit; origin is the name of the remote (required) + # optional if refSelection is specified (available in v0.11.0+) + ref: origin/master diff --git a/lib/modules/manager/vendir/__fixtures__/valid-contents.yaml b/lib/modules/manager/vendir/__fixtures__/valid-contents.yaml index 04334c59af9d41..9492aebf173199 100644 --- a/lib/modules/manager/vendir/__fixtures__/valid-contents.yaml +++ b/lib/modules/manager/vendir/__fixtures__/valid-contents.yaml @@ -31,3 +31,8 @@ directories: version: "7.10.1" repository: url: oci://test + # Normal Git Repo + - path: custom-repo-custom-version + git: + url: https://github.com/test/test + ref: "7.10.1" diff --git a/lib/modules/manager/vendir/__fixtures__/valid-vendir.yaml b/lib/modules/manager/vendir/__fixtures__/valid-vendir.yaml new file mode 100644 index 00000000000000..3635b4f6873742 --- /dev/null +++ b/lib/modules/manager/vendir/__fixtures__/valid-vendir.yaml @@ -0,0 +1,38 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: vendor + contents: + # Normal Helm Chart + - path: custom-repo-custom-version + helmChart: + name: contour + version: "7.10.1" + repository: + url: https://charts.bitnami.com/bitnami + # Normal Helm Chart 2 for handling lists + - path: thing + helmChart: + name: test + version: "7.10.1" + repository: + url: https://charts.bitnami.com/bitnami + # Normal Git Repo + - path: custom-repo-custom-version + git: + url: https://github.com/test/test + ref: "7.10.1" + # OCI Helm Chart + - path: custom-repo-custom-version + helmChart: + name: contour + version: "7.10.1" + repository: + url: oci://charts.bitnami.com/bitnami + # Aliased OCI Helm Chart + - path: custom-repo-custom-version + helmChart: + name: oci + version: "7.10.1" + repository: + url: oci://test diff --git a/lib/modules/manager/vendir/artifacts.spec.ts b/lib/modules/manager/vendir/artifacts.spec.ts index 32d7ce8efdc23b..8726fe3a31c546 100644 --- a/lib/modules/manager/vendir/artifacts.spec.ts +++ b/lib/modules/manager/vendir/artifacts.spec.ts @@ -462,7 +462,6 @@ describe('modules/manager/vendir/artifacts', () => { fs.readLocalFile.mockResolvedValueOnce(vendirLockFile1); fs.getSiblingFileName.mockReturnValueOnce('vendir.lock.yml'); fs.readLocalFile.mockResolvedValueOnce(vendirLockFile2); - fs.readLocalFile.mockResolvedValueOnce('0.35.0'); const execSnapshots = mockExecAll(); fs.privateCacheDir.mockReturnValue( '/tmp/renovate/cache/__renovate-private-cache', diff --git a/lib/modules/manager/vendir/extract.spec.ts b/lib/modules/manager/vendir/extract.spec.ts index e6e3c36b2bf1c0..66fd02e686ad05 100644 --- a/lib/modules/manager/vendir/extract.spec.ts +++ b/lib/modules/manager/vendir/extract.spec.ts @@ -72,6 +72,12 @@ describe('modules/manager/vendir/extract', () => { packageName: 'quay.example.com/organization/aliased-oci-chart', pinDigests: false, }, + { + currentValue: '7.10.1', + depName: 'https://github.com/test/test', + packageName: 'https://github.com/test/test', + datasource: 'git-refs', + }, ], }); }); diff --git a/lib/modules/manager/vendir/extract.ts b/lib/modules/manager/vendir/extract.ts index 94049a52ae628b..34b1387dab0aba 100644 --- a/lib/modules/manager/vendir/extract.ts +++ b/lib/modules/manager/vendir/extract.ts @@ -1,5 +1,7 @@ import { logger } from '../../../logger'; +import { getHttpUrl } from '../../../util/git/url'; import { parseSingleYaml } from '../../../util/yaml'; +import { GitRefsDatasource } from '../../datasource/git-refs'; import { HelmDatasource } from '../../datasource/helm'; import { getDep } from '../dockerfile/extract'; import { isOCIRegistry } from '../helmv3/utils'; @@ -8,7 +10,12 @@ import type { PackageDependency, PackageFileContent, } from '../types'; -import { HelmChartDefinition, Vendir, VendirDefinition } from './schema'; +import { + GitRefDefinition, + HelmChartDefinition, + Vendir, + VendirDefinition, +} from './schema'; // TODO: Add support for other vendir types (like git tags, github releases, etc.) // Recommend looking at the kustomize manager for more information on support. @@ -27,6 +34,7 @@ export function extractHelmChart( ...dep, depName: helmChart.name, packageName: dep.depName, + depType: 'HelmChart', // https://github.com/helm/helm/issues/10312 // https://github.com/helm/helm/issues/10678 pinDigests: false, @@ -35,11 +43,26 @@ export function extractHelmChart( return { depName: helmChart.name, currentValue: helmChart.version, + depType: 'HelmChart', registryUrls: [helmChart.repository.url], datasource: HelmDatasource.id, }; } +export function extractGitSource( + gitSource: GitRefDefinition, +): PackageDependency | null { + const httpUrl = getHttpUrl(gitSource.url); + return { + depName: httpUrl, + packageName: httpUrl, + depType: 'GitSource', + currentValue: gitSource.ref, + registryUrls: [httpUrl], + datasource: GitRefsDatasource.id, + }; +} + export function parseVendir( content: string, packageFile?: string, @@ -71,12 +94,16 @@ export function extractPackageFile( // grab the helm charts const contents = pkg.directories.flatMap((directory) => directory.contents); for (const content of contents) { - const dep = extractHelmChart(content.helmChart, config.registryAliases); - if (dep) { - deps.push({ - ...dep, - depType: 'HelmChart', - }); + if ('helmChart' in content && content.helmChart) { + const dep = extractHelmChart(content.helmChart, config.registryAliases); + if (dep) { + deps.push(dep); + } + } else if ('git' in content && content.git) { + const dep = extractGitSource(content.git); + if (dep) { + deps.push(dep); + } } } diff --git a/lib/modules/manager/vendir/readme.md b/lib/modules/manager/vendir/readme.md index 3c7eaf0f97e591..a9861052c993ce 100644 --- a/lib/modules/manager/vendir/readme.md +++ b/lib/modules/manager/vendir/readme.md @@ -1,8 +1,10 @@ -Renovate supports updating Helm Chart references in vendir.yml via the [vendir](https://carvel.dev/vendir/) tool. Renovate requires the presence of a [vendir lock file](https://carvel.dev/vendir/docs/v0.40.x/vendir-lock-spec/) which is generated by vendir and should be stored in source code. +Renovate supports updating Helm Chart references and git references in vendir.yml via the [vendir](https://carvel.dev/vendir/) tool. Renovate requires the presence of a [vendir lock file](https://carvel.dev/vendir/docs/v0.40.x/vendir-lock-spec/) which is generated by vendir and should be stored in source code. + +### Helm Charts It supports both https and oci helm chart repositories. -```yaml title="Example vendir.yml" +```yaml title="Example helm chart vendir.yml" apiVersion: vendir.k14s.io/v1alpha1 kind: Config @@ -32,3 +34,27 @@ directories: #### OCI Aliases for OCI registries are supported via the dockerfile/docker manager + +### Git + +Renovates supporting explicit refs in for git references in vendir.yml + +```yaml title="Example git vendir.yml" +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config + +# one or more directories to manage with vendir +directories: + - path: config/_ytt_lib + contents: + path: github.com/cloudfoundry/cf-k8s-networking + git: + # http or ssh urls are supported (required) + url: https://github.com/cloudfoundry/cf-k8s-networking + # branch, tag, commit; origin is the name of the remote (required) + # optional if refSelection is specified (available in v0.11.0+) + ref: origin/master + # depth of commits to fetch; 0 (default) means everything (optional; v0.29.0+) + depth: 1 + ... +``` diff --git a/lib/modules/manager/vendir/schema.ts b/lib/modules/manager/vendir/schema.ts index 8e761a450a01e7..03418dc0eac191 100644 --- a/lib/modules/manager/vendir/schema.ts +++ b/lib/modules/manager/vendir/schema.ts @@ -6,6 +6,12 @@ export const VendirResource = z.object({ kind: z.literal('Config'), }); +export const GitRef = z.object({ + ref: z.string(), + url: z.string().regex(/^(?:ssh|https?):\/\/.+/), + depth: z.number().optional(), +}); + export const HelmChart = z.object({ name: z.string(), version: z.string(), @@ -14,11 +20,18 @@ export const HelmChart = z.object({ }), }); -export const Contents = z.object({ +export const HelmChartContent = z.object({ path: z.string(), helmChart: HelmChart, }); +export const GitRefContent = z.object({ + path: z.string(), + git: GitRef, +}); + +export const Contents = z.union([HelmChartContent, GitRefContent]); + export const Vendir = VendirResource.extend({ directories: z.array( z.object({ @@ -30,3 +43,4 @@ export const Vendir = VendirResource.extend({ export type VendirDefinition = z.infer; export type HelmChartDefinition = z.infer; +export type GitRefDefinition = z.infer;