This is an automated email from the ASF dual-hosted git repository.

mfordjody pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git


The following commit(s) were added to refs/heads/master by this push:
     new b7605bae Refine the build and release process (#961)
b7605bae is described below

commit b7605bae2a78e886a52857e0651dd43bce49da2f
Author: mfordjody <[email protected]>
AuthorDate: Sat Jul 18 16:26:01 2026 +0800

    Refine the build and release process (#961)
---
 manifests/charts/base/Chart.yaml => .dockerignore  |  23 ++--
 .github/workflows/ci.yml                           |   2 +
 .github/workflows/release.yaml                     | 124 +++++++++++++++++++++
 dubbod/discovery/docker/dockerfile.dubbod          |  18 ++-
 manifests/charts/README.md                         |   5 +
 manifests/charts/base/Chart.yaml                   |   4 +-
 manifests/charts/dubbod/Chart.yaml                 |   4 +-
 manifests/charts/dubbod/README.md                  |  31 ++++--
 .../charts/dubbod/templates/cni-daemonset.yaml     |   2 +-
 .../charts/dubbod/templates/configmap-values.yaml  |   3 +-
 manifests/charts/dubbod/templates/deployment.yaml  |   7 +-
 manifests/charts/dubbod/values.yaml                |   4 +-
 tests/e2e/run.sh                                   |  78 ++++++++++++-
 13 files changed, 261 insertions(+), 44 deletions(-)

diff --git a/manifests/charts/base/Chart.yaml b/.dockerignore
similarity index 62%
copy from manifests/charts/base/Chart.yaml
copy to .dockerignore
index 0fb64454..a52d2fde 100644
--- a/manifests/charts/base/Chart.yaml
+++ b/.dockerignore
@@ -13,19 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-apiVersion: v2
-annotations:
-  licenses: Apache-2.0
-name: base
-home: https://github.com/apache/dubbo-kubernetes
-icon: https://avatars.githubusercontent.com/u/11751992?s=200&v=4
-description: Helm chart for deploying dubbo cluster resources and CRDs.
-version: 0.3.9
-appVersion: "latest"
-maintainers:
-  - name: mfordjody
-    email: [email protected]
-sources:
-  - https://dubbo.apache.org
-  - https://github.com/kdubbo
-  - https://github.com/apache/dubbo-kubernetes
+.git
+.github
+.idea
+.vscode
+bin
+coverage.txt
+*.log
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cb30f9d3..17efd658 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -192,4 +192,6 @@ jobs:
           version: 'v0.30.0'
 
       - name: Run e2e smoke test
+        env:
+          UPGRADE_FROM_VERSION: '0.4.3'
         run: make test-e2e
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 6807e38c..7ce67f7c 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -23,6 +23,10 @@ on:
 permissions:
   contents: write
 
+concurrency:
+  group: release-${{ github.ref }}
+  cancel-in-progress: false
+
 jobs:
   create_release:
     name: Create Release
@@ -32,6 +36,15 @@ jobs:
       - name: Checkout code
         uses: actions/checkout@v4
 
+      - name: Validate release tag
+        env:
+          TAG: ${{ github.ref_name }}
+        run: |
+          if [[ ! "${TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+            echo "Release tag must be numeric semantic version (for example, 
0.4.3): ${TAG}" >&2
+            exit 1
+          fi
+
       - name: Create GitHub Release if missing
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -147,3 +160,114 @@ jobs:
             "${{ steps.package_ctl.outputs.name }}.sha256" \
             "${{ steps.package_dubbo.outputs.name }}" \
             "${{ steps.package_dubbo.outputs.name }}.sha256"
+
+  publish_image:
+    name: Publish Multi-Architecture Image
+    needs: create_release
+    if: github.repository == 'apache/dubbo-kubernetes'
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    permissions:
+      contents: read
+      id-token: write
+      packages: write
+    env:
+      IMAGE: ghcr.io/${{ github.repository }}/dubbod
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v4
+
+      - name: Set up QEMU
+        uses: docker/[email protected]
+
+      - name: Set up Docker Buildx
+        uses: docker/[email protected]
+
+      - name: Log in to GitHub Container Registry
+        uses: docker/[email protected]
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build and push versioned image
+        id: build_image
+        uses: docker/[email protected]
+        with:
+          context: .
+          file: dubbod/discovery/docker/dockerfile.dubbod
+          platforms: linux/amd64,linux/arm64
+          push: true
+          tags: ${{ env.IMAGE }}:${{ github.ref_name }}
+          labels: |
+            org.opencontainers.image.source=https://github.com/${{ 
github.repository }}
+            org.opencontainers.image.revision=${{ github.sha }}
+            org.opencontainers.image.version=${{ github.ref_name }}
+          build-args: |
+            GIT_VERSION=${{ github.ref_name }}
+          provenance: mode=max
+          sbom: true
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
+
+      - name: Install cosign
+        uses: sigstore/[email protected]
+
+      - name: Sign image digest with GitHub OIDC
+        env:
+          DIGEST: ${{ steps.build_image.outputs.digest }}
+        run: cosign sign --yes "${IMAGE}@${DIGEST}"
+
+      - name: Verify image signature
+        env:
+          DIGEST: ${{ steps.build_image.outputs.digest }}
+          CERTIFICATE_IDENTITY: https://github.com/${{ github.repository 
}}/.github/workflows/release.yaml@${{ github.ref }}
+        run: |
+          cosign verify \
+            --certificate-identity "${CERTIFICATE_IDENTITY}" \
+            --certificate-oidc-issuer 
"https://token.actions.githubusercontent.com"; \
+            "${IMAGE}@${DIGEST}"
+
+  package_charts:
+    name: Package Helm Charts
+    needs: create_release
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v4
+
+      - name: Install Helm
+        uses: azure/[email protected]
+        with:
+          version: 'v3.16.4'
+
+      - name: Lint, package, and verify charts
+        env:
+          TAG: ${{ github.ref_name }}
+        run: |
+          mkdir -p release-charts
+          helm lint manifests/charts/base
+          helm lint manifests/charts/dubbod
+          helm package manifests/charts/base \
+            --version "${TAG}" \
+            --app-version "${TAG}" \
+            --destination release-charts
+          helm package manifests/charts/dubbod \
+            --version "${TAG}" \
+            --app-version "${TAG}" \
+            --destination release-charts
+          helm template dubbod "release-charts/dubbod-${TAG}.tgz" \
+            --set global.proxyless.cni.enabled=false \
+            | grep -F "image: 
\"ghcr.io/apache/dubbo-kubernetes/dubbod:${TAG}\""
+          (
+            cd release-charts
+            sha256sum "base-${TAG}.tgz" > "base-${TAG}.tgz.sha256"
+            sha256sum "dubbod-${TAG}.tgz" > "dubbod-${TAG}.tgz.sha256"
+          )
+
+      - name: Upload chart assets
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          TAG: ${{ github.ref_name }}
+        run: gh release upload "${TAG}" --clobber release-charts/*
diff --git a/dubbod/discovery/docker/dockerfile.dubbod 
b/dubbod/discovery/docker/dockerfile.dubbod
index c78991f3..9e54cd30 100644
--- a/dubbod/discovery/docker/dockerfile.dubbod
+++ b/dubbod/discovery/docker/dockerfile.dubbod
@@ -17,6 +17,7 @@ FROM golang:1.25 AS builder
 
 ARG TARGETOS
 ARG TARGETARCH
+ARG GIT_VERSION=unknown
 
 WORKDIR /src
 
@@ -25,15 +26,26 @@ ENV CGO_ENABLED=0 \
     GOARCH=${TARGETARCH}
 
 COPY go.mod go.sum ./
-RUN go mod download -x
+RUN --mount=type=cache,target=/go/pkg/mod \
+    for attempt in 1 2 3; do \
+        if go mod download; then exit 0; fi; \
+        if [ "${attempt}" -eq 3 ]; then exit 1; fi; \
+        sleep "$((attempt * 5))"; \
+    done
 
 COPY . .
 
-RUN go build -v -trimpath -ldflags="-s -w" \
+RUN --mount=type=cache,target=/go/pkg/mod \
+    --mount=type=cache,target=/root/.cache/go-build \
+    go build -v -trimpath \
+    -ldflags="-s -w -X 
github.com/apache/dubbo-kubernetes/pkg/version.gitTag=${GIT_VERSION}" \
     -o /out/dubbod \
     ./dubbod/discovery/cmd/main.go
 
-RUN go build -v -trimpath -ldflags="-s -w" \
+RUN --mount=type=cache,target=/go/pkg/mod \
+    --mount=type=cache,target=/root/.cache/go-build \
+    go build -v -trimpath \
+    -ldflags="-s -w -X 
github.com/apache/dubbo-kubernetes/pkg/version.gitTag=${GIT_VERSION}" \
     -o /out/dubbo-cni \
     ./cni/main.go
 
diff --git a/manifests/charts/README.md b/manifests/charts/README.md
index ee7de938..91f0960c 100644
--- a/manifests/charts/README.md
+++ b/manifests/charts/README.md
@@ -15,3 +15,8 @@ Both install paths render exactly these charts:
 Any manifest change must be made here; do not fork rendered output elsewhere.
 CI lints and renders both charts on every PR (`make lint-helm`), and the kind
 smoke test installs them end-to-end (`make test-e2e`).
+
+Every numeric release packages both charts with the release version and uploads
+the archives plus SHA-256 checksums to the matching GitHub Release. The dubbod
+chart's `appVersion` selects the same versioned
+`ghcr.io/apache/dubbo-kubernetes/dubbod` image by default.
diff --git a/manifests/charts/base/Chart.yaml b/manifests/charts/base/Chart.yaml
index 0fb64454..671e966e 100644
--- a/manifests/charts/base/Chart.yaml
+++ b/manifests/charts/base/Chart.yaml
@@ -20,8 +20,8 @@ name: base
 home: https://github.com/apache/dubbo-kubernetes
 icon: https://avatars.githubusercontent.com/u/11751992?s=200&v=4
 description: Helm chart for deploying dubbo cluster resources and CRDs.
-version: 0.3.9
-appVersion: "latest"
+version: 0.4.3
+appVersion: "0.4.3"
 maintainers:
   - name: mfordjody
     email: [email protected]
diff --git a/manifests/charts/dubbod/Chart.yaml 
b/manifests/charts/dubbod/Chart.yaml
index 64091abc..fba01f48 100644
--- a/manifests/charts/dubbod/Chart.yaml
+++ b/manifests/charts/dubbod/Chart.yaml
@@ -25,8 +25,8 @@ keywords:
   - dubbod
   - dubbo-discovery
   - dubbo-control-plane
-version: 0.3.9
-appVersion: "latest"
+version: 0.4.3
+appVersion: "0.4.3"
 maintainers:
   - name: mfordjody
     email: [email protected]
diff --git a/manifests/charts/dubbod/README.md 
b/manifests/charts/dubbod/README.md
index ae2c4794..315c2310 100644
--- a/manifests/charts/dubbod/README.md
+++ b/manifests/charts/dubbod/README.md
@@ -1,23 +1,32 @@
 # Dubbod Helm Chart
 
-This chart installs an Dubbod deployment.
+This chart installs the Dubbod deployment.
 
-## Setup Repo Info
+## Installing a Versioned Release
 
 ```bash
-helm repo add dubbo https://charts.dubbo.apache.org
-helm repo update
+# Select a release whose Assets include the packaged charts.
+VERSION="<version>"
+kubectl create namespace dubbo-system
+helm upgrade --install dubbo-base \
+  
"https://github.com/apache/dubbo-kubernetes/releases/download/${VERSION}/base-${VERSION}.tgz";
 \
+  --namespace dubbo-system
+helm upgrade --install dubbod \
+  
"https://github.com/apache/dubbo-kubernetes/releases/download/${VERSION}/dubbod-${VERSION}.tgz";
 \
+  --namespace dubbo-system
 ```
 
-See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command 
documentation.
-
-## Installing the Chart
+Release `0.4.3` predates packaged chart assets; the commands above apply to
+releases produced by the current release workflow.
 
-To install the chart with the release name dubbo:
+The packaged chart defaults to
+`ghcr.io/apache/dubbo-kubernetes/dubbod:${VERSION}`. Override the shared
+control-plane/CNI image when using a mirror or a locally loaded image:
 
 ```bash
-kubectl create namespace dubbo-system
-helm install dubbod dubbo/dubbod --namespace dubbo-system
+helm upgrade --install dubbod ./dubbod-${VERSION}.tgz \
+  --namespace dubbo-system \
+  --set-string 
global.proxyless.cni.image=registry.example.com/dubbod:${VERSION}
 ```
 
 ## Uninstalling the Chart
@@ -26,4 +35,4 @@ To uninstall/delete the dubbo deployment:
 
 ```bash
 helm delete dubbod --namespace dubbo-system
-```
\ No newline at end of file
+```
diff --git a/manifests/charts/dubbod/templates/cni-daemonset.yaml 
b/manifests/charts/dubbod/templates/cni-daemonset.yaml
index 93315724..5e802e4c 100644
--- a/manifests/charts/dubbod/templates/cni-daemonset.yaml
+++ b/manifests/charts/dubbod/templates/cni-daemonset.yaml
@@ -28,7 +28,7 @@
 {{- $enabled = $cni.enabled }}
 {{- end }}
 {{- if $enabled }}
-{{- $image := coalesce $cni.image $defaultCNI.image "kdubbo/dubbod:debug" }}
+{{- $image := coalesce $cni.image $defaultCNI.image (printf 
"ghcr.io/apache/dubbo-kubernetes/dubbod:%s" .Chart.AppVersion) }}
 {{- $binDir := coalesce $cni.binDir $defaultCNI.binDir "/opt/cni/bin" }}
 {{- $confDir := coalesce $cni.confDir $defaultCNI.confDir "/etc/cni/net.d" }}
 {{- $stateDir := coalesce $cni.stateDir $defaultCNI.stateDir 
"/var/run/dubbo-cni" }}
diff --git a/manifests/charts/dubbod/templates/configmap-values.yaml 
b/manifests/charts/dubbod/templates/configmap-values.yaml
index f25278d6..aacad334 100644
--- a/manifests/charts/dubbod/templates/configmap-values.yaml
+++ b/manifests/charts/dubbod/templates/configmap-values.yaml
@@ -29,6 +29,7 @@
 {{- $statusPort := coalesce $global.statusPort $defaultGlobal.statusPort 26020 
}}
 {{- $guiPort := int (coalesce $gui.port $defaultGUI.port 26080) }}
 {{- $guiNodePort := int (coalesce $gui.nodePort $defaultGUI.nodePort 30080) }}
+{{- $image := coalesce $cni.image $defaultCNI.image (printf 
"ghcr.io/apache/dubbo-kubernetes/dubbod:%s" .Chart.AppVersion) }}
 {{- $cniEnabled := false }}
 {{- if hasKey $defaultCNI "enabled" }}
 {{- $cniEnabled = $defaultCNI.enabled }}
@@ -54,7 +55,7 @@ data:
       proxyless:
         cni:
           enabled: {{ $cniEnabled }}
-          image: {{ coalesce $cni.image $defaultCNI.image 
"kdubbo/dubbod:debug" | quote }}
+          image: {{ $image | quote }}
           binDir: {{ coalesce $cni.binDir $defaultCNI.binDir "/opt/cni/bin" | 
quote }}
           confDir: {{ coalesce $cni.confDir $defaultCNI.confDir 
"/etc/cni/net.d" | quote }}
           stateDir: {{ coalesce $cni.stateDir $defaultCNI.stateDir 
"/var/run/dubbo-cni" | quote }}
diff --git a/manifests/charts/dubbod/templates/deployment.yaml 
b/manifests/charts/dubbod/templates/deployment.yaml
index eb87a688..87b9607c 100644
--- a/manifests/charts/dubbod/templates/deployment.yaml
+++ b/manifests/charts/dubbod/templates/deployment.yaml
@@ -15,11 +15,15 @@
 
 {{- $defaults := .Values._internal_default_values_not_set | default dict }}
 {{- $defaultGlobal := $defaults.global | default dict }}
+{{- $defaultProxyless := $defaultGlobal.proxyless | default dict }}
+{{- $defaultCNI := $defaultProxyless.cni | default dict }}
 {{- $defaultGUI := $defaultGlobal.gui | default dict }}
 {{- $defaultMulticluster := $defaultGlobal.multicluster | default dict }}
 {{- $defaultRemoteAccess := $defaultMulticluster.remoteAccess | default dict }}
 {{- $defaultEastWestGateway := $defaultMulticluster.eastWestGateway | default 
dict }}
 {{- $global := .Values.global | default dict }}
+{{- $proxyless := $global.proxyless | default dict }}
+{{- $cni := $proxyless.cni | default dict }}
 {{- $gui := $global.gui | default dict }}
 {{- $multicluster := $global.multicluster | default dict }}
 {{- $remoteAccess := $multicluster.remoteAccess | default dict }}
@@ -29,6 +33,7 @@
 {{- $remoteAccessCertificateHosts := $remoteAccess.certificateHosts | default 
$defaultRemoteAccess.certificateHosts | default (list) }}
 {{- $eastWestGateways := $eastWestGateway.gateways | default 
$defaultEastWestGateway.gateways | default (list) }}
 {{- $eastWestGatewayEntries := list }}
+{{- $image := coalesce $cni.image $defaultCNI.image (printf 
"ghcr.io/apache/dubbo-kubernetes/dubbod:%s" .Chart.AppVersion) }}
 {{- $defaultEastWestGatewayPort := int (coalesce $eastWestGateway.port 
$defaultEastWestGateway.port 15443) }}
 {{- range $gateway := $eastWestGateways }}
 {{- $gatewayPort := int (coalesce $gateway.port $defaultEastWestGatewayPort) }}
@@ -64,7 +69,7 @@ spec:
                     app: dubbod
       containers:
         - name: execute
-          image: "kdubbo/dubbod:debug"
+          image: {{ $image | quote }}
           imagePullPolicy: IfNotPresent
           args:
             - "execute"
diff --git a/manifests/charts/dubbod/values.yaml 
b/manifests/charts/dubbod/values.yaml
index a815da30..2342ecba 100644
--- a/manifests/charts/dubbod/values.yaml
+++ b/manifests/charts/dubbod/values.yaml
@@ -27,7 +27,9 @@ _internal_default_values_not_set:
     proxyless:
       cni:
         enabled: true
-        image: "kdubbo/dubbod:debug"
+        # Shared control-plane/CNI image. An empty value resolves to
+        # ghcr.io/apache/dubbo-kubernetes/dubbod:<Chart.appVersion>.
+        image: ""
         binDir: "/opt/cni/bin"
         confDir: "/etc/cni/net.d"
         stateDir: "/var/run/dubbo-cni"
diff --git a/tests/e2e/run.sh b/tests/e2e/run.sh
index 20ec33ab..8029c309 100755
--- a/tests/e2e/run.sh
+++ b/tests/e2e/run.sh
@@ -24,6 +24,9 @@
 #   CLUSTER_NAME    kind cluster name           (default: dubbo-e2e)
 #   IMAGE           dubbod image to build/load  (default: kdubbo/dubbod:debug)
 #   DUBBOD_REPLICAS control plane replicas      (default: 2, exercises HA)
+#   UPGRADE_FROM_VERSION previous release to install before upgrading 
(default: 0.4.3)
+#   UPGRADE_FROM_CHART   local previous chart path; skips release download
+#   UPGRADE_FROM_IMAGE   image expected by the previous chart (default: 
kdubbo/dubbod:debug)
 #   SKIP_BUILD      set to 1 to reuse an already-built ${IMAGE}
 #   KEEP_CLUSTER    set to 1 to keep the kind cluster after the run
 
@@ -33,9 +36,14 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
 CLUSTER_NAME="${CLUSTER_NAME:-dubbo-e2e}"
 IMAGE="${IMAGE:-kdubbo/dubbod:debug}"
 DUBBOD_REPLICAS="${DUBBOD_REPLICAS:-2}"
+UPGRADE_FROM_VERSION="${UPGRADE_FROM_VERSION:-0.4.3}"
+UPGRADE_FROM_CHART="${UPGRADE_FROM_CHART:-}"
+UPGRADE_FROM_IMAGE="${UPGRADE_FROM_IMAGE:-kdubbo/dubbod:debug}"
 SYSTEM_NS="dubbo-system"
 APP_NS="e2e"
 KUBECTL=(kubectl --context "kind-${CLUSTER_NAME}")
+UPGRADE_TMP_DIR=""
+PREVIOUS_CHART=""
 
 log() { echo "--- $*"; }
 
@@ -53,14 +61,51 @@ cleanup() {
   if [[ "${KEEP_CLUSTER:-0}" != "1" ]]; then
     kind delete cluster --name "${CLUSTER_NAME}" || true
   fi
+  if [[ -n "${UPGRADE_TMP_DIR}" && "${UPGRADE_TMP_DIR}" == */dubbo-upgrade.* 
]]; then
+    rm -rf -- "${UPGRADE_TMP_DIR}"
+  fi
 }
 trap cleanup EXIT
 
