Skip to content

Commit 187e266

Browse files
committed
improvement(helm): hygiene pass — CI gating, strict values schema, ESO v1 default, ci values
Closes the gaps from a best-practices audit of the chart (template-level conformance was already clean: full label set, 82 unit tests, kubeconform- valid renders): - new Helm Chart workflow gates every chart change: helm lint, the 82 helm-unittest cases, kubeconform validation of default + all-components renders (k8s 1.29 strict, CRD catalog), and a render of all 10 example values files - helm/sim/ci/ values files (chart-testing convention) so the chart lints and templates cleanly out of the box with dummy secrets - values.schema.json declares all 30 top-level keys (16 were invisible) and sets root additionalProperties: false, so top-level typos fail fast - externalSecrets.apiVersion defaults to v1: current ESO releases removed the v1beta1 compatibility path in 2026, so the old default produced rejected manifests on new installs; NOTES/values comments updated - wait-for-postgres init container gets requests/limits (the only container in the chart without them; broke ResourceQuota'd namespaces) - drop the telemetry Prometheus scrape config for app/realtime — neither exposes /metrics, so it was dead config that also rendered a realtime target with realtime disabled - chart 1.2.0 with README upgrade notes
1 parent f0f9870 commit 187e266

14 files changed

Lines changed: 261 additions & 22 deletions

.github/workflows/helm.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Helm Chart
2+
3+
on:
4+
push:
5+
branches: [main, staging, dev]
6+
paths:
7+
- 'helm/sim/**'
8+
- '.github/workflows/helm.yml'
9+
pull_request:
10+
branches: [main, staging, dev]
11+
paths:
12+
- 'helm/sim/**'
13+
- '.github/workflows/helm.yml'
14+
15+
concurrency:
16+
group: helm-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
chart:
24+
name: Lint, test, and validate chart
25+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
26+
timeout-minutes: 15
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Set up Helm
31+
uses: azure/setup-helm@v4
32+
with:
33+
version: v3.16.4
34+
35+
- name: Helm lint
36+
run: helm lint helm/sim --values helm/sim/ci/default-values.yaml
37+
38+
- name: Helm unit tests
39+
run: |
40+
helm plugin install https://github.com/helm-unittest/helm-unittest --version v0.8.2
41+
helm unittest helm/sim
42+
43+
- name: Install kubeconform
44+
run: |
45+
curl -sSL -o /tmp/kubeconform.tar.gz \
46+
https://github.com/yannh/kubeconform/releases/download/v0.6.7/kubeconform-linux-amd64.tar.gz
47+
tar -xzf /tmp/kubeconform.tar.gz -C /tmp kubeconform
48+
49+
- name: Render and validate manifests (default configuration)
50+
run: |
51+
helm template sim helm/sim --namespace sim \
52+
--values helm/sim/ci/default-values.yaml \
53+
| /tmp/kubeconform -strict -summary \
54+
-kubernetes-version 1.29.0 \
55+
-schema-location default \
56+
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'
57+
58+
- name: Render and validate manifests (all components enabled)
59+
run: |
60+
helm template sim helm/sim --namespace sim \
61+
--values helm/sim/ci/full-values.yaml \
62+
| /tmp/kubeconform -strict -summary \
63+
-kubernetes-version 1.29.0 \
64+
-schema-location default \
65+
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'
66+
67+
- name: Render every example values file
68+
run: |
69+
set -euo pipefail
70+
for f in helm/sim/examples/values-*.yaml; do
71+
echo "--- $f"
72+
# Examples intentionally omit secrets (their headers document the
73+
# required --set flags), so supply the CI dummies alongside each.
74+
helm template sim helm/sim --namespace sim \
75+
--values "$f" \
76+
--values helm/sim/ci/default-values.yaml \
77+
--set copilot.postgresql.auth.password=ci-dummy-password \
78+
--set copilot.server.env.AGENT_API_DB_ENCRYPTION_KEY=cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici \
79+
--set copilot.server.env.INTERNAL_API_SECRET=cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici \
80+
--set copilot.server.env.LICENSE_KEY=ci-dummy-license \
81+
--set copilot.server.env.SIM_BASE_URL=https://ci.example.com \
82+
--set copilot.server.env.SIM_AGENT_API_KEY=ci-dummy-agent-key \
83+
--set copilot.server.env.REDIS_URL=redis://ci-redis:6379 \
84+
--set copilot.server.env.OPENAI_API_KEY_1=ci-dummy-openai-key \
85+
--set externalDatabase.password=ci-dummy-password > /dev/null
86+
done

helm/sim/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v2
22
name: sim
33
description: A Helm chart for Sim - the open-source AI workspace where teams build, deploy, and manage AI agents
44
type: application
5-
version: 1.1.0
5+
version: 1.2.0
66
appVersion: "0.6.73"
77
kubeVersion: ">=1.25.0-0"
88
home: https://sim.ai

helm/sim/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,12 @@ kubectl --namespace sim logs deploy/sim-app -c migrations
467467

468468
---
469469

470+
## Upgrading to 1.2.0
471+
472+
* `externalSecrets.apiVersion` now defaults to `"v1"` — current External Secrets Operator releases no longer serve `v1beta1` (removed upstream in 2026). Set `externalSecrets.apiVersion: "v1beta1"` only if you still run ESO < 0.17.
473+
* `values.schema.json` now declares every top-level key and rejects unknown top-level keys, so a typo like `networkPolciy:` fails fast at install time instead of being silently ignored. If an upgrade suddenly fails schema validation, check your values file for stray top-level keys.
474+
* The opt-in telemetry collector no longer ships a Prometheus scrape config for the app/realtime services (they expose no `/metrics` endpoint); OTLP ingestion is unchanged.
475+
470476
## Upgrading to 1.1.0
471477

472478
No action is required for working configurations. Notes:

helm/sim/ci/default-values.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# CI-only values: the minimum required secrets so `helm lint`/`helm template`
2+
# render the DEFAULT configuration. Dummy values — never use in a deployment.
3+
app:
4+
env:
5+
BETTER_AUTH_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
6+
ENCRYPTION_KEY: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
7+
INTERNAL_API_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
8+
CRON_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
9+
10+
postgresql:
11+
auth:
12+
password: "ci-dummy-password"

helm/sim/ci/full-values.yaml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# CI-only values: every optional component enabled so the full template surface
2+
# renders and validates. Dummy values — never use in a deployment.
3+
app:
4+
env:
5+
BETTER_AUTH_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
6+
ENCRYPTION_KEY: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
7+
INTERNAL_API_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
8+
CRON_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
9+
API_ENCRYPTION_KEY: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
10+
11+
postgresql:
12+
auth:
13+
password: "ci-dummy-password"
14+
tls:
15+
enabled: true
16+
17+
certManager:
18+
enabled: true
19+
20+
ingress:
21+
enabled: true
22+
app:
23+
host: ci.example.com
24+
paths: [{ path: /, pathType: Prefix }]
25+
realtime:
26+
host: ci-ws.example.com
27+
paths: [{ path: /, pathType: Prefix }]
28+
tls:
29+
enabled: true
30+
31+
networkPolicy:
32+
enabled: true
33+
34+
autoscaling:
35+
enabled: true
36+
37+
monitoring:
38+
serviceMonitor:
39+
enabled: true
40+
41+
telemetry:
42+
enabled: true
43+
jaeger:
44+
enabled: true
45+
prometheus:
46+
enabled: true
47+
otlp:
48+
enabled: true
49+
50+
sharedStorage:
51+
enabled: true
52+
53+
ollama:
54+
enabled: true
55+
56+
pii:
57+
enabled: true
58+
59+
copilot:
60+
enabled: true
61+
postgresql:
62+
auth:
63+
password: "ci-dummy-password"
64+
server:
65+
env:
66+
AGENT_API_DB_ENCRYPTION_KEY: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
67+
INTERNAL_API_SECRET: "cicicicicicicicicicicicicicicicicicicicicicicicicicicicicicicici"
68+
LICENSE_KEY: "ci-dummy-license"
69+
SIM_BASE_URL: "https://ci.example.com"
70+
SIM_AGENT_API_KEY: "ci-dummy-agent-key"
71+
REDIS_URL: "redis://ci-redis:6379"
72+
OPENAI_API_KEY_1: "ci-dummy-openai-key"

helm/sim/templates/NOTES.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ Your release is named {{ .Release.Name }} in namespace {{ .Release.Namespace }}.
8686

8787
5. Upgrade notes (read before upgrading from a chart version released before this one):
8888

89-
* externalSecrets.apiVersion default is "v1beta1" (was "v1"). v1beta1 is
90-
supported by every ESO release from v0.7+ through current. If you're on
91-
ESO v0.17+ and want the graduated v1 API, set externalSecrets.apiVersion: "v1".
89+
* externalSecrets.apiVersion defaults to "v1". Current ESO releases no
90+
longer serve v1beta1 (the compatibility path was removed in 2026) — set
91+
externalSecrets.apiVersion: "v1beta1" only if you still run ESO < 0.17.
9292
* networkPolicy.egress remains a list of custom egress rules (unchanged).
9393
Cloud-metadata CIDR blocking is now configured via networkPolicy.egressExceptCidrs
9494
(defaults to AWS/GCP/Azure IMDS + ECS task metadata).

helm/sim/templates/external-secret-app.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# - a string: treated as the remoteRef.key (legacy form)
1010
# - a map: passed through as the remoteRef block (e.g. {key, property,
1111
# version, decodingStrategy, conversionStrategy, metadataPolicy})
12-
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1beta1" }}
12+
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1" }}
1313
kind: ExternalSecret
1414
metadata:
1515
name: {{ include "sim.fullname" . }}-app-secrets

helm/sim/templates/external-secret-copilot.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# template rendering if a required key (or any non-empty copilot.server.env key) is
77
# missing a matching remoteRefs.copilot entry, so a misconfiguration surfaces at
88
# `helm template` time instead of a container starting with an empty value.
9-
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1beta1" }}
9+
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1" }}
1010
kind: ExternalSecret
1111
metadata:
1212
name: {{ include "sim.copilot.envSecretName" . }}

helm/sim/templates/external-secret-external-db.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{- if and .Values.externalSecrets.enabled .Values.externalDatabase.enabled .Values.externalSecrets.remoteRefs.externalDatabase.password }}
22
# ExternalSecret for external database password (syncs from external secret managers)
3-
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1beta1" }}
3+
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1" }}
44
kind: ExternalSecret
55
metadata:
66
name: {{ include "sim.fullname" . }}-external-db-secret

helm/sim/templates/external-secret-postgresql.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{- if and .Values.externalSecrets.enabled .Values.postgresql.enabled .Values.externalSecrets.remoteRefs.postgresql.password }}
22
# ExternalSecret for PostgreSQL password (syncs from external secret managers)
3-
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1beta1" }}
3+
apiVersion: external-secrets.io/{{ .Values.externalSecrets.apiVersion | default "v1" }}
44
kind: ExternalSecret
55
metadata:
66
name: {{ include "sim.fullname" . }}-postgresql-secret

0 commit comments

Comments
 (0)