Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/helm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ on:
paths:
- "charts/**"
jobs:
unit-test:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Helm tool installer
uses: Azure/setup-helm@v3

- name: Install helm-unittest plugin
run: helm plugin install https://github.com/helm-unittest/helm-unittest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we pin a version please?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — pinned to --version v1.1.1 (the current latest release, which the suite is verified against). Happy to bump it in a follow-up whenever you want to track newer plugin releases.


- name: Run helm unit tests
run: helm unittest charts/kafka-ui

build-and-test:
runs-on: ubuntu-latest
steps:
Expand Down
48 changes: 48 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Pre-commit hooks for kafbat/helm-charts
#
# Install once: pre-commit install
# Run on demand: pre-commit run --all-files
#
# These mirror what CI enforces (see .github/workflows/), so contributors
# catch issues locally before pushing. During a normal `git commit` the hooks
# only run against the files you staged, so they won't churn unrelated files.
repos:
# Render the chart templates and assert on the output. Mirrors the
# `unit-test` job in .github/workflows/helm.yaml. Requires the plugin:
# helm plugin install https://github.com/helm-unittest/helm-unittest
- repo: local
hooks:
- id: helm-unittest
name: helm unittest (kafka-ui)
entry: helm unittest charts/kafka-ui
language: system
files: '^charts/kafka-ui/(templates/.*|values\.yaml|Chart\.yaml|tests/.*\.yaml)$'
pass_filenames: false
verbose: true

# Keep CONFIGURATION.md in sync with the @param metadata in values.yaml.
# Mirrors the "Update README from values.yaml metadata" workflow, which
# otherwise auto-commits this on the PR.
- repo: local
hooks:
- id: readme-generator-for-helm
name: regenerate CONFIGURATION.md from values.yaml
entry: npx --yes @bitnami/readme-generator-for-helm --values charts/kafka-ui/values.yaml --readme charts/kafka-ui/CONFIGURATION.md
language: system
files: '^charts/kafka-ui/(values\.yaml|CONFIGURATION\.md)$'
pass_filenames: false

# General hygiene. These act only on staged files during a normal commit.
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
# Helm templates rely on significant whitespace in places; leave them.
exclude: '^charts/.*/templates/.*$'
- id: end-of-file-fixer
exclude: '^charts/.*/templates/.*$'
- id: check-merge-conflict
- id: check-added-large-files
- id: check-yaml
# Helm templates are Go templates, not plain YAML — skip them.
exclude: '^charts/.*/templates/.*$'
3 changes: 3 additions & 0 deletions charts/kafka-ui/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
| `probes.readiness.initialDelaySeconds` | Initial delay seconds for readiness probe | `10` |
| `probes.readiness.periodSeconds` | Period seconds for readiness probe | `30` |
| `probes.readiness.timeoutSeconds` | Timeout seconds for readiness probe | `10` |
| `probes.startup.failureThreshold` | Failure threshold for startup probe | `5` |
| `probes.startup.periodSeconds` | Period seconds for startup probe | `40` |
| `probes.startup.timeoutSeconds` | Timeout seconds for startup probe | `10` |

### Security Context

Expand Down
2 changes: 1 addition & 1 deletion charts/kafka-ui/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ apiVersion: v2
name: kafka-ui
description: A Helm chart for kafka-UI
type: application
version: 1.6.4
version: 1.6.6
appVersion: v1.5.0
icon: https://raw.githubusercontent.com/kafbat/kafka-ui/main/documentation/images/logo_new.png
57 changes: 57 additions & 0 deletions charts/kafka-ui/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Chart unit tests