+prepare_previous_chart() {
+  if [[ -n "${UPGRADE_FROM_CHART}" ]]; then
+    [[ -e "${UPGRADE_FROM_CHART}" ]] || fail "previous chart not found: 
${UPGRADE_FROM_CHART}"
+    PREVIOUS_CHART="${UPGRADE_FROM_CHART}"
+    return
+  fi
+
+  UPGRADE_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/dubbo-upgrade.XXXXXX")"
+  local chart_asset="dubbod-${UPGRADE_FROM_VERSION}.tgz"
+  local 
release_url="https://github.com/apache/dubbo-kubernetes/releases/download/${UPGRADE_FROM_VERSION}";
+  if curl -fsSL --retry 3 "${release_url}/${chart_asset}" -o 
"${UPGRADE_TMP_DIR}/${chart_asset}" 2>/dev/null; then
+    log "using packaged chart from release ${UPGRADE_FROM_VERSION}"
+    curl -fsSL --retry 3 "${release_url}/${chart_asset}.sha256" \
+      -o "${UPGRADE_TMP_DIR}/${chart_asset}.sha256"
+    (cd "${UPGRADE_TMP_DIR}" && sha256sum -c "${chart_asset}.sha256")
+    PREVIOUS_CHART="${UPGRADE_TMP_DIR}/${chart_asset}"
+    return
+  fi
+
+  log "release ${UPGRADE_FROM_VERSION} predates packaged charts; using its 
tagged source chart"
+  local source_archive="${UPGRADE_TMP_DIR}/source.tar.gz"
+  curl -fsSL --retry 3 \
+    
"https://github.com/apache/dubbo-kubernetes/archive/refs/tags/${UPGRADE_FROM_VERSION}.tar.gz";
 \
+    -o "${source_archive}"
+  tar -xzf "${source_archive}" -C "${UPGRADE_TMP_DIR}"
+  
PREVIOUS_CHART="${UPGRADE_TMP_DIR}/dubbo-kubernetes-${UPGRADE_FROM_VERSION}/manifests/charts/dubbod"
+  [[ -f "${PREVIOUS_CHART}/Chart.yaml" ]] || fail "tagged release chart not 
found: ${PREVIOUS_CHART}"
+}
+
 if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
   log "building ${IMAGE}"
   docker build -f "${ROOT}/dubbod/discovery/docker/dockerfile.dubbod" -t 
