From 6e84d6370738eac4494fb96c26e5c0fb05ff2801 Mon Sep 17 00:00:00 2001 From: Razvan-Daniel Mihai <84674+razvan@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:12:19 +0200 Subject: [PATCH 1/2] helm: build and publish for multiple repositories --- Makefile | 40 +++++++++++++++++++ deploy/helm/airflow-operator/README.md | 40 +++++++++++++++++++ .../airflow-operator/templates/_helpers.tpl | 7 ++++ .../templates/deployment.yaml | 4 +- .../airflow-operator/values.registry-oci.yaml | 4 ++ .../values.registry-quay.yaml | 4 ++ deploy/helm/airflow-operator/values.yaml | 3 +- 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 deploy/helm/airflow-operator/values.registry-oci.yaml create mode 100644 deploy/helm/airflow-operator/values.registry-quay.yaml diff --git a/Makefile b/Makefile index 32f2bcad..7b4ece89 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ # This script also requires `jq` https://stedolan.github.io/jq/ .PHONY: build publish +.PHONY: chart-package-oci chart-package-quay chart-package-all +.PHONY: chart-publish-oci chart-publish-quay chart-publish-all OPERATOR_NAME := airflow-operator VERSION := $(shell cargo metadata --format-version 1 | jq -r '.packages[] | select(.name=="stackable-${OPERATOR_NAME}") | .version') @@ -15,6 +17,12 @@ VERSION := $(shell cargo metadata --format-version 1 | jq -r '.packages[] | sele OCI_REGISTRY_HOSTNAME := oci.stackable.tech OCI_REGISTRY_PROJECT_IMAGES := sdp +OCI_REGISTRY_PROJECT_CHARTS ?= sdp/charts +QUAY_REGISTRY_PROJECT_CHARTS ?= stackable/charts + +CHART_DIR := deploy/helm/${OPERATOR_NAME} +CHART_PACKAGE_OUTPUT_DIR ?= /tmp + SHELL=/usr/bin/env bash -euo pipefail render-readme: @@ -53,6 +61,38 @@ crds: 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 +chart-package-oci: compile-chart + tmp_dir="$$(mktemp -d)"; \ + trap 'rm -rf "$$tmp_dir"' EXIT; \ + cp -r "${CHART_DIR}" "$$tmp_dir/"; \ + yq ea '. as $$item ireduce ({}; . * $$item )' \ + "$$tmp_dir/${OPERATOR_NAME}/values.yaml" \ + "$$tmp_dir/${OPERATOR_NAME}/values.registry-oci.yaml" \ + > "$$tmp_dir/${OPERATOR_NAME}/values.yaml.new"; \ + mv "$$tmp_dir/${OPERATOR_NAME}/values.yaml.new" "$$tmp_dir/${OPERATOR_NAME}/values.yaml"; \ + helm package "$$tmp_dir/${OPERATOR_NAME}" --destination "${CHART_PACKAGE_OUTPUT_DIR}" + +chart-package-quay: compile-chart + tmp_dir="$$(mktemp -d)"; \ + trap 'rm -rf "$$tmp_dir"' EXIT; \ + cp -r "${CHART_DIR}" "$$tmp_dir/"; \ + yq ea '. as $$item ireduce ({}; . * $$item )' \ + "$$tmp_dir/${OPERATOR_NAME}/values.yaml" \ + "$$tmp_dir/${OPERATOR_NAME}/values.registry-quay.yaml" \ + > "$$tmp_dir/${OPERATOR_NAME}/values.yaml.new"; \ + mv "$$tmp_dir/${OPERATOR_NAME}/values.yaml.new" "$$tmp_dir/${OPERATOR_NAME}/values.yaml"; \ + helm package "$$tmp_dir/${OPERATOR_NAME}" --destination "${CHART_PACKAGE_OUTPUT_DIR}" + +chart-package-all: chart-package-oci chart-package-quay + +chart-publish-oci: chart-package-oci + helm push "${CHART_PACKAGE_OUTPUT_DIR}/${OPERATOR_NAME}-${VERSION}.tgz" "oci://${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_CHARTS}" + +chart-publish-quay: chart-package-quay + helm push "${CHART_PACKAGE_OUTPUT_DIR}/${OPERATOR_NAME}-${VERSION}.tgz" "oci://quay.io/${QUAY_REGISTRY_PROJECT_CHARTS}" + +chart-publish-all: chart-publish-oci chart-publish-quay + clean: chart-clean cargo clean docker rmi --force '${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}' diff --git a/deploy/helm/airflow-operator/README.md b/deploy/helm/airflow-operator/README.md index 9acc52bf..3c58d076 100644 --- a/deploy/helm/airflow-operator/README.md +++ b/deploy/helm/airflow-operator/README.md @@ -17,6 +17,46 @@ make compile-chart helm install airflow-operator deploy/helm/airflow-operator ``` +## Publish The Chart To Multiple Registries + +This chart is structured so the operator image can be sourced from different registries without +duplicating templates. + +- `values.yaml` contains the default image coordinates (`image.registry` and `image.repository`). +- `values.registry-oci.yaml` sets defaults for chart artifacts published to `oci.stackable.tech`. +- `values.registry-quay.yaml` sets defaults for chart artifacts published to `quay.io`. + +Package each artifact with a registry-specific `values.yaml` so users of each chart registry +automatically pull images from the same source registry. + +`helm package` does not accept a values overlay directly, so create a temporary chart copy per +target and merge values before packaging: + +```bash +# Package chart with oci.stackable.tech defaults +tmp_oci="$(mktemp -d)" +cp -r deploy/helm/airflow-operator "${tmp_oci}/" +yq ea '. as $item ireduce ({}; . * $item )' \ + "${tmp_oci}/airflow-operator/values.yaml" \ + "${tmp_oci}/airflow-operator/values.registry-oci.yaml" \ + > "${tmp_oci}/airflow-operator/values.yaml.new" +mv "${tmp_oci}/airflow-operator/values.yaml.new" "${tmp_oci}/airflow-operator/values.yaml" +helm package "${tmp_oci}/airflow-operator" --destination /tmp/charts-oci + +# Package chart with quay.io defaults +tmp_quay="$(mktemp -d)" +cp -r deploy/helm/airflow-operator "${tmp_quay}/" +yq ea '. as $item ireduce ({}; . * $item )' \ + "${tmp_quay}/airflow-operator/values.yaml" \ + "${tmp_quay}/airflow-operator/values.registry-quay.yaml" \ + > "${tmp_quay}/airflow-operator/values.yaml.new" +mv "${tmp_quay}/airflow-operator/values.yaml.new" "${tmp_quay}/airflow-operator/values.yaml" +helm package "${tmp_quay}/airflow-operator" --destination /tmp/charts-quay +``` + +Then push the packaged chart from `/tmp/charts-oci` to `oci.stackable.tech` and the packaged chart +from `/tmp/charts-quay` to `quay.io`. + ## Usage of the CRDs The usage of this operator and its CRDs is described in the [documentation](https://docs.stackable.tech/airflow/index.html) diff --git a/deploy/helm/airflow-operator/templates/_helpers.tpl b/deploy/helm/airflow-operator/templates/_helpers.tpl index 1096ffc6..80f2848b 100644 --- a/deploy/helm/airflow-operator/templates/_helpers.tpl +++ b/deploy/helm/airflow-operator/templates/_helpers.tpl @@ -77,3 +77,10 @@ Labels for Kubernetes objects created by helm test {{- define "operator.testLabels" -}} helm.sh/test: {{ include "operator.chart" . }} {{- end }} + +{{/* +Build the full container image reference. +*/}} +{{- define "operator.image" -}} +{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) -}} +{{- end }} diff --git a/deploy/helm/airflow-operator/templates/deployment.yaml b/deploy/helm/airflow-operator/templates/deployment.yaml index 0f4d902e..f9a84385 100644 --- a/deploy/helm/airflow-operator/templates/deployment.yaml +++ b/deploy/helm/airflow-operator/templates/deployment.yaml @@ -15,7 +15,7 @@ spec: template: metadata: annotations: - internal.stackable.tech/image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + internal.stackable.tech/image: "{{ include "operator.image" . }}" checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} @@ -37,7 +37,7 @@ spec: - name: {{ include "operator.appname" . }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + image: "{{ include "operator.image" . }}" imagePullPolicy: {{ .Values.image.pullPolicy }} resources: {{- toYaml .Values.resources | nindent 12 }} diff --git a/deploy/helm/airflow-operator/values.registry-oci.yaml b/deploy/helm/airflow-operator/values.registry-oci.yaml new file mode 100644 index 00000000..d03570c9 --- /dev/null +++ b/deploy/helm/airflow-operator/values.registry-oci.yaml @@ -0,0 +1,4 @@ +--- +# Values overlay for chart packages published to oci.stackable.tech. +image: + registry: oci.stackable.tech/sdp diff --git a/deploy/helm/airflow-operator/values.registry-quay.yaml b/deploy/helm/airflow-operator/values.registry-quay.yaml new file mode 100644 index 00000000..a7f4792b --- /dev/null +++ b/deploy/helm/airflow-operator/values.registry-quay.yaml @@ -0,0 +1,4 @@ +--- +# Values overlay for chart packages published to quay.io. +image: + registry: quay.io/stackable diff --git a/deploy/helm/airflow-operator/values.yaml b/deploy/helm/airflow-operator/values.yaml index 89b8a10d..06c16456 100644 --- a/deploy/helm/airflow-operator/values.yaml +++ b/deploy/helm/airflow-operator/values.yaml @@ -1,7 +1,8 @@ # Default values for airflow-operator. --- image: - repository: oci.stackable.tech/sdp/airflow-operator + registry: oci.stackable.tech/sdp + repository: airflow-operator pullPolicy: IfNotPresent pullSecrets: [] From 2d17c856b08dd29d8445845e06cc93d1a9f3da13 Mon Sep 17 00:00:00 2001 From: Razvan-Daniel Mihai <84674+razvan@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:30:27 +0200 Subject: [PATCH 2/2] update readme --- deploy/helm/airflow-operator/README.md | 64 +++++++++++++------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/deploy/helm/airflow-operator/README.md b/deploy/helm/airflow-operator/README.md index 3c58d076..5142f585 100644 --- a/deploy/helm/airflow-operator/README.md +++ b/deploy/helm/airflow-operator/README.md @@ -17,45 +17,47 @@ make compile-chart helm install airflow-operator deploy/helm/airflow-operator ``` -## Publish The Chart To Multiple Registries +## Publish The Chart -This chart is structured so the operator image can be sourced from different registries without -duplicating templates. +The Helm chart is published to two different repositories: -- `values.yaml` contains the default image coordinates (`image.registry` and `image.repository`). -- `values.registry-oci.yaml` sets defaults for chart artifacts published to `oci.stackable.tech`. -- `values.registry-quay.yaml` sets defaults for chart artifacts published to `quay.io`. +- oci.stackable.tech +- quay.io -Package each artifact with a registry-specific `values.yaml` so users of each chart registry -automatically pull images from the same source registry. +Each chart version references images from it's corresponding repository. -`helm package` does not accept a values overlay directly, so create a temporary chart copy per -target and merge values before packaging: +Package and publish both variants: ```bash -# Package chart with oci.stackable.tech defaults -tmp_oci="$(mktemp -d)" -cp -r deploy/helm/airflow-operator "${tmp_oci}/" -yq ea '. as $item ireduce ({}; . * $item )' \ - "${tmp_oci}/airflow-operator/values.yaml" \ - "${tmp_oci}/airflow-operator/values.registry-oci.yaml" \ - > "${tmp_oci}/airflow-operator/values.yaml.new" -mv "${tmp_oci}/airflow-operator/values.yaml.new" "${tmp_oci}/airflow-operator/values.yaml" -helm package "${tmp_oci}/airflow-operator" --destination /tmp/charts-oci - -# Package chart with quay.io defaults -tmp_quay="$(mktemp -d)" -cp -r deploy/helm/airflow-operator "${tmp_quay}/" -yq ea '. as $item ireduce ({}; . * $item )' \ - "${tmp_quay}/airflow-operator/values.yaml" \ - "${tmp_quay}/airflow-operator/values.registry-quay.yaml" \ - > "${tmp_quay}/airflow-operator/values.yaml.new" -mv "${tmp_quay}/airflow-operator/values.yaml.new" "${tmp_quay}/airflow-operator/values.yaml" -helm package "${tmp_quay}/airflow-operator" --destination /tmp/charts-quay +make chart-package-all +make chart-publish-all ``` -Then push the packaged chart from `/tmp/charts-oci` to `oci.stackable.tech` and the packaged chart -from `/tmp/charts-quay` to `quay.io`. +Package and publish for oci.stackable.tech: + +```bash +make chart-package-oci +make chart-publish-oci +``` + +Package and publish for quay.io: + +```bash +make chart-package-quay +make chart-publish-quay +``` + +Install from oci.stackable.tech: + +```bash +helm install airflow-operator oci://oci.stackable.tech/sdp/charts/airflow-operator --version 0.0.0-dev +``` + +Install from quay.io: + +```shell +helm install airflow-operator oci://quay.io/stackable/charts/airflow-operator --version 0.0.0-dev +``` ## Usage of the CRDs