From c5db2dc718417d905f9adb51c2f9704c82a23dec Mon Sep 17 00:00:00 2001
From: Morre <mmeyer@anaconda.com>
Date: Thu, 19 Jan 2023 18:50:40 +0100
Subject: [PATCH] feat(manager/terraform): support OCI charts in helm_release
 (#19869)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com>
---
 lib/modules/manager/helmv3/utils.spec.ts           | 14 +++++++++++++-
 lib/modules/manager/helmv3/utils.ts                | 11 +++++++++--
 lib/modules/manager/terraform/__fixtures__/helm.tf |  7 +++++++
 lib/modules/manager/terraform/extract.spec.ts      |  8 +++++++-
 .../terraform/extractors/resources/helm-release.ts |  7 +++++++
 lib/modules/manager/terraform/readme.md            |  2 +-
 6 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/lib/modules/manager/helmv3/utils.spec.ts b/lib/modules/manager/helmv3/utils.spec.ts
index 0529768408..a83ce2d38d 100644
--- a/lib/modules/manager/helmv3/utils.spec.ts
+++ b/lib/modules/manager/helmv3/utils.spec.ts
@@ -1,4 +1,4 @@
-import { isAlias, resolveAlias } from './utils';
+import { isAlias, isOCIRegistry, resolveAlias } from './utils';
 
 describe('modules/manager/helmv3/utils', () => {
   describe('.resolveAlias()', () => {
@@ -70,4 +70,16 @@ describe('modules/manager/helmv3/utils', () => {
       expect(repository).toBeFalse();
     });
   });
+
+  describe('.isOCIRegistry()', () => {
+    it('return false if repository is null', () => {
+      const repository = isOCIRegistry(null);
+      expect(repository).toBeFalse();
+    });
+
+    it('return false if repository is undefined', () => {
+      const repository = isOCIRegistry(undefined);
+      expect(repository).toBeFalse();
+    });
+  });
 });
diff --git a/lib/modules/manager/helmv3/utils.ts b/lib/modules/manager/helmv3/utils.ts
index be803f6730..3e29cb0940 100644
--- a/lib/modules/manager/helmv3/utils.ts
+++ b/lib/modules/manager/helmv3/utils.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import upath from 'upath';
 import { logger } from '../../../logger';
 import { DockerDatasource } from '../../datasource/docker';
@@ -82,8 +83,14 @@ export function isAlias(repository: string): boolean {
   return repository.startsWith('@') || repository.startsWith('alias:');
 }
 
-export function isOCIRegistry(repository: Repository): boolean {
-  return repository.repository.startsWith('oci://');
+export function isOCIRegistry(
+  repository: Repository | string | null | undefined
+): boolean {
+  if (is.nullOrUndefined(repository)) {
+    return false;
+  }
+  const repo = is.string(repository) ? repository : repository.repository;
+  return repo.startsWith('oci://');
 }
 
 export function aliasRecordToRepositories(
diff --git a/lib/modules/manager/terraform/__fixtures__/helm.tf b/lib/modules/manager/terraform/__fixtures__/helm.tf
index 32f04accc6..a977c66268 100644
--- a/lib/modules/manager/terraform/__fixtures__/helm.tf
+++ b/lib/modules/manager/terraform/__fixtures__/helm.tf
@@ -38,3 +38,10 @@ resource "helm_release" "invalid_3" {
   chart      = "redis"
   version    = "6.0.1"
 }
+
+## chart in OCI registry
+resource "helm_release" "karpenter" {
+  name  = "karpenter"
+  chart = "oci://public.ecr.aws/karpenter/karpenter"
+  version = "v0.22.1"
+}
diff --git a/lib/modules/manager/terraform/extract.spec.ts b/lib/modules/manager/terraform/extract.spec.ts
index 4c1220fb9b..978645438f 100644
--- a/lib/modules/manager/terraform/extract.spec.ts
+++ b/lib/modules/manager/terraform/extract.spec.ts
@@ -574,7 +574,7 @@ describe('modules/manager/terraform/extract', () => {
 
     it('extract helm releases', async () => {
       const res = await extractPackageFile(helm, 'helm.tf', {});
-      expect(res?.deps).toHaveLength(6);
+      expect(res?.deps).toHaveLength(7);
       expect(res?.deps.filter((dep) => dep.skipReason)).toHaveLength(2);
       expect(res?.deps).toIncludeAllPartialMembers([
         {
@@ -617,6 +617,12 @@ describe('modules/manager/terraform/extract', () => {
           depName: 'redis',
           depType: 'helm_release',
         },
+        {
+          currentValue: 'v0.22.1',
+          datasource: 'docker',
+          depName: 'public.ecr.aws/karpenter/karpenter',
+          depType: 'helm_release',
+        },
       ]);
     });
 
diff --git a/lib/modules/manager/terraform/extractors/resources/helm-release.ts b/lib/modules/manager/terraform/extractors/resources/helm-release.ts
index 75cbb985fc..83d156881e 100644
--- a/lib/modules/manager/terraform/extractors/resources/helm-release.ts
+++ b/lib/modules/manager/terraform/extractors/resources/helm-release.ts
@@ -1,5 +1,7 @@
 import is from '@sindresorhus/is';
+import { DockerDatasource } from '../../../../datasource/docker';
 import { HelmDatasource } from '../../../../datasource/helm';
+import { isOCIRegistry } from '../../../helmv3/utils';
 import type { PackageDependency } from '../../../types';
 import { DependencyExtractor } from '../../base';
 import { checkIfStringIsPath } from '../../util';
@@ -29,9 +31,14 @@ export class HelmReleaseExtractor extends DependencyExtractor {
         }
         if (!helmRelease.chart) {
           dep.skipReason = 'invalid-name';
+        } else if (isOCIRegistry(helmRelease.chart)) {
+          // For oci charts, we remove the oci:// and use the docker datasource
+          dep.depName = helmRelease.chart.replace('oci://', '');
+          dep.datasource = DockerDatasource.id;
         } else if (checkIfStringIsPath(helmRelease.chart)) {
           dep.skipReason = 'local-chart';
         }
+
         dependencies.push(dep);
       }
     }
diff --git a/lib/modules/manager/terraform/readme.md b/lib/modules/manager/terraform/readme.md
index 5faa900edb..e32eb95541 100644
--- a/lib/modules/manager/terraform/readme.md
+++ b/lib/modules/manager/terraform/readme.md
@@ -33,7 +33,7 @@ Renovate can update the `required_version` attribute of the Terraform block.
 
 #### helm_release
 
-Renovate can update the version attribute of `helm_release` resources.
+Renovate can update the version attribute of `helm_release` resources. This applies to both helm chart repositories and [charts published in OCI registries](https://helm.sh/docs/topics/registries/).
 
 | Name             | Public hosting | Private hosting |
 | ---------------- | :------------: | :-------------: |
-- 
GitLab