"${IMAGE}" "${ROOT}"
 fi
 
+if [[ "${IMAGE}" != "${UPGRADE_FROM_IMAGE}" ]]; then
+  log "tagging ${IMAGE} as ${UPGRADE_FROM_IMAGE} for the previous chart"
+  docker tag "${IMAGE}" "${UPGRADE_FROM_IMAGE}"
+fi
+
 if ! kind get clusters 2>/dev/null | grep -qx "${CLUSTER_NAME}"; then
   log "creating kind cluster ${CLUSTER_NAME}"
   kind create cluster --name "${CLUSTER_NAME}" --wait 120s
@@ -68,6 +113,9 @@ fi
 
 log "loading ${IMAGE} into kind"
 kind load docker-image "${IMAGE}" --name "${CLUSTER_NAME}"
+if [[ "${IMAGE}" != "${UPGRADE_FROM_IMAGE}" ]]; then
+  kind load docker-image "${UPGRADE_FROM_IMAGE}" --name "${CLUSTER_NAME}"
+fi
 
 log "installing Gateway API CRDs"
 # Pin to the sigs.k8s.io/gateway-api version in go.mod.
@@ -80,21 +128,38 @@ helm upgrade --install dubbo-base 
"${ROOT}/manifests/charts/base" \
   -n "${SYSTEM_NS}" --create-namespace
 
 install_dubbod() {
+  local chart="$1"
+  local image="$2"
   # The CNI daemonset needs privileged host access; keep the smoke test to the
   # control plane itself.
-  helm upgrade --install dubbod "${ROOT}/manifests/charts/dubbod" \
+  helm upgrade --install dubbod "${chart}" \
     --kube-context "kind-${CLUSTER_NAME}" \
     -n "${SYSTEM_NS}" \
     --set global.proxyless.cni.enabled=false \
+    --set-string global.proxyless.cni.image="${image}" \
     --set replicaCount="${DUBBOD_REPLICAS}"
 }
 
