This is an automated email from the ASF dual-hosted git repository.
janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-operator.git
The following commit(s) were added to refs/heads/main by this push:
new c7f1476 Add tooling to publish Helm charts as OCI artifacts to GHCR
(#814)
c7f1476 is described below
commit c7f147649312775b19a8feb1987eb7b7430ad5c4
Author: Jan Høydahl <[email protected]>
AuthorDate: Sat Oct 24 02:50:39 2026 +0200
Add tooling to publish Helm charts as OCI artifacts to GHCR (#814)
---
.github/workflows/publish-helm-oci.yaml | 265 ++++++++++++++++++++++++++++++++
hack/release/smoke_test/test_cluster.sh | 30 +++-
hack/release/wizard/releaseWizard.yaml | 76 +++++++++
3 files changed, 364 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/publish-helm-oci.yaml
b/.github/workflows/publish-helm-oci.yaml
new file mode 100644
index 0000000..bbdf72f
--- /dev/null
+++ b/.github/workflows/publish-helm-oci.yaml
@@ -0,0 +1,265 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Publish Helm Charts to OCI Registry
+
+# Publishes already-released, already-voted-on Helm charts from
dist.apache.org (or
+# archive.apache.org, for older releases) to the GitHub Container Registry, as
OCI artifacts.
+#
+# The charts on dist.apache.org remain the canonical, signed release
artifacts; the OCI
+# copies are convenience binaries. This workflow therefore never builds a
chart, it only
+# re-publishes a verified copy of one that has already been released.
+#
+# This workflow is also used to backfill previously released versions. Note
that
+# dist.apache.org only keeps the most recent release, so backfilling an older
version means
+# pointing at archive.apache.org instead; both hosts carry the same
.sha512/.asc/.prov files.
+
+on:
+ workflow_dispatch:
+ inputs:
+ solr-operator-chart-url:
+ description: 'URL to solr-operator Helm chart tarball on
dist.apache.org or archive.apache.org (e.g.,
https://dist.apache.org/repos/dist/release/solr/solr-operator/v0.10.0/helm-charts/solr-operator-0.10.0.tgz)'
+ required: true
+ type: string
+ solr-chart-url:
+ description: 'URL to solr Helm chart tarball on dist.apache.org or
archive.apache.org (e.g.,
https://dist.apache.org/repos/dist/release/solr/solr-operator/v0.10.0/helm-charts/solr-0.10.0.tgz)'
+ required: true
+ type: string
+ dry-run:
+ description: 'Dry run - download and verify charts but do not push to
the OCI registry'
+ required: false
+ type: boolean
+ default: false
+
+permissions:
+ contents: read
+ packages: write
+
+# Publishing is not safe to run twice at once: two runs could race on the same
chart tag.
+concurrency:
+ group: publish-helm-oci
+ cancel-in-progress: false
+
+env:
+ # 'helm push' appends the chart name from Chart.yaml to this target,
producing:
+ # ghcr.io/apache/solr-operator/helm/solr-operator
+ # ghcr.io/apache/solr-operator/helm/solr
+ # The charts are namespaced under the repository name because
ghcr.io/apache/* is a
+ # single namespace shared by every ASF project. Keeping the charts here also
leaves
+ # 'apache/solr' free for a future Solr server image.
+ OCI_TARGET: oci://ghcr.io/apache/solr-operator/helm
+ ASF_KEYS_URL: https://dist.apache.org/repos/dist/release/solr/KEYS
+
+jobs:
+ publish-oci:
+ name: Publish Helm Charts to OCI Registry
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ # Both the action and the Helm version it installs are pinned: this
workflow publishes
+ # release artifacts, so it must not change behaviour because an upstream
tag moved.
+ - name: Install Helm
+ uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 #
v4.3.1
+ with:
+ version: 'v4.3.1'
+
+ # Inputs are passed through the environment rather than interpolated
into the
+ # script body, so that a malicious input cannot inject shell commands.
+ - name: Validate input URLs
+ id: inputs
+ env:
+ OPERATOR_CHART_URL: ${{ inputs.solr-operator-chart-url }}
+ SOLR_CHART_URL: ${{ inputs.solr-chart-url }}
+ run: |
+ set -euo pipefail
+
+ # dist.apache.org holds only the current release, so older versions
have to be
+ # backfilled from archive.apache.org. Both are ASF-controlled hosts.
+ dist_re='^https://dist\.apache\.org/repos/dist/(release|dev)/solr/'
+ archive_re='^https://archive\.apache\.org/dist/solr/'
+
+ for url in "${OPERATOR_CHART_URL}" "${SOLR_CHART_URL}"; do
+ if [[ ! "${url}" =~ ${dist_re} && ! "${url}" =~ ${archive_re} ]];
then
+ echo "Error: chart URLs must be from dist.apache.org or
archive.apache.org: ${url}" >&2
+ exit 1
+ fi
+ done
+
+ # The .sha512 and .prov files both reference the chart's original
filename, so
+ # the downloads must keep their basenames rather than being renamed.
+ OPERATOR_CHART_FILE="$(basename "${OPERATOR_CHART_URL}")"
+ SOLR_CHART_FILE="$(basename "${SOLR_CHART_URL}")"
+
+ if [[ ! "${OPERATOR_CHART_FILE}" =~
^solr-operator-[0-9][A-Za-z0-9.+_-]*\.tgz$ ]]; then
+ echo "Error: unexpected solr-operator chart filename:
${OPERATOR_CHART_FILE}" >&2
+ exit 1
+ fi
+ if [[ ! "${SOLR_CHART_FILE}" =~ ^solr-[0-9][A-Za-z0-9.+_-]*\.tgz$
]]; then
+ echo "Error: unexpected solr chart filename: ${SOLR_CHART_FILE}"
>&2
+ exit 1
+ fi
+
+ echo "operator-chart-file=${OPERATOR_CHART_FILE}" >> "$GITHUB_OUTPUT"
+ echo "solr-chart-file=${SOLR_CHART_FILE}" >> "$GITHUB_OUTPUT"
+ echo "URLs validated"
+ echo " solr-operator chart: ${OPERATOR_CHART_FILE}"
+ echo " solr chart: ${SOLR_CHART_FILE}"
+
+ - name: Download charts, checksums, signatures and provenance
+ env:
+ OPERATOR_CHART_URL: ${{ inputs.solr-operator-chart-url }}
+ SOLR_CHART_URL: ${{ inputs.solr-chart-url }}
+ run: |
+ set -euo pipefail
+ mkdir -p charts && cd charts
+
+ # The .prov file is what makes 'helm install --verify' work against
the OCI
+ # copy: 'helm push' uploads it automatically when it sits next to
the chart.
+ for url in "${OPERATOR_CHART_URL}" "${SOLR_CHART_URL}"; do
+ for suffix in "" .sha512 .asc .prov; do
+ curl --fail --show-error --silent --location --retry 3
--retry-delay 5 \
+ -O "${url}${suffix}"
+ done
+ done
+
+ echo "Downloaded:"
+ ls -lh
+
+ - name: Verify SHA512 checksums
+ working-directory: charts
+ run: |
+ set -euo pipefail
+ sha512sum -c ./*.tgz.sha512
+ echo "SHA512 checksums verified"
+
+ # The checksums come from the same host as the charts, so on their own
they only
+ # prove the download was not corrupted. The detached GPG signatures are
what prove
+ # the artifacts are the ones the PMC voted on.
+ - name: Verify GPG signatures
+ working-directory: charts
+ run: |
+ set -euo pipefail
+ curl --fail --show-error --silent --location "${ASF_KEYS_URL}" | gpg
--import --quiet
+ for asc in ./*.tgz.asc; do
+ gpg --verify "${asc}" "${asc%.asc}"
+ done
+ echo "GPG signatures verified"
+
+ - name: Extract chart versions
+ id: versions
+ working-directory: charts
+ env:
+ OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }}
+ SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }}
+ run: |
+ set -euo pipefail
+ OPERATOR_VERSION="$(tar -xzOf "${OPERATOR_CHART_FILE}"
solr-operator/Chart.yaml | awk '$1 == "version:" {print $2; exit}')"
+ SOLR_VERSION="$(tar -xzOf "${SOLR_CHART_FILE}" solr/Chart.yaml | awk
'$1 == "version:" {print $2; exit}')"
+
+ echo "operator-version=${OPERATOR_VERSION}" >> "$GITHUB_OUTPUT"
+ echo "solr-version=${SOLR_VERSION}" >> "$GITHUB_OUTPUT"
+ echo "Solr Operator chart version: ${OPERATOR_VERSION}"
+ echo "Solr chart version: ${SOLR_VERSION}"
+
+ - name: Log in to GitHub Container Registry
+ if: ${{ !inputs.dry-run }}
+ env:
+ REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REGISTRY_USER: ${{ github.actor }}
+ run: |
+ set -euo pipefail
+ echo "${REGISTRY_TOKEN}" | \
+ helm registry login ghcr.io -u "${REGISTRY_USER}" --password-stdin
+ echo "Logged in to ghcr.io"
+
+ - name: Push charts to OCI registry
+ if: ${{ !inputs.dry-run }}
+ working-directory: charts
+ env:
+ OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }}
+ SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }}
+ run: |
+ set -euo pipefail
+ # helm appends each chart's name, so both charts share one push
target.
+ helm push "${OPERATOR_CHART_FILE}" "${OCI_TARGET}"
+ helm push "${SOLR_CHART_FILE}" "${OCI_TARGET}"
+
+ # Packages are created private by default on ghcr.io. Re-pulling
anonymously is what
+ # catches that: it fails loudly rather than leaving a chart nobody can
install.
+ - name: Verify published charts are anonymously pullable
+ if: ${{ !inputs.dry-run }}
+ env:
+ OPERATOR_VERSION: ${{ steps.versions.outputs.operator-version }}
+ SOLR_VERSION: ${{ steps.versions.outputs.solr-version }}
+ OPERATOR_CHART_FILE: ${{ steps.inputs.outputs.operator-chart-file }}
+ SOLR_CHART_FILE: ${{ steps.inputs.outputs.solr-chart-file }}
+ run: |
+ set -euo pipefail
+ helm registry logout ghcr.io || true
+
+ # 'helm pull --verify' reads the pushed .prov, so this also proves
provenance
+ # survived the round-trip. helm looks for the legacy public keyring.
+ gpg --export > ~/.gnupg/pubring.gpg
+
+ mkdir -p pulled
+ helm pull --verify "${OCI_TARGET}/solr-operator" --version
"${OPERATOR_VERSION}" -d pulled
+ helm pull --verify "${OCI_TARGET}/solr" --version "${SOLR_VERSION}"
-d pulled
+
+ # The pulled charts must be byte-identical to the released ones.
+ cmp "pulled/${OPERATOR_CHART_FILE}" "charts/${OPERATOR_CHART_FILE}"
+ cmp "pulled/${SOLR_CHART_FILE}" "charts/${SOLR_CHART_FILE}"
+ echo "Charts are public, verifiable and identical to the released
artifacts"
+
+ - name: Summary
+ if: ${{ success() }}
+ env:
+ OPERATOR_VERSION: ${{ steps.versions.outputs.operator-version }}
+ SOLR_VERSION: ${{ steps.versions.outputs.solr-version }}
+ DRY_RUN: ${{ inputs.dry-run }}
+ run: |
+ set -euo pipefail
+ REGISTRY="${OCI_TARGET}"
+
+ if [[ "${DRY_RUN}" == "true" ]]; then
+ echo "## Dry run - nothing was published" >> "$GITHUB_STEP_SUMMARY"
+ else
+ echo "## Helm charts published" >> "$GITHUB_STEP_SUMMARY"
+ fi
+ {
+ echo ""
+ echo "| Check | Result |"
+ echo "| --- | --- |"
+ echo "| URLs from dist.apache.org | passed |"
+ echo "| SHA512 checksums | verified |"
+ echo "| GPG signatures | verified |"
+ echo "| solr-operator chart version | \`${OPERATOR_VERSION}\` |"
+ echo "| solr chart version | \`${SOLR_VERSION}\` |"
+ echo ""
+ } >> "$GITHUB_STEP_SUMMARY"
+
+ if [[ "${DRY_RUN}" == "true" ]]; then
+ echo "Re-run with **dry-run = false** to publish." >>
"$GITHUB_STEP_SUMMARY"
+ else
+ {
+ echo "Anonymously pulled back and verified against the released
artifacts."
+ echo ""
+ echo '```bash'
+ echo "helm install solr-operator ${REGISTRY}/solr-operator
--version ${OPERATOR_VERSION}"
+ echo "helm install example ${REGISTRY}/solr --version
${SOLR_VERSION}"
+ echo '```'
+ } >> "$GITHUB_STEP_SUMMARY"
+ fi
diff --git a/hack/release/smoke_test/test_cluster.sh
b/hack/release/smoke_test/test_cluster.sh
index b99e722..75c0b30 100755
--- a/hack/release/smoke_test/test_cluster.sh
+++ b/hack/release/smoke_test/test_cluster.sh
@@ -23,7 +23,7 @@ set -u
show_help() {
cat << EOF
-Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k
KUBERNETES_VERSION] [-t SOLR_IMAGE] [-g GPG_KEY] -v VERSION -l LOCATION
+Usage: ./hack/release/smoke_test/test_cluster.sh [-h] [-i IMAGE] [-k
KUBERNETES_VERSION] [-t SOLR_IMAGE] [-g GPG_KEY] [-o OCI_REGISTRY] -v VERSION
-l LOCATION
Test the release candidate in a Kind cluster
@@ -34,11 +34,14 @@ Test the release candidate in a Kind cluster
-g GPG Key (fingerprint) used to sign the artifacts (Optional, if not
provided then the helm chart will not be verified)
-k Kubernetes Version to test with (full tag, e.g. v1.26.6) (Optional,
defaults to a compatible version)
-t Full solr image, or image tag (for the official Solr image), to test
with (e.g. apache/solr-nightly:9.0.0, 9.10.0). (Optional, defaults to a
compatible version)
+ -o OCI registry to install the Helm charts from, e.g.
oci://ghcr.io/apache/solr-operator/helm (Optional)
+ Use this after a release has been published, to smoke test the
published OCI artifacts.
+ The CRDs are still taken from LOCATION, since they are not part of the
OCI artifacts.
EOF
}
OPTIND=1
-while getopts hv:i:l:g:k:t: opt; do
+while getopts hv:i:l:g:k:t:o: opt; do
case $opt in
h)
show_help
@@ -56,6 +59,8 @@ while getopts hv:i:l:g:k:t: opt; do
;;
t) SOLR_IMAGE=$OPTARG
;;
+ o) OCI_REGISTRY=$OPTARG
+ ;;
*)
show_help >&2
exit 1
@@ -86,14 +91,15 @@ fi
export LOCATION="$LOCATION"
export VERSION="$VERSION"
+# An OCI registry is never a helm repo, so there is nothing to add or remove
for it.
function add_solr_helm_repo() {
- if (echo "${LOCATION}" | grep "http"); then
+ if [[ -z "${OCI_REGISTRY:-}" ]] && (echo "${LOCATION}" | grep "http"); then
helm repo add --force-update "apache-solr-test-${VERSION}"
"${LOCATION}/helm-charts"
fi
}
function remove_solr_helm_repo() {
- if (echo "${LOCATION}" | grep "http"); then
+ if [[ -z "${OCI_REGISTRY:-}" ]] && (echo "${LOCATION}" | grep "http"); then
helm repo remove "apache-solr-test-${VERSION}"
fi
}
@@ -113,6 +119,16 @@ else
SOLR_HELM_CHART="apache-solr-test-${VERSION}/solr"
fi
+# The charts published to an OCI registry are the same artifacts that were
staged at
+# LOCATION, so only where the charts are pulled from changes. CRDs still come
from LOCATION.
+# Unlike a helm repo, an OCI reference has no index, so the version must be
given explicitly.
+CHART_VERSION_ARG=()
+if [[ -n "${OCI_REGISTRY:-}" ]]; then
+ OP_HELM_CHART="${OCI_REGISTRY}/solr-operator"
+ SOLR_HELM_CHART="${OCI_REGISTRY}/solr"
+ CHART_VERSION_ARG=(--version "${VERSION#v}")
+fi
+
if ! (which kind); then
echo "Install Kind (Kubernetes in Docker)"
GO111MODULE="on" go install sigs.k8s.io/[email protected]
@@ -163,13 +179,13 @@ add_solr_helm_repo
# Install the Solr Operator
kubectl create -f "${LOCATION}/crds/all-with-dependencies.yaml" || kubectl
replace -f "${LOCATION}/crds/all-with-dependencies.yaml"
-helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} solr-operator
"${OP_HELM_CHART}" \
+helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} solr-operator
"${OP_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"} \
--set-string image.tag="${IMAGE##*:}" \
--set image.repository="${IMAGE%%:*}" \
--set image.pullPolicy="Never"
printf "\nInstall a test Solr Cluster\n"
-helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example
"${SOLR_HELM_CHART}" \
+helm install --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example
"${SOLR_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"} \
--set replicas=2 \
--set image.repository="${SOLR_IMAGE%%:*}" \
--set-string image.tag="${SOLR_IMAGE##*:}" \
@@ -291,7 +307,7 @@ fi
printf "\nDo a rolling restart and make sure the cluster is healthy
afterwards\n"
add_solr_helm_repo
-helm upgrade --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example
"${SOLR_HELM_CHART}" --reuse-values \
+helm upgrade --kube-context "${KUBE_CONTEXT}" ${VERIFY_OR_NOT} example
"${SOLR_HELM_CHART}" ${CHART_VERSION_ARG[@]+"${CHART_VERSION_ARG[@]}"}
--reuse-values \
--set-string podOptions.annotations.restart="true"
printf '\nWait for the rolling restart to begin.\n\n'
grep -q "2 [[:digit:]] [[:digit:]] 0" <(exec
kubectl get solrcloud example -w); kill $!
diff --git a/hack/release/wizard/releaseWizard.yaml
b/hack/release/wizard/releaseWizard.yaml
index ee3b9eb..1405639 100644
--- a/hack/release/wizard/releaseWizard.yaml
+++ b/hack/release/wizard/releaseWizard.yaml
@@ -1120,6 +1120,78 @@ groups:
cmd: ./hack/release/upload/upload_helm.sh -g "{{ gpg_key |
default("<gpg_key_id>", True) }}" -a "{{ gpg.apache_id | default("<apache_id>",
True) }}" -c "{{ official_helm_charts_url }}" -r "{{ dist_release_url }}"
logfile: upload_helm.log
tee: true
+ - !Todo
+ id: publish_helm_charts_oci
+ title: Publish Helm charts to the OCI registry (GHCR)
+ depends: publish_helm_charts
+ vars:
+ dist_release_url:
https://dist.apache.org/repos/dist/release/solr/solr-operator/{{
release_version }}
+ solr_operator_chart_url: '{{ dist_release_url
}}/helm-charts/solr-operator-{{ release_version[1:] }}.tgz'
+ solr_chart_url: '{{ dist_release_url }}/helm-charts/solr-{{
release_version[1:] }}.tgz'
+ workflow_url:
https://github.com/apache/solr-operator/actions/workflows/publish-helm-oci.yaml
+ description: |
+ Publish the released Helm charts as OCI artifacts to the GitHub
Container Registry,
+ using the "Publish Helm Charts to OCI Registry" GitHub Actions workflow.
+
+ The charts on dist.apache.org remain the canonical, signed release
artifacts.
+ The OCI copies are convenience binaries, published to:
+ - oci://ghcr.io/apache/solr-operator/helm/solr-operator
+ - oci://ghcr.io/apache/solr-operator/helm/solr
+
+ Steps to publish:
+ 1. Navigate to the GitHub Actions workflow:
+ {{ workflow_url }}
+
+ 2. Click the "Run workflow" button on the right side
+
+ 3. Fill in the workflow inputs:
+ - solr-operator-chart-url: {{ solr_operator_chart_url }}
+ - solr-chart-url: {{ solr_chart_url }}
+ - dry-run: true
+
+ 4. The dry-run verifies, without publishing anything, that:
+ - The URLs are valid and point at dist.apache.org
+ - The charts, checksums, signatures and provenance files all download
+ - The SHA512 checksums match
+ - The GPG signatures verify against the Solr KEYS file
+ - The chart versions are what you expect
+
+ 5. Re-run the workflow with dry-run = false to actually publish
+
+ 6. Monitor the workflow execution for any errors. After pushing, the
workflow logs
+ out of the registry and pulls both charts back anonymously, verifying
their
+ provenance and checking they are byte-identical to the released
artifacts.
+ If this step fails with an authorization error, the ghcr.io packages
are still
+ private and INFRA needs to make them public - see the note below.
+
+ 7. Confirm for yourself that the charts are resolvable, with no
credentials:
+
+ helm registry logout ghcr.io
+ helm show chart oci://ghcr.io/apache/solr-operator/helm/solr-operator
--version {{ release_version[1:] }}
+ helm show chart oci://ghcr.io/apache/solr-operator/helm/solr
--version {{ release_version[1:] }}
+
+ 8. Smoke test an actual install from the OCI registry, in a throwaway
Kind cluster.
+ The -o flag points the Helm installs at the OCI registry, while the
CRDs still come
+ from the release location. This verifies 'helm install --verify'
against the pushed
+ .prov files, which is the part 'helm show chart' does not cover:
+
+ ./hack/release/smoke_test/test_cluster.sh \
+ -v "{{ release_version }}" \
+ -l "{{ dist_release_url }}" \
+ -i "apache/solr-operator:{{ release_version }}-rc{{ rc_number }}"
\
+ -g "{{ gpg_key | default("<gpg_key_id>", True) }}" \
+ -o "oci://ghcr.io/apache/solr-operator/helm"
+
+ Note this uses the RC Docker image, since the final image is not
pushed to Docker
+ Hub until a later step. The chart is what is under test here, not the
image.
+
+ Note: the workflow authenticates with the built-in GITHUB_TOKEN, so no
secrets need
+ to be configured. However, ghcr.io creates new packages as *private*.
The very first
+ time a chart name is published, an INFRA ticket is needed to make the
package public.
+ This is a one-time action per chart name; later versions inherit the
visibility.
+ links:
+ -
https://github.com/apache/solr-operator/actions/workflows/publish-helm-oci.yaml
+ - https://dist.apache.org/repos/dist/release/solr/solr-operator/{{
release_version }}/helm-charts/
- !Todo
id: publish_crds
title: Publish the staged CRDs
@@ -1179,11 +1251,15 @@ groups:
depends:
- publish_docker_image
- publish_helm_charts
+ - publish_helm_charts_oci
description: |
Check to make sure that ArtifactHub has successfully loaded the {{
release_version }} version of the Solr Operator and Solr Helm Charts.
Mark this as complete when you have confirmed all aspects of the chart
in artifactHub.
The ChangeLog is very finicky, so make sure that it renders correctly.
+
+ Note that ArtifactHub still indexes the HTTPS chart repository, not the
OCI registry,
+ so the OCI copies published in the previous step will not show up here.
links:
- https://artifacthub.io/packages/helm/apache-solr/solr-operator
- https://artifacthub.io/packages/helm/apache-solr/solr