From d909c31b5e7cba0fb11bf07a3cd28e78309409bd Mon Sep 17 00:00:00 2001
From: Stefan Prodan 
Date: Fri, 10 May 2024 16:23:02 +0300
Subject: [PATCH] Fix: Allow upgrading from v2beta1 to v2 (GA) Add
 `.spec.chartRef` placeholder to v2beta1 to allow upgrading to v2 GA.
Signed-off-by: Stefan Prodan 
---
 api/v2/helmrelease_types.go                   | 16 +++----
 api/v2beta1/helmrelease_types.go              | 10 ++++-
 api/v2beta1/zz_generated.deepcopy.go          | 11 ++++-
 api/v2beta2/helmrelease_types.go              |  3 ++
 .../helm.toolkit.fluxcd.io_helmreleases.yaml  | 45 +++++++++++++++++--
 docs/api/v2/helm.md                           | 16 +++----
 6 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/api/v2/helmrelease_types.go b/api/v2/helmrelease_types.go
index 317db89..800470b 100644
--- a/api/v2/helmrelease_types.go
+++ b/api/v2/helmrelease_types.go
@@ -66,7 +66,7 @@ type PostRenderer struct {
 // HelmReleaseSpec defines the desired state of a Helm release.
 // +kubebuilder:validation:XValidation:rule="(has(self.chart) && !has(self.chartRef)) || (!has(self.chart) && has(self.chartRef))", message="either chart or chartRef must be set"
 type HelmReleaseSpec struct {
-	// Chart defines the template of the v1beta2.HelmChart that should be created
+	// Chart defines the template of the v1.HelmChart that should be created
 	// for this HelmRelease.
 	// +optional
 	Chart *HelmChartTemplate `json:"chart,omitempty"`
@@ -287,20 +287,20 @@ func (d DriftDetection) MustDetectChanges() bool {
 }
 
 // HelmChartTemplate defines the template from which the controller will
-// generate a v1beta2.HelmChart object in the same namespace as the referenced
+// generate a v1.HelmChart object in the same namespace as the referenced
 // v1.Source.
 type HelmChartTemplate struct {
 	// ObjectMeta holds the template for metadata like labels and annotations.
 	// +optional
 	ObjectMeta *HelmChartTemplateObjectMeta `json:"metadata,omitempty"`
 
-	// Spec holds the template for the v1beta2.HelmChartSpec for this HelmRelease.
+	// Spec holds the template for the v1.HelmChartSpec for this HelmRelease.
 	// +required
 	Spec HelmChartTemplateSpec `json:"spec"`
 }
 
 // HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
-// v1beta2.HelmChart.
+// v1.HelmChart.
 type HelmChartTemplateObjectMeta struct {
 	// Map of string keys and values that can be used to organize and categorize
 	// (scope and select) objects.
@@ -317,7 +317,7 @@ type HelmChartTemplateObjectMeta struct {
 }
 
 // HelmChartTemplateSpec defines the template from which the controller will
-// generate a v1beta2.HelmChartSpec object.
+// generate a v1.HelmChartSpec object.
 type HelmChartTemplateSpec struct {
 	// The name or path the Helm chart is available at in the SourceRef.
 	// +kubebuilder:validation:MinLength=1
@@ -325,7 +325,7 @@ type HelmChartTemplateSpec struct {
 	// +required
 	Chart string `json:"chart"`
 
-	// Version semver expression, ignored for charts from v1beta2.GitRepository and
+	// Version semver expression, ignored for charts from v1.GitRepository and
 	// v1beta2.Bucket sources. Defaults to latest when omitted.
 	// +kubebuilder:default:=*
 	// +optional
@@ -372,7 +372,7 @@ type HelmChartTemplateSpec struct {
 	Verify *HelmChartTemplateVerification `json:"verify,omitempty"`
 }
 
-// GetInterval returns the configured interval for the v1beta2.HelmChart,
+// GetInterval returns the configured interval for the v1.HelmChart,
 // or the given default.
 func (in HelmChartTemplate) GetInterval(defaultInterval metav1.Duration) metav1.Duration {
 	if in.Spec.Interval == nil {
@@ -382,7 +382,7 @@ func (in HelmChartTemplate) GetInterval(defaultInterval metav1.Duration) metav1.
 }
 
 // GetNamespace returns the namespace targeted namespace for the
-// v1beta2.HelmChart, or the given default.
+// v1.HelmChart, or the given default.
 func (in HelmChartTemplate) GetNamespace(defaultNamespace string) string {
 	if in.Spec.SourceRef.Namespace == "" {
 		return defaultNamespace
diff --git a/api/v2beta1/helmrelease_types.go b/api/v2beta1/helmrelease_types.go
index 0557cdf..3c200da 100644
--- a/api/v2beta1/helmrelease_types.go
+++ b/api/v2beta1/helmrelease_types.go
@@ -70,7 +70,15 @@ type HelmReleaseSpec struct {
 	// Chart defines the template of the v1beta2.HelmChart that should be created
 	// for this HelmRelease.
 	// +required
-	Chart HelmChartTemplate `json:"chart"`
+	Chart *HelmChartTemplate `json:"chart,omitempty"`
+
+	// ChartRef holds a reference to a source controller resource containing the
+	// Helm chart artifact.
+	//
+	// Note: this field is provisional to the v2 API, and not actively used
+	// by v2beta1 HelmReleases.
+	// +optional
+	ChartRef *v2.CrossNamespaceSourceReference `json:"chartRef,omitempty"`
 
 	// Interval at which to reconcile the Helm release.
 	// This interval is approximate and may be subject to jitter to ensure
diff --git a/api/v2beta1/zz_generated.deepcopy.go b/api/v2beta1/zz_generated.deepcopy.go
index f985bf8..35fdf31 100644
--- a/api/v2beta1/zz_generated.deepcopy.go
+++ b/api/v2beta1/zz_generated.deepcopy.go
@@ -208,7 +208,16 @@ func (in *HelmReleaseList) DeepCopyObject() runtime.Object {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *HelmReleaseSpec) DeepCopyInto(out *HelmReleaseSpec) {
 	*out = *in
-	in.Chart.DeepCopyInto(&out.Chart)
+	if in.Chart != nil {
+		in, out := &in.Chart, &out.Chart
+		*out = new(HelmChartTemplate)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ChartRef != nil {
+		in, out := &in.ChartRef, &out.ChartRef
+		*out = new(v2.CrossNamespaceSourceReference)
+		**out = **in
+	}
 	out.Interval = in.Interval
 	if in.KubeConfig != nil {
 		in, out := &in.KubeConfig, &out.KubeConfig
diff --git a/api/v2beta2/helmrelease_types.go b/api/v2beta2/helmrelease_types.go
index cea04dc..89b9fef 100644
--- a/api/v2beta2/helmrelease_types.go
+++ b/api/v2beta2/helmrelease_types.go
@@ -85,6 +85,9 @@ type HelmReleaseSpec struct {
 
 	// ChartRef holds a reference to a source controller resource containing the
 	// Helm chart artifact.
+	//
+	// Note: this field is provisional to the v2 API, and not actively used
+	// by v2beta2 HelmReleases.
 	// +optional
 	ChartRef *CrossNamespaceSourceReference `json:"chartRef,omitempty"`
 
diff --git a/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml b/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml
index 7be94e2..e6193ca 100644
--- a/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml
+++ b/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml
@@ -53,7 +53,7 @@ spec:
             properties:
               chart:
                 description: |-
-                  Chart defines the template of the v1beta2.HelmChart that should be created
+                  Chart defines the template of the v1.HelmChart that should be created
                   for this HelmRelease.
                 properties:
                   metadata:
@@ -79,7 +79,7 @@ spec:
                         type: object
                     type: object
                   spec:
-                    description: Spec holds the template for the v1beta2.HelmChartSpec
+                    description: Spec holds the template for the v1.HelmChartSpec
                       for this HelmRelease.
                     properties:
                       chart:
@@ -179,7 +179,7 @@ spec:
                       version:
                         default: '*'
                         description: |-
-                          Version semver expression, ignored for charts from v1beta2.GitRepository and
+                          Version semver expression, ignored for charts from v1.GitRepository and
                           v1beta2.Bucket sources. Defaults to latest when omitted.
                         type: string
                     required:
@@ -1358,6 +1358,40 @@ spec:
                 required:
                 - spec
                 type: object
+              chartRef:
+                description: |-
+                  ChartRef holds a reference to a source controller resource containing the
+                  Helm chart artifact.
+
+
+                  Note: this field is provisional to the v2 API, and not actively used
+                  by v2beta1 HelmReleases.
+                properties:
+                  apiVersion:
+                    description: APIVersion of the referent.
+                    type: string
+                  kind:
+                    description: Kind of the referent.
+                    enum:
+                    - OCIRepository
+                    - HelmChart
+                    type: string
+                  name:
+                    description: Name of the referent.
+                    maxLength: 253
+                    minLength: 1
+                    type: string
+                  namespace:
+                    description: |-
+                      Namespace of the referent, defaults to the namespace of the Kubernetes
+                      resource object that contains the reference.
+                    maxLength: 63
+                    minLength: 1
+                    type: string
+                required:
+                - kind
+                - name
+                type: object
               dependsOn:
                 description: |-
                   DependsOn may contain a meta.NamespacedObjectReference slice with
@@ -2121,7 +2155,6 @@ spec:
                   type: object
                 type: array
             required:
-            - chart
             - interval
             type: object
           status:
@@ -2611,6 +2644,10 @@ spec:
                 description: |-
                   ChartRef holds a reference to a source controller resource containing the
                   Helm chart artifact.
+
+
+                  Note: this field is provisional to the v2 API, and not actively used
+                  by v2beta2 HelmReleases.
                 properties:
                   apiVersion:
                     description: APIVersion of the referent.
diff --git a/docs/api/v2/helm.md b/docs/api/v2/helm.md
index 8f928a6..6d0504e 100644
--- a/docs/api/v2/helm.md
+++ b/docs/api/v2/helm.md
@@ -79,7 +79,7 @@ HelmChartTemplate
 
 | 
 (Optional)
- Chart defines the template of the v1beta2.HelmChart that should be created
+ Chart defines the template of the v1.HelmChart that should be created
 for this HelmRelease. 
  | 
 
@@ -668,7 +668,7 @@ bool
 HelmReleaseSpec)
 
 HelmChartTemplate defines the template from which the controller will
-generate a v1beta2.HelmChart object in the same namespace as the referenced
+generate a v1.HelmChart object in the same namespace as the referenced
 v1.Source.