From dd23a5a0d8d557b932fe39c28b5e63d29868a975 Mon Sep 17 00:00:00 2001 From: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com> Date: Tue, 9 Jun 2026 00:10:21 +0100 Subject: [PATCH 1/2] Add helm-unittest suite for operator-crds toggles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The operator-crds chart wraps every CRD in two values gates: crds.install (gates the whole render) and crds.keep (gates the helm.sh/resource-policy: keep annotation). A regression in either is silent — `helm install` still succeeds with the install gate removed, and a dropped keep annotation silently cascade-deletes CRs on uninstall. `ct install` cannot catch these. Add a helm-unittest suite covering all 13 CRDs that asserts the default render, crds.install=false, and crds.keep=false behaviours, plus a `task helm-unittest` runner and a CI step. Following the pattern established in stacklok-llm-gateway. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/helm-charts-test.yml | 9 ++++ Taskfile.yml | 12 +++++ deploy/charts/operator-crds/.helmignore | 2 + .../operator-crds/tests/toggles_test.yaml | 52 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 deploy/charts/operator-crds/tests/toggles_test.yaml diff --git a/.github/workflows/helm-charts-test.yml b/.github/workflows/helm-charts-test.yml index c123dbc334..02b2afbce8 100644 --- a/.github/workflows/helm-charts-test.yml +++ b/.github/workflows/helm-charts-test.yml @@ -53,6 +53,15 @@ jobs: - name: Run chart-testing (lint) run: ct lint --config ct.yaml + - name: Run helm-unittest (operator-crds toggles) + # Renders the operator-crds chart with default / crds.install=false + # / crds.keep=false and asserts the rendered output (CRD count, keep + # annotation presence). Catches silent regressions in the toggle + # wrappers that `ct install` cannot — `helm install` succeeds even + # when the install gate has been removed. The plugin version is + # pinned in the Taskfile's `helm-unittest` task. + run: task helm-unittest + - name: Create KIND cluster uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 diff --git a/Taskfile.yml b/Taskfile.yml index bc214299d8..b8fe13668e 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -26,6 +26,18 @@ tasks: - command -v helm-docs >/dev/null 2>&1 || go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest - helm-docs --chart-search-root=deploy/charts + helm-unittest: + desc: Run helm-unittest suites against the Helm charts + vars: + # Pinned version — bump deliberately alongside the matching pin in + # .github/workflows/helm-charts-test.yml. + HELM_UNITTEST_VERSION: v1.0.3 + cmds: + - >- + helm plugin list | grep -q unittest || + helm plugin install https://github.com/helm-unittest/helm-unittest --version {{.HELM_UNITTEST_VERSION}} + - helm unittest deploy/charts/operator-crds + mock-install: desc: Install the mockgen tool for mock generation status: diff --git a/deploy/charts/operator-crds/.helmignore b/deploy/charts/operator-crds/.helmignore index 2c12e2b315..27e87cb768 100644 --- a/deploy/charts/operator-crds/.helmignore +++ b/deploy/charts/operator-crds/.helmignore @@ -23,6 +23,8 @@ .vscode/ # Source CRD files (only wrapped templates are needed) files/ +# helm-unittest test suites (not part of the packaged chart) +tests/ # Documentation CLAUDE.md CONTRIBUTING.md diff --git a/deploy/charts/operator-crds/tests/toggles_test.yaml b/deploy/charts/operator-crds/tests/toggles_test.yaml new file mode 100644 index 0000000000..d5c17ca290 --- /dev/null +++ b/deploy/charts/operator-crds/tests/toggles_test.yaml @@ -0,0 +1,52 @@ +suite: crds chart toggles +# Exercises the two values knobs that wrap every CRD template: +# crds.install — gates the entire CRD render +# crds.keep — gates the `helm.sh/resource-policy: keep` annotation +# A regression in either is silent at install time (gate removed → +# unconditional install still works; keep removed → uninstall silently +# cascade-deletes CRs). These tests make both behaviours red-on-break. +# Assertions apply per template — each `templates:` entry renders one +# CustomResourceDefinition, so the three toggle tests run once per CRD. +templates: + - toolhive.stacklok.dev_embeddingservers.yaml + - toolhive.stacklok.dev_mcpexternalauthconfigs.yaml + - toolhive.stacklok.dev_mcpgroups.yaml + - toolhive.stacklok.dev_mcpoidcconfigs.yaml + - toolhive.stacklok.dev_mcpregistries.yaml + - toolhive.stacklok.dev_mcpremoteproxies.yaml + - toolhive.stacklok.dev_mcpserverentries.yaml + - toolhive.stacklok.dev_mcpservers.yaml + - toolhive.stacklok.dev_mcptelemetryconfigs.yaml + - toolhive.stacklok.dev_mcptoolconfigs.yaml + - toolhive.stacklok.dev_mcpwebhookconfigs.yaml + - toolhive.stacklok.dev_virtualmcpcompositetooldefinitions.yaml + - toolhive.stacklok.dev_virtualmcpservers.yaml + +tests: + - it: renders the CRD with the keep annotation on chart defaults + asserts: + - hasDocuments: + count: 1 + - isKind: + of: CustomResourceDefinition + - equal: + path: metadata.annotations["helm.sh/resource-policy"] + value: keep + + - it: renders nothing when crds.install is false + set: + crds.install: false + asserts: + - hasDocuments: + count: 0 + + - it: omits the keep annotation when crds.keep is false + set: + crds.keep: false + asserts: + - hasDocuments: + count: 1 + - isKind: + of: CustomResourceDefinition + - notExists: + path: metadata.annotations["helm.sh/resource-policy"] From 52c2966e7372adb5c1b88cfa85dc6d00fbb25a77 Mon Sep 17 00:00:00 2001 From: Chris Burns <29541485+ChrisJBurns@users.noreply.github.com> Date: Tue, 9 Jun 2026 00:15:29 +0100 Subject: [PATCH 2/2] Generalize helm-unittest CI step description The suite will grow beyond the operator-crds toggles, so replace the toggle-specific comment with a generic note on what helm-unittest is and why we run it. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/helm-charts-test.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/helm-charts-test.yml b/.github/workflows/helm-charts-test.yml index 02b2afbce8..cefaa6c488 100644 --- a/.github/workflows/helm-charts-test.yml +++ b/.github/workflows/helm-charts-test.yml @@ -53,13 +53,12 @@ jobs: - name: Run chart-testing (lint) run: ct lint --config ct.yaml - - name: Run helm-unittest (operator-crds toggles) - # Renders the operator-crds chart with default / crds.install=false - # / crds.keep=false and asserts the rendered output (CRD count, keep - # annotation presence). Catches silent regressions in the toggle - # wrappers that `ct install` cannot — `helm install` succeeds even - # when the install gate has been removed. The plugin version is - # pinned in the Taskfile's `helm-unittest` task. + - name: Run helm-unittest + # helm-unittest renders the charts and asserts on the resulting + # Kubernetes manifests, catching template regressions that `ct lint` + # and `ct install` do not — `helm install` can succeed even when the + # rendered output is subtly wrong. The plugin version is pinned in + # the Taskfile's `helm-unittest` task. run: task helm-unittest - name: Create KIND cluster