From 5e2b2ea76ae9f169963bdb701d22e7a954b94e3f Mon Sep 17 00:00:00 2001 From: Lars Francke Date: Mon, 3 Aug 2026 23:50:01 +0200 Subject: [PATCH 1/2] feat: Generate the Artifact Hub CRD annotation from extra/crds.yaml This is derived from extra/crds.yaml and ends up in Chart.yaml. --- template/Makefile.j2 | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/template/Makefile.j2 b/template/Makefile.j2 index 73ee6a25..9983449c 100644 --- a/template/Makefile.j2 +++ b/template/Makefile.j2 @@ -28,7 +28,7 @@ docker-build: docker build --force-rm --build-arg VERSION=${VERSION} -t "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}" -f docker/Dockerfile . ## Chart related targets -compile-chart: version crds +compile-chart: version crds crd-annotation chart-clean: rm -rf "deploy/helm/${OPERATOR_NAME}/crds" @@ -43,6 +43,29 @@ crds: mkdir -p extra cargo run --bin stackable-"${OPERATOR_NAME}" -- crd > extra/crds.yaml +# This adds CRD metadata for artifacthub.io (AH) to Chart.yaml. +# We don't ship CRDs in our Helm charts (anymore), so we need these annotations to provide details. +# We only list the storage version as we're unsure if AH supports more than one (docs unclear). +# The yq thing here selects the storage version and then maps various metadata bits to the form AH requires. +# +# It appends a single annotation whose value is a list, one entry per CRD. +# Example: For the secret-operator that comes out as: +# +# artifacthub.io/crds: |- +# - kind: SecretClass +# version: v1alpha2 +# name: secretclasses.secrets.stackable.tech +# displayName: SecretClass +# description: A SecretClass is a cluster-global Kubernetes resource that defines ... +# - kind: TrustStore +# version: v1alpha1 +# name: truststores.secrets.stackable.tech +# displayName: TrustStore +# description: A TrustStore requests information about how to validate secrets ... +crd-annotation: crds + @CRDS="$$(yq ea -o=yaml '[.] | map(.spec.versions |= map(select(.storage == true))) | map({"kind": .spec.names.kind, "version": .spec.versions[0].name, "name": .metadata.name, "displayName": .spec.names.kind, "description": (.spec.versions[0].schema.openAPIV3Schema.description // "")})' extra/crds.yaml)" \ + yq -i '.annotations["artifacthub.io/crds"] = strenv(CRDS) | .annotations["artifacthub.io/crds"] style="literal"' "deploy/helm/${OPERATOR_NAME}/Chart.yaml" + chart-lint: compile-chart docker run -it -v $(shell pwd):/build/helm-charts -w /build/helm-charts quay.io/helmpack/chart-testing:v3.5.0 ct lint --config deploy/helm/ct.yaml From 85a78447a890ac2babaca386b7f1ced45965cecd Mon Sep 17 00:00:00 2001 From: Lars Francke Date: Tue, 4 Aug 2026 09:46:09 +0200 Subject: [PATCH 2/2] chore: Split the CRD annotation yq expressions into named variables Addresses review feedback: the recipe was one long line, so it was not obvious that it reads extra/crds.yaml and writes Chart.yaml. CRD_ANNOTATION_READ and CRD_ANNOTATION_WRITE are now separate, each with its own comment. Still a single shell command: the env-var prefix is needed because the value is multi-line and reaches yq via strenv. --- template/Makefile.j2 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/template/Makefile.j2 b/template/Makefile.j2 index 9983449c..4b96010c 100644 --- a/template/Makefile.j2 +++ b/template/Makefile.j2 @@ -46,7 +46,6 @@ crds: # This adds CRD metadata for artifacthub.io (AH) to Chart.yaml. # We don't ship CRDs in our Helm charts (anymore), so we need these annotations to provide details. # We only list the storage version as we're unsure if AH supports more than one (docs unclear). -# The yq thing here selects the storage version and then maps various metadata bits to the form AH requires. # # It appends a single annotation whose value is a list, one entry per CRD. # Example: For the secret-operator that comes out as: @@ -62,9 +61,21 @@ crds: # name: truststores.secrets.stackable.tech # displayName: TrustStore # description: A TrustStore requests information about how to validate secrets ... +# +# The two yq expressions are split out below so it's easier to review and see what's going on. + +# READ step: turn every CRD document in extra/crds.yaml into one AH card entry. +# `[.] | map(...)` collects the documents into a list and maps each one to the format (see above) required by AH. +# The result of this is a list of these entries. +CRD_ANNOTATION_READ := [.] | map(.spec.versions |= map(select(.storage == true))) | map({"kind": .spec.names.kind, "version": .spec.versions[0].name, "name": .metadata.name, "displayName": .spec.names.kind, "description": (.spec.versions[0].schema.openAPIV3Schema.description // "")}) + +# WRITE step: Write that list to Chart.yaml as an annotation value. +# Literal block scalar so it stays readable in Chart.yaml. +CRD_ANNOTATION_WRITE := .annotations["artifacthub.io/crds"] = strenv(CRDS) | .annotations["artifacthub.io/crds"] style="literal" + crd-annotation: crds - @CRDS="$$(yq ea -o=yaml '[.] | map(.spec.versions |= map(select(.storage == true))) | map({"kind": .spec.names.kind, "version": .spec.versions[0].name, "name": .metadata.name, "displayName": .spec.names.kind, "description": (.spec.versions[0].schema.openAPIV3Schema.description // "")})' extra/crds.yaml)" \ - yq -i '.annotations["artifacthub.io/crds"] = strenv(CRDS) | .annotations["artifacthub.io/crds"] style="literal"' "deploy/helm/${OPERATOR_NAME}/Chart.yaml" + @CRDS="$$(yq ea -o=yaml '$(CRD_ANNOTATION_READ)' extra/crds.yaml)" \ + yq -i '$(CRD_ANNOTATION_WRITE)' "deploy/helm/${OPERATOR_NAME}/Chart.yaml" chart-lint: compile-chart docker run -it -v $(shell pwd):/build/helm-charts -w /build/helm-charts quay.io/helmpack/chart-testing:v3.5.0 ct lint --config deploy/helm/ct.yaml