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

villebro pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/superset-kubernetes-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new d673122  test(helm): cover opt-out and template-helper branches (#232)
d673122 is described below

commit d673122ce11388d11b479d28874785209e357b58
Author: Ville Brofeldt <[email protected]>
AuthorDate: Thu Jul 23 19:31:48 2026 -0700

    test(helm): cover opt-out and template-helper branches (#232)
    
    * test(helm): cover opt-out and template-helper branches
    
    Adds targeted helm-unittest coverage for the chart render branches the
    two golden-snapshot suites (minimal, full-options) never exercised, plus
    small documentation and CI-hygiene fixes surfaced while reviewing the
    changes accumulated since 0.1.1 ahead of the 0.2.0 release branch.
    
    - charts/superset-operator/tests/optout_and_helpers_test.yaml: new
      targeted-assertion suite covering the serviceAccountName helper
      branches, metrics-disabled wiring, and the leader-election toggle,
      varying one knob at a time.
    - docs/contributing/development-guidelines.md: correct the Helm chart
      tests description — the two existing suites are snapshot-only; the new
      suite is what provides targeted assertions — and name all three.
    - docs/user-guide/lifecycle.md: clarify that migrate triggers on the
      resolved repository:tag string, so mutable tags or a digest repoint at
      the same tag do not re-run "superset db upgrade".
    - renovate.json: fix the helm-checksum prBodyNote to reference the
      actual CI check name ("Verify Helm checksum pin").
    - scripts/verify-release-ci.sh: document that E2E is intentionally not a
      release-publish gate (dynamic matrix job names).
    
    * docs: recommend pinning explicit image tags; drop latest from examples
    
    Adds an Image section to the configuration reference recommending
    explicit release tags over mutable ones such as `latest`, and pins the
    Superset image to the canonical 6.1.0 across all examples. Beyond the
    usual reproducibility argument, the operator keys the migrate task off
    the resolved repository:tag string, so a mutable tag repointed at a new
    build never re-runs `superset db upgrade` and the schema silently drifts
    from the running code.
    
    - docs/user-guide/configuration.md: new "## Image" section documenting
      the field and the pin-your-tags recommendation, cross-linked to
      Lifecycle > Changing the image tag.
    - Replace `latest` with 6.1.0 in every Superset-image example: index,
      README, architecture overview/internals (spec and status), lifecycle
      status samples, the dev-guide test snippet, and the dev sample CR.
    - Leave the experimental websocket community image
      (oneacrefund/superset-websocket) on `latest` — that is the only tag it
      publishes.
---
 README.md                                          |   2 +-
 .../tests/optout_and_helpers_test.yaml             | 126 +++++++++++++++++++++
 config/samples/superset_v1alpha1_superset.yaml     |   2 +-
 docs/architecture/internals.md                     |   4 +-
 docs/architecture/overview.md                      |   2 +-
 docs/contributing/development-guidelines.md        |   4 +-
 docs/index.md                                      |   4 +-
 docs/user-guide/configuration.md                   |  13 +++
 docs/user-guide/lifecycle.md                       |   6 +-
 renovate.json                                      |   2 +-
 scripts/verify-release-ci.sh                       |   7 ++
 11 files changed, 160 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 616f5af..9516209 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ metadata:
   name: my-superset
 spec:
   image:
-    tag: "latest"
+    tag: "6.1.0"
   environment: Development
   secretKey: thisIsNotSecure_changeInProduction!
   metastore:
diff --git a/charts/superset-operator/tests/optout_and_helpers_test.yaml 
b/charts/superset-operator/tests/optout_and_helpers_test.yaml
new file mode 100644
index 0000000..38cc060
--- /dev/null
+++ b/charts/superset-operator/tests/optout_and_helpers_test.yaml
@@ -0,0 +1,126 @@
+# 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.
+
+# Targeted assertions for the opt-out / helper branches that the full-render
+# golden snapshots (minimal_test.yaml, full_options_test.yaml) do not exercise.
+# Golden snapshots pin one combined config each; these focused tests vary a
+# single knob at a time so every branch of the affected helper/template is
+# covered and easy to extend with new cases.
+suite: opt-out branches and template helpers
+# Pin release identity so the fullname helper resolves deterministically:
+# release "my-release" does not contain chart name "superset-operator", so
+# `superset-operator.fullname` = "my-release-superset-operator".
+release:
+  name: my-release
+  namespace: my-namespace
+tests:
+  # --- superset-operator.serviceAccountName: all four branches ---
+  - it: uses the custom SA name when serviceAccount.create is true
+    set:
+      serviceAccount:
+        create: true
+        name: custom-sa
+    template: templates/deployment.yaml
+    asserts:
+      - equal:
+          path: spec.template.spec.serviceAccountName
+          value: custom-sa
+
+  - it: creates the SA object with the custom name when create is true
+    set:
+      serviceAccount:
+        create: true
+        name: custom-sa
+    template: templates/serviceaccount.yaml
+    asserts:
+      - hasDocuments:
+          count: 1
+      - equal:
+          path: metadata.name
+          value: custom-sa
+
+  - it: falls back to the fullname when create is true and no name is set
+    set:
+      serviceAccount:
+        create: true
+        name: ""
+    template: templates/deployment.yaml
+    asserts:
+      - equal:
+          path: spec.template.spec.serviceAccountName
+          value: my-release-superset-operator
+
+  - it: uses the external SA name when create is false
+    set:
+      serviceAccount:
+        create: false
+        name: preexisting-operator-sa
+    asserts:
+      - template: templates/deployment.yaml
+        equal:
+          path: spec.template.spec.serviceAccountName
+          value: preexisting-operator-sa
+      - template: templates/serviceaccount.yaml
+        hasDocuments:
+          count: 0
+
+  # The chart intentionally does not enforce serviceAccount cross-field rules
+  # (create=false with no name is unusual and left to the operator); this pins
+  # the relaxed fallback so it can't change silently — create=false + no name
+  # resolves to the cluster "default" SA rather than an empty string.
+  - it: falls back to the default SA when create is false and no name is set
+    set:
+      serviceAccount:
+        create: false
+        name: ""
+    asserts:
+      - template: templates/deployment.yaml
+        equal:
+          path: spec.template.spec.serviceAccountName
+          value: default
+      - template: templates/serviceaccount.yaml
+        hasDocuments:
+          count: 0
+
+  # --- metrics.enabled: false ---
+  - it: binds metrics to 0 and renders no metrics resources when disabled
+    set:
+      metrics:
+        enabled: false
+    asserts:
+      - template: templates/deployment.yaml
+        contains:
+          path: spec.template.spec.containers[0].args
+          content: --metrics-bind-address=0
+      - template: templates/metrics-service.yaml
+        hasDocuments:
+          count: 0
+      - template: templates/metrics-rbac.yaml
+        hasDocuments:
+          count: 0
+      - template: templates/metrics-servicemonitor.yaml
+        hasDocuments:
+          count: 0
+
+  # --- leaderElection.enabled: false ---
+  - it: disables leader election on the manager args when disabled
+    set:
+      leaderElection:
+        enabled: false
+    template: templates/deployment.yaml
+    asserts:
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: --leader-elect=false
diff --git a/config/samples/superset_v1alpha1_superset.yaml 
b/config/samples/superset_v1alpha1_superset.yaml
index 87921e0..32fe89f 100644
--- a/config/samples/superset_v1alpha1_superset.yaml
+++ b/config/samples/superset_v1alpha1_superset.yaml
@@ -24,7 +24,7 @@ metadata:
   name: superset-sample
 spec:
   image:
-    tag: latest-dev
+    tag: 6.1.0
   environment: Development
   secretKey: thisIsNotSecure_changeInProduction!
   metastore:
diff --git a/docs/architecture/internals.md b/docs/architecture/internals.md
index 00523df..e0c96f4 100644
--- a/docs/architecture/internals.md
+++ b/docs/architecture/internals.md
@@ -257,14 +257,14 @@ The parent `Superset` CR reports aggregate status:
 status:
   phase: Running
   observedGeneration: 3
-  tag: "latest"
+  tag: "6.1.0"
   ready: "7/7"
   components:
     webServer:
       phase: Ready
       ready: "2/2"
       ref: Deployment/example-web-server
-      image: apache/superset:latest
+      image: apache/superset:6.1.0
       replicas: 2
       readyReplicas: 2
       resources:
diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md
index d9b56fa..8d994ba 100644
--- a/docs/architecture/overview.md
+++ b/docs/architecture/overview.md
@@ -60,7 +60,7 @@ kind: Superset
 metadata:
   name: my-superset
 spec:
-  image: { tag: "latest" }
+  image: { tag: "6.1.0" }
   environment: Development
   secretKey: thisIsNotSecure_changeInProduction!
   metastore:
diff --git a/docs/contributing/development-guidelines.md 
b/docs/contributing/development-guidelines.md
index b813ac7..59df80d 100644
--- a/docs/contributing/development-guidelines.md
+++ b/docs/contributing/development-guidelines.md
@@ -125,7 +125,7 @@ func TestReconcile_MyScenario(t *testing.T) {
     superset := &supersetv1alpha1.Superset{
         ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "default"},
         Spec: supersetv1alpha1.SupersetSpec{
-            Image:       supersetv1alpha1.ImageSpec{Repository: 
"apache/superset", Tag: "latest"},
+            Image:       supersetv1alpha1.ImageSpec{Repository: 
"apache/superset", Tag: "6.1.0"},
             Environment: strPtr("dev"),
             SecretKey:   strPtr("test-secret-key"),
             Lifecycle: &supersetv1alpha1.LifecycleSpec{
@@ -215,7 +215,7 @@ helm unittest -u charts/superset-operator   # update 
snapshots after an intended
 make helm-values-covered    # verify every values.yaml knob is exercised
 ```
 
-Two scenarios anchor the suite: `minimal_test.yaml` renders the chart with 
default `values.yaml`, and `full_options_test.yaml` renders it with every knob 
set via `tests/values/full-options.yaml`. Both capture a full-render 
**snapshot** (stored in `tests/__snapshot__/`) plus targeted assertions for 
invariants that must never silently change (watch-scope RBAC, 
`WATCH_NAMESPACE`, ServiceAccount create-vs-BYO, metrics wiring). Chart/release 
identity is pinned in each suite so snapshots are s [...]
+Coverage comes in two complementary forms. Full-render **snapshots** catch 
drift across the whole rendered output — `minimal_test.yaml` (default 
`values.yaml`) and `full_options_test.yaml` (every knob set via 
`tests/values/full-options.yaml`), stored in `tests/__snapshot__/`. Targeted 
assertions (e.g. `optout_and_helpers_test.yaml`) cover opt-out and 
template-helper branches a single combined snapshot cannot systematically 
reach, varying one knob at a time. Chart/release identity is pinn [...]
 
 **Any change to the chart — especially a new values knob or feature — must be 
exercised in `tests/values/full-options.yaml` and its rendered effect captured 
in the snapshot (`helm unittest -u`).** This is enforced: `make 
helm-values-covered` (`scripts/check-chart-values-covered.sh`) fails CI when a 
`values.yaml` key is not set in the comprehensive values file. It closes the 
gap a snapshot alone cannot — a knob that defaults to null and renders nothing 
under defaults would otherwise leave [...]
 
diff --git a/docs/index.md b/docs/index.md
index 680f61a..45b8eae 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -58,7 +58,7 @@ metadata:
   name: my-superset
 spec:
   image:
-    tag: "latest"
+    tag: "6.1.0"
   environment: Development
   secretKey: thisIsNotSecure_changeInProduction!
   metastore:
@@ -107,7 +107,7 @@ The operator resolves this into parent-owned resources. 
Lifecycle task Jobs run
 ```text
 $ kubectl get supersets
 NAME           TAG      PHASE     LIFECYCLE   READY   AVAILABLE   AGE
-my-superset    latest   Running   Complete    3/3     True        5m
+my-superset    6.1.0    Running   Complete    3/3     True        5m
 
 $ kubectl get superset my-superset -o 
jsonpath='{.status.lifecycle.migrate.state}'
 Complete
diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md
index 2b24a79..98ac704 100644
--- a/docs/user-guide/configuration.md
+++ b/docs/user-guide/configuration.md
@@ -69,6 +69,19 @@ spec:
   webServer: {}
 ```
 
+## Image
+
+`spec.image` sets the Superset image for all Python components. `repository` 
defaults to the official Superset image; `tag` is required — set it to the 
release you want:
+
+```yaml
+spec:
+  image:
+    repository: apachesuperset.docker.scarf.sh/apache/superset  # default
+    tag: "6.1.0"
+```
+
+**Pin an explicit release tag — avoid mutable tags such as `latest`.** Beyond 
the usual reasons (reproducible rollouts, no surprise upgrades), the operator 
keys the migrate task off the resolved `repository:tag` string: repointing a 
mutable tag at a new build leaves the string unchanged, so `superset db 
upgrade` does **not** run and the schema silently drifts from the running code. 
Distinct, immutable release tags keep upgrades — and their migrations — 
deterministic. See [Lifecycle › Cha [...]
+
 ## Metastore
 
 The `metastore` field provides database connection configuration. There are 
two modes:
diff --git a/docs/user-guide/lifecycle.md b/docs/user-guide/lifecycle.md
index 70b1012..7b6a7ea 100644
--- a/docs/user-guide/lifecycle.md
+++ b/docs/user-guide/lifecycle.md
@@ -148,6 +148,8 @@ kubectl get superset my-superset -o 
jsonpath='{.status.lifecycle}'
 
 Any change to the resolved lifecycle image tag re-runs the migrate task 
(`superset db upgrade`), whether the new tag is a higher or lower version. The 
operator does not compare versions — it runs `superset db upgrade` on every 
image change.
 
+The migrate trigger keys off the resolved `repository:tag` string, not the 
underlying image digest. Mutable tags therefore do **not** re-run migrate: 
repointing a tag such as `latest` (or any tag) at a new digest leaves the 
string unchanged, so no migration runs. To force a migration, change the tag to 
a distinct value or bump `migrate.trigger`.
+
 Migrate only ever runs `superset db upgrade`; the operator never runs 
`superset db downgrade` (Superset's down migrations are poorly tested and often 
break). So pinning back to an older image re-runs the forward migration rather 
than reversing the schema — you are responsible for ensuring the database is 
compatible with the target image, for example by restoring a backup taken 
before the upgrade. Take a backup before every upgrade so you can revert if 
needed.
 
 ## Drain Behavior
@@ -606,13 +608,13 @@ status:
       startedAt: "2026-03-16T10:00:00Z"
       completedAt: "2026-03-16T10:00:12Z"
       attempts: 1
-      image: apache/superset:latest
+      image: apache/superset:6.1.0
     init:
       state: Complete
       startedAt: "2026-03-16T10:00:13Z"
       completedAt: "2026-03-16T10:00:22Z"
       attempts: 1
-      image: apache/superset:latest
+      image: apache/superset:6.1.0
 ```
 
 Task Job names are deterministic: `{parentName}-{taskType}` (e.g. 
`my-superset-migrate`). Inspect the Job directly with `kubectl get job 
my-superset-migrate`.
diff --git a/renovate.json b/renovate.json
index edb9ae7..ecd3270 100644
--- a/renovate.json
+++ b/renovate.json
@@ -36,7 +36,7 @@
       "matchFileNames": ["scripts/install-helm.sh"],
       "addLabels": ["review:helm-checksum"],
       "prBodyNotes": [
-        ":warning: After bumping Helm, run `make sync-helm-checksum` and 
commit the result to update the pinned `HELM_SHA256` in 
`scripts/install-helm.sh`. The `Verify helm checksum` CI check will fail until 
this is done."
+        ":warning: After bumping Helm, run `make sync-helm-checksum` and 
commit the result to update the pinned `HELM_SHA256` in 
`scripts/install-helm.sh`. The `Verify Helm checksum pin` CI check will fail 
until this is done."
       ]
     }
   ],
diff --git a/scripts/verify-release-ci.sh b/scripts/verify-release-ci.sh
index e022b35..d7b71b4 100755
--- a/scripts/verify-release-ci.sh
+++ b/scripts/verify-release-ci.sh
@@ -24,6 +24,13 @@
 # filters in ci.yaml/test.yaml/license.yml), so the tagged commit — the release
 # branch HEAD — carries their check runs.
 #
+# E2E is intentionally NOT among the gated checks. The E2E matrix jobs use
+# dynamic names (e.g. "E2E (1.34)", "E2E (next, best-effort)") that are
+# impractical to pin as branch-protection contexts, so E2E is treated as
+# best-effort and does not block a release. If E2E should ever gate releases,
+# add its (stabilized) job names to .asf.yaml rather than special-casing them
+# here.
+#
 # Only release tags (refs/tags/v*) are gated; pushes to main and 
workflow_dispatch
 # runs (which publish the throwaway `dev`/`sha-` images) proceed without 
waiting.
 #

Reply via email to