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.
#