These suites use [`helm-unittest`](https://github.com/helm-unittest/helm-unittest)
to render the chart's templates and assert on the resulting manifests. They run
in milliseconds, need no Kubernetes cluster, and catch template regressions
(missing fields, broken conditionals, failed `fail`/`required` guards) before a
change is ever applied.

## Running locally

Install the plugin once:

```bash
helm plugin install https://github.com/helm-unittest/helm-unittest
```

Then run the suites from the repository root:

```bash
helm unittest charts/kafka-ui
```

## Layout

One suite per template, named `<template>_test.yaml`:

| Suite | Template under test | Highlights |
|-------|---------------------|------------|
| `ingress_test.yaml` | `ingress.yaml` | API version selection, TLS, ingressClassName, templated host |
| `service_test.yaml` | `service.yaml` | type/port, NodePort/LoadBalancer specifics, selector labels |
| `deployment_test.yaml` | `deployment.yaml` | replicas vs. autoscaling, image reference, probes, env wiring |
| `notes_test.yaml` | `NOTES.txt` | ClusterIP port-forward fallback |

## Adding tests for a new feature

When you add or change a template, add or update the matching `*_test.yaml`
suite in the same PR. A good suite covers:

1. **Does not render when disabled** — the feature's `enabled: false` path.
2. **Renders correctly when enabled** — kind, apiVersion, name, namespace.
3. **Each configurable knob** — one assertion per value that changes output.
4. **Guards** — every `fail`/`required` is exercised with `failedTemplate`
so a misconfiguration is a red test, not a red CI render.

### Notes for templates that `include` siblings

`deployment.yaml` builds checksum annotations by `include`-ing `configmap.yaml`,
`configmap_fromValues.yaml` and `secret.yaml`. Those templates must be listed
under `templates:` so the includes resolve, and each test uses a
`documentSelector` with `skipEmptyTemplates: true` to assert against the
Deployment document while ignoring the (often empty) configmap/secret renders.

### Notes for `NOTES.txt`

`NOTES.txt` is plain text, not a manifest, so use the raw assertions
(`matchRegexRaw`, `equalRaw`) which operate on the rendered text directly
instead of a YAML `path`.
172 changes: 172 additions & 0 deletions charts/kafka-ui/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
suite: Deployment

# deployment.yaml computes checksum annotations by include-ing configmap.yaml,
# configmap_fromValues.yaml and secret.yaml, so those templates must be loaded
# for the suite to render. Those three emit no documents under most of these
# cases, so each test selects the Deployment document and skips empty templates.
templates:
- deployment.yaml
- configmap.yaml
- configmap_fromValues.yaml
- secret.yaml

tests:
- it: renders a Deployment with the fullname and release namespace
release:
name: kafka-ui
namespace: kafka
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- isKind:
of: Deployment
- isAPIVersion:
of: apps/v1
- equal:
path: metadata.name
value: kafka-ui
- equal:
path: metadata.namespace
value: kafka

- it: sets replicas from replicaCount when autoscaling is disabled
set:
replicaCount: 3
autoscaling:
enabled: false
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.replicas
value: 3

- it: omits replicas when autoscaling is enabled
set:
autoscaling:
enabled: true
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- notExists:
path: spec.replicas

- it: builds the image reference from registry, repository and appVersion
chart:
appVersion: v1.5.0
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: ghcr.io/kafbat/kafka-ui:v1.5.0

- it: allows the image tag to be overridden
set:
image:
tag: v1.4.0
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: ghcr.io/kafbat/kafka-ui:v1.4.0

- it: honours a global imageRegistry override
set:
global:
imageRegistry: my-mirror.example.com
image:
tag: v1.5.0
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: my-mirror.example.com/kafbat/kafka-ui:v1.5.0

- it: exposes the http container port 8080
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.template.spec.containers[0].ports[0].name
value: http
- equal:
path: spec.template.spec.containers[0].ports[0].containerPort
value: 8080

- it: wires the service account name
release:
name: kafka-ui
set:
serviceAccount:
create: true
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- equal:
path: spec.template.spec.serviceAccountName
value: kafka-ui

- it: defines liveness, readiness and startup probes
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- exists:
path: spec.template.spec.containers[0].livenessProbe
- exists:
path: spec.template.spec.containers[0].readinessProbe
- exists:
path: spec.template.spec.containers[0].startupProbe

- it: renders env entries supplied via env
set:
env:
- name: MY_VAR
value: my-value
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: MY_VAR
value: my-value

- it: sets the config additional-location env when yamlApplicationConfig is set
set:
yamlApplicationConfig:
kafka:
clusters:
- name: local
documentSelector:
path: kind
value: Deployment
skipEmptyTemplates: true
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: SPRING_CONFIG_ADDITIONAL-LOCATION
value: /kafka-ui/config.yml
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Loading