-log "installing dubbod chart (${DUBBOD_REPLICAS} replicas)"
-install_dubbod
+prepare_previous_chart
+
+log "installing dubbod ${UPGRADE_FROM_VERSION} chart (${DUBBOD_REPLICAS} 
replicas)"
+install_dubbod "${PREVIOUS_CHART}" "${UPGRADE_FROM_IMAGE}"
 
-log "waiting for dubbod rollout"
+log "waiting for previous dubbod rollout"
 "${KUBECTL[@]}" -n "${SYSTEM_NS}" rollout status deploy/dubbod --timeout=300s \
-  || fail "dubbod deployment did not become ready"
+  || fail "dubbod ${UPGRADE_FROM_VERSION} deployment did not become ready"
+
+log "upgrading dubbod ${UPGRADE_FROM_VERSION} to the current chart"
+install_dubbod "${ROOT}/manifests/charts/dubbod" "${IMAGE}" \
+  || fail "upgrade from dubbod ${UPGRADE_FROM_VERSION} to the current chart 
failed"
+"${KUBECTL[@]}" -n "${SYSTEM_NS}" rollout status deploy/dubbod --timeout=300s \
+  || fail "upgraded dubbod deployment did not become ready"
+
+HELM_REVISION="$(helm history dubbod --kube-context "kind-${CLUSTER_NAME}" -n 
"${SYSTEM_NS}" | awk 'END {print $1}')"
+[[ "${HELM_REVISION}" -ge 2 ]] || fail "helm release revision is 
${HELM_REVISION}, want at least 2 after upgrade"
+DEPLOYED_IMAGE="$("${KUBECTL[@]}" -n "${SYSTEM_NS}" get deploy dubbod -o 
jsonpath='{.spec.template.spec.containers[0].image}')"
+[[ "${DEPLOYED_IMAGE}" == "${IMAGE}" ]] \
+  || fail "upgraded deployment image is ${DEPLOYED_IMAGE}, want ${IMAGE}"
 
 if [[ "${DUBBOD_REPLICAS}" -gt 1 ]]; then
   log "asserting PodDisruptionBudget exists for HA"
@@ -106,7 +171,8 @@ fi
 # hit server-side apply conflicts on the fields dubbod manages at runtime
 # (webhook caBundle / failurePolicy).
 log "re-running helm upgrade against the live control plane"
-install_dubbod || fail "helm upgrade over a running dubbod failed (SSA field 
conflict?)"
+install_dubbod "${ROOT}/manifests/charts/dubbod" "${IMAGE}" \
+  || fail "helm upgrade over a running dubbod failed (SSA field conflict?)"
 
 log "deploying sample workload (httpbin)"
 "${KUBECTL[@]}" create namespace "${APP_NS}" --dry-run=client -o yaml | 
"${KUBECTL[@]}" apply -f -

Reply via email to