Helm charts for ClickStack (HyperDX observability platform). Two charts:
charts/clickstack— main chart (HyperDX app, ClickHouse, MongoDB, OTEL collector)charts/clickstack-operators— operator dependencies (MongoDB, ClickHouse operators)
Package manager: Yarn 4 (via Corepack). Versioning: Changesets.
Use the Makefile for tool setup, unit tests, and template coverage:
make setup # install helm-unittest, helm-docs, chart deps, and git hooks
make test # helm-unittest + example values validation
make coverage # helmcov template coverage
make integration # Kind integration suites (SUITES=api-only for one)
make ci # test + coverage + docs verificationThe pre-commit hook runs make test when staged files under charts/ change, and
make docs when chart values, templates, or README templates change. Install hooks
with make setup or make hooks.
# Install JS dependencies (for changesets/versioning scripts only)
yarn install
# Build Helm chart dependencies (required before template/test commands)
helm dependency build charts/clickstack# Validate templates render without errors
helm template clickstack-test charts/clickstack
# Validate with specific values file
helm template clickstack-test charts/clickstack -f examples/alb-ingress/values.yaml
helm template clickstack-test charts/clickstack -f examples/api-only/values.yamlmake test
# Run a SINGLE test file
helm unittest -f tests/app-deployment_test.yaml charts/clickstack
# Run tests matching a pattern
helm unittest -f 'tests/clickhouse-*_test.yaml' charts/clickstackTest files live in charts/clickstack/tests/ and follow the naming convention
<component>_test.yaml. Snapshots are stored in tests/__snapshot__/.
Shared value fixtures live in charts/clickstack/tests/values/<case>.yaml and are
loaded with the suite-level values: key when a test needs more data than inline
set: overrides comfortably provide:
suite: Test Deployment Default Sources Tpl
templates:
- hyperdx/deployment.yaml
values:
- values/deployment-tpl-defaults.yaml
tests:
- it: should render tpl-interpolated default connections
asserts:
- matchRegex:
path: spec.template.spec.containers[0].env[?(@.name=="DEFAULT_CONNECTIONS")].value
pattern: clickhouse-headlessPrefer inline set: for small overrides; use tests/values/ for multi-field
fixtures or tpl-heavy defaults reused across assertions.
make coverage
# Verbose per-file output
VERBOSE=1 make coverage
# Override the line and branch minimums
COVERAGE_THRESHOLD=99 BRANCH_COVERAGE_THRESHOLD=90 make coverageDownloads the helmcov release pinned in scripts/tool-versions.env into .tools/
and fails below 99% line and 90% branch coverage. Outputs coverage.out (Go
coverprofile) and coverage.xml (Cobertura).
CI runs the helmcov GitHub Action
via the helmcov job in .github/workflows/helm-test.yaml, which posts or updates
a pull request comment with line/branch coverage and uncovered details.
make docsRegenerates charts/*/README.md from values.yaml using helm-docs.
Only values with # comments in values.yaml appear in the README (--ignore-non-descriptions).
Each chart README includes version and CI build status badges.
The pre-commit hook verifies docs are up to date when values or templates change.
Suites live under integration-tests/<suite-name>/. Each has suite.yaml,
values.yaml, and assert.sh. Run locally with:
make integration # every suite, as CI runs them
make integration SUITES=api-only # one suiteEach suite creates a test-<suite> Kind cluster and deletes it afterwards. The
full-stack suite also runs scripts/smoke-test.sh and the Playwright checks in scripts/e2e/.
Requires: kind, helm, kubectl, yq.
- Always prefix with
warren/:warren/HDX-3588-otel-autoscaling,warren/fix-rbac-regression
- Conventional commits:
feat:,fix:,chore:,refactor:,docs:,test:,ci: - Scope is optional:
fix(ci):,feat!:(breaking) - Reference Linear ticket when applicable:
fix: make -app suffix conditional on fullnameOverride (HDX-3850)
- Title:
[HDX-<ticket>] <description> - Include Linear ticket link in description
- Merge strategy: squash merge (Kodiak auto-merge with
automergelabel)
- Add a changeset for user-facing changes:
npx changeset - Changesets live in
.changeset/and drive version bumps on release - If a change needs action on upgrade or restarts pods, add a bullet under
## Unreleasedindocs/UPGRADE.md(create the heading if the last release consumed it). The release renames it to the new version. The Upgrade Notes check fails amajorchangeset without one and warns onminor.
- Prefix all template names with
clickstack.:clickstack.fullname,clickstack.labels - Component-specific:
clickstack.hyperdx.fullname,clickstack.mongodb.fullname - Always use
include(nottemplate) so output can be piped to functions
- Organized by component:
templates/hyperdx/,templates/clickhouse/,templates/mongodb/ - Use
nindentfor indentation in template pipelines:{{- include "clickstack.labels" . | nindent 4 }} - Quote string values with
| quote; usetoYamlfor complex values - Guard optional sections with
{{- if .Values.x.y }}blocks - Use
tplfor values that may contain template expressions (see configmap.yaml)
- Top-level keys:
global,hyperdx,clickhouse,mongodb,otel-collector - Document user-facing values with
# --comments directly above each key (helm-docs format) make docsomits undocumented keys (--ignore-non-descriptions); prefer commenting parent keys for operator/subchart passthrough specshyperdx.config— non-sensitive env vars (ConfigMap), supportstplexpressionshyperdx.secrets— sensitive env vars (Secret); set tonullto skip creationhyperdx.deployment— Deployment spec (image, replicas, resources, probes, etc.)- Document all values with inline YAML comments
- Always include common labels via
{{- include "clickstack.labels" . | nindent 4 }} - Always include selector labels via
{{- include "clickstack.selectorLabels" . | nindent 6 }}
Test files use YAML format with helm-unittest conventions:
suite: Test <Component Name>
templates:
- <component>/<template>.yaml
tests:
- it: should <describe expected behavior>
set:
<values to override>
asserts:
- isKind:
of: <Kind>
- equal:
path: <jsonpath>
value: <expected>- One test file per template (or logical group)
- Use
hasDocuments: count: 0to assert a template produces no output - Use
matchRegexfor dynamic names (e.g.,pattern: -app$) - Use
containsfor list items (ports, env vars, etc.) - Test both default values and overridden values
- Test conditional rendering (enabled/disabled features)
- Always start with
#!/usr/bin/env bashandset -euo pipefail - Use uppercase for exported env vars:
RELEASE_NAME,NAMESPACE,SUITE_DIR - Use functions for reusable logic (see
smoke-test.sh,run-suite.sh) - Default variables with
${VAR:-default}or${1:?Usage message}
| Workflow | File | Trigger | Purpose |
|---|---|---|---|
| Helm Chart Tests | helm-test.yaml |
push/PR to main | helm-unittest job (unit tests + example validation + docs check) and helmcov job (template coverage; PR comment with line/branch coverage) |
| Integration Test | chart-test.yml |
push/PR/nightly | Kind-based integration suites |
| Release | release.yml |
after tests pass on main | Changeset version + chart release |
| Update App Version | update-app-version.yml |
workflow_dispatch | Bump appVersion in Chart.yaml |
| Bump ClickHouse Image | bump-clickhouse-image.yml |
weekly/workflow_dispatch | PR moving the ClickHouse server and keeper tags to the newest patch on their LTS line |
- Chart definition:
charts/clickstack/Chart.yaml - Default values:
charts/clickstack/values.yaml - Helper templates:
charts/clickstack/templates/_helpers.tpl - Unit tests:
charts/clickstack/tests/*_test.yaml - Integration suites:
integration-tests/*/ - Example values:
examples/*/values.yaml - Version sync script:
scripts/update-chart-versions.js - Smoke test:
scripts/smoke-test.sh - Makefile:
make setup,make test,make coverage