Rework Helm chart and add local dev support - #558
Conversation
Rework the Helm chart around external datastores with two deployment
modes: a stateless Deployment (default) and a SQLite StatefulSet+PVC
mode gated by persistence.enabled, with guardrails preventing unsafe
multi-replica/autoscaling combinations.
Add HTTP /health and /health/ready probes, ConfigMap-rendered
config.yaml with ${VAR} expansion, chart or existing Secret via
envFrom, distroless-matched securityContext, plus Ingress, HPA, PDB,
NetworkPolicy, ServiceMonitor and config/secret checksum auto-reload.
Add CI workflows to lint, template, and kubeconform-validate the chart
and to publish it to the Docker Hub OCI registry on helm-v* tags.
Drop the previous Bitnami redis subchart and Gateway API HTTPRoute in
favor of external-only dependencies and Ingress-based routing.
Deploy a stdlib-only OpenAI-compatible mock upstream (ConfigMap-mounted Python server) via `make kind-up`, and point the dev OpenAI provider at it (OPENAI_BASE_URL) so /v1/models and /v1/chat/completions work end-to-end in kind without real provider credentials. Extends CI kubeconform validation and dev docs accordingly.
📝 WalkthroughWalkthroughThe PR replaces the legacy Helm chart with ChangesHelm chart foundation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/helm-ci.yml:
- Around line 82-86: Add a no-values helm template validation before the
existing values-file loop in the workflow, piping the default render through
kubeconform with the same strict, missing-schema, and summary options. Keep the
current named-values validation loop unchanged.
- Line 29: Pin the actions at lines 29, 34, 55, 64, and 67 to their reviewed
full commit SHAs instead of mutable version tags, while preserving each original
version tag in an adjacent comment for maintenance.
- Around line 73-76: Update the kubeconform installation steps around the curl
download and tar extraction to download the release CHECKSUMS file, verify
kubeconform-linux-amd64.tar.gz against its expected checksum, and only extract
and install after verification succeeds. Keep the existing version and asset
names consistent.
In @.github/workflows/helm-release.yml:
- Around line 24-25: Harden the release workflow by pinning both
actions/checkout and azure/setup-helm to immutable commit SHAs instead of
mutable version tags, and update the Docker login step to receive
DOCKER_USERNAME and DOCKERHUB_TOKEN through its env block rather than
interpolating secrets directly in the run script; preserve the existing
metadata-step environment handling.
- Around line 27-30: Update the version value in the “Set up Helm” workflow step
to the latest supported Helm v3.x patch release, replacing the outdated v3.16.3
pin while preserving the existing azure/setup-helm@v4 action configuration.
In `@deploy/helm/gomodel/Chart.yaml`:
- Around line 7-8: Replace the "latest" value in Chart.yaml’s appVersion with
the concrete released GoModel version this chart was tested against, and update
that pinned version for every subsequent chart release so default image tags and
version labels remain meaningful.
In `@deploy/helm/gomodel/templates/_helpers.tpl`:
- Around line 116-127: Document the probe-path limitation in the comment for the
gomodel.basePath helper, explicitly stating that only env.BASE_PATH and
config.server.base_path are supported sources; also update the README.md
probe-path documentation to state the same restriction and clarify that
BASE_PATH supplied through extraEnv or secrets.data is not honored.
In `@deploy/helm/gomodel/templates/_pod.tpl`:
- Around line 54-99: Update the port configuration around the pod template’s
http container port so it is derived from the configured application port rather
than hardcoded to 8080. Compute the resolved port once using the existing
configuration values and reuse that helper for containerPort, the named http
Service port, and any corresponding Service targetPort, while preserving the
named-port references used by the probes.
In `@deploy/helm/gomodel/templates/pdb.yaml`:
- Around line 10-13: Update the PodDisruptionBudget condition around
podDisruptionBudget.maxUnavailable and minAvailable to detect explicitly
configured zero values, not only truthy values. Reject configurations where both
fields are set together or both are null/nil, while rendering exactly one
configured field, including maxUnavailable: 0.
In `@deploy/helm/gomodel/values.schema.json`:
- Around line 109-117: Update the secrets.data schema within the secrets
properties to define its additional properties as strings, while preserving the
object type and existing secrets validation. This must reject nested objects,
booleans, and other non-string values during schema validation.
In `@deploy/local/kind-cluster.yaml`:
- Around line 4-6: Update the comments in the local kind cluster configuration,
including the comment near extraPortMappings, to describe gateway access through
the NodePort mapping from container port 30080 to host port 8080. Remove the
stale claim that Skaffold port-forwarding is required and that the mappings are
reserved for an optional 80/443 Ingress controller.
In `@docs/dev/local-kubernetes.md`:
- Line 5: Update the external links in docs/dev/local-kubernetes.md, including
the Helm chart reference and the deploy/local/values.yaml reference, to absolute
GitHub URLs targeting the main branch; preserve the existing link text and
destinations.
In `@Makefile`:
- Around line 89-91: Update the comment above the undeploy-k8s target to clarify
that skaffold delete removes only the Helm release, while dependency manifests
remain until make kind-down; do not change the command unless explicitly adding
dependency deletion to this target.
- Around line 65-68: Update the kind create command in the kind-up target to
pass KIND_CLUSTER via the kind cluster name option, ensuring newly created
clusters and contexts match the existing kind-$(KIND_CLUSTER) references.
In `@skaffold.yaml`:
- Around line 3-11: Correct the local gateway access comments in the skaffold
configuration: remove the claim that make dev-k8s provides Skaffold
port-forwarding and state that access uses the kind NodePort mapping 30080 to
8080, unless an explicit portForward configuration is added.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2a9b35ff-1f14-4d1c-a564-4eced617b880
⛔ Files ignored due to path filters (1)
helm/Chart.lockis excluded by!**/*.lock
📒 Files selected for processing (46)
.dockerignore.github/workflows/helm-ci.yml.github/workflows/helm-release.yml.pre-commit-config.yamlDockerfile.devMakefiledeploy/helm/gomodel/.helmignoredeploy/helm/gomodel/Chart.yamldeploy/helm/gomodel/README.mddeploy/helm/gomodel/ci/ingress-tls-values.yamldeploy/helm/gomodel/ci/sqlite-persistent-values.yamldeploy/helm/gomodel/ci/stateless-values.yamldeploy/helm/gomodel/templates/NOTES.txtdeploy/helm/gomodel/templates/_helpers.tpldeploy/helm/gomodel/templates/_pod.tpldeploy/helm/gomodel/templates/configmap.yamldeploy/helm/gomodel/templates/deployment.yamldeploy/helm/gomodel/templates/hpa.yamldeploy/helm/gomodel/templates/ingress.yamldeploy/helm/gomodel/templates/networkpolicy.yamldeploy/helm/gomodel/templates/pdb.yamldeploy/helm/gomodel/templates/secret.yamldeploy/helm/gomodel/templates/service.yamldeploy/helm/gomodel/templates/serviceaccount.yamldeploy/helm/gomodel/templates/servicemonitor.yamldeploy/helm/gomodel/templates/statefulset.yamldeploy/helm/gomodel/values.schema.jsondeploy/helm/gomodel/values.yamldeploy/local/deps.yamldeploy/local/kind-cluster.yamldeploy/local/mockllm.yamldeploy/local/values.yamldocs/DEVELOPMENT.mddocs/dev/local-kubernetes.mdhelm/Chart.yamlhelm/README.mdhelm/templates/NOTES.txthelm/templates/_helpers.tplhelm/templates/configmap.yamlhelm/templates/deployment.yamlhelm/templates/gateway.yamlhelm/templates/secret.yamlhelm/templates/servicemonitor.yamlhelm/values.schema.jsonhelm/values.yamlskaffold.yaml
💤 Files with no reviewable changes (11)
- helm/templates/secret.yaml
- helm/templates/gateway.yaml
- helm/Chart.yaml
- helm/templates/deployment.yaml
- helm/templates/NOTES.txt
- helm/templates/servicemonitor.yaml
- helm/templates/configmap.yaml
- helm/templates/_helpers.tpl
- helm/README.md
- helm/values.yaml
- helm/values.schema.json
| name: Lint and template | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow file =="
if [ -f .github/workflows/helm-ci.yml ]; then
nl -ba .github/workflows/helm-ci.yml | sed -n '1,110p'
else
echo "missing .github/workflows/helm-ci.yml"
fi
echo
echo "== action uses lines =="
rg -n 'uses:\s*[^#\s]+' .github/workflows/helm-ci.yml || trueRepository: ENTERPILOT/GoModel
Length of output: 216
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow file =="
if [ -f .github/workflows/helm-ci.yml ]; then
awk '{printf "%7d %s\n", NR, $0}' .github/workflows/helm-ci.yml | sed -n '1,110p'
else
echo "missing .github/workflows/helm-ci.yml"
fi
echo
echo "== action uses lines =="
grep -nE 'uses:\s*[^#\s]+' .github/workflows/helm-ci.yml || trueRepository: ENTERPILOT/GoModel
Length of output: 3983
Pin every GitHub Action to a full commit SHA.
Mutable action tags such as actions/checkout@v7, azure/setup-helm@v4, and helm/chart-testing-action@v2 can be retargeted to execute different code. Pin lines 29, 34, 55, 64, and 67 to reviewed full commit SHAs, and keep the version tag in a comment for maintenance.
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 29-31: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 29-29: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/helm-ci.yml at line 29, Pin the actions at lines 29, 34,
55, 64, and 67 to their reviewed full commit SHAs instead of mutable version
tags, while preserving each original version tag in an adjacent comment for
maintenance.
Source: Linters/SAST tools
| curl -sSL -o /tmp/kubeconform.tar.gz \ | ||
| https://github.com/yannh/kubeconform/releases/download/v0.6.7/kubeconform-linux-amd64.tar.gz | ||
| tar -xzf /tmp/kubeconform.tar.gz -C /tmp | ||
| sudo mv /tmp/kubeconform /usr/local/bin/ |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
gh api repos/yannh/kubeconform/releases/tags/v0.6.7 \
--jq '.assets[].name'Repository: ENTERPILOT/GoModel
Length of output: 470
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
URL="https://github.com/yannh/kubeconform/releases/download/v0.6.7/kubeconform-linux-amd64.tar.gz"
printf 'asset URL reachable: '
curl -Ifs "$URL" > /tmp/kubeconform-check-url-reach.txt
curl -Ifs "$URL" | sed -n '1p'
printf '\nchecksum file URL reachable: '
GH="https://github.com/yannh/kubeconform/releases/download/v0.6.7/CHECKSUMS"
curl -Ifs "$GH" > /tmp/kubeconform-check-checksum-url.txt
curl -Ifs "$GH" | sed -n '1p'
printf '\nchecksum file first lines:\n'
curl -sf "$GH" | sed -n '1,20p'
printf '\nlocal workflow lines:\n'
sed -n '60,85p' .github/workflows/helm-ci.ymlRepository: ENTERPILOT/GoModel
Length of output: 1269
Verify the kubeconform checksum before installing.
This script downloads the release asset directly to /tmp, extracts it, and moves it onto PATH without comparing it against the upstream CHECKSUMS checksum file. Add a checksum verification step for kubeconform-linux-amd64.tar.gz before extraction.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/helm-ci.yml around lines 73 - 76, Update the kubeconform
installation steps around the curl download and tar extraction to download the
release CHECKSUMS file, verify kubeconform-linux-amd64.tar.gz against its
expected checksum, and only extract and install after verification succeeds.
Keep the existing version and asset names consistent.
| for f in deploy/helm/gomodel/ci/*-values.yaml deploy/local/values.yaml; do | ||
| echo "Validating manifests rendered with $f" | ||
| helm template ci deploy/helm/gomodel -f "$f" \ | ||
| | kubeconform -strict -ignore-missing-schemas -summary | ||
| done |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Validate the default chart render with kubeconform.
The workflow renders default values at line 45, but only named value files enter the kubeconform pipeline here. Add a no-values helm template validation before the loop. Otherwise, an invalid default-only manifest can pass CI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/helm-ci.yml around lines 82 - 86, Add a no-values helm
template validation before the existing values-file loop in the workflow, piping
the default render through kubeconform with the same strict, missing-schema, and
summary options. Keep the current named-values validation loop unchanged.
| - name: Checkout | ||
| uses: actions/checkout@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
Harden the checkout/setup-helm pinning and secret usage.
Two independent hardening gaps:
actions/checkout@v7(line 25) andazure/setup-helm@v4(line 28) are pinned to mutable tags, not commit SHAs. A compromised or re-pointed tag would run arbitrary code in this release pipeline.secrets.DOCKER_USERNAME/secrets.DOCKERHUB_TOKEN(lines 49-51) are interpolated directly intorun:script text instead of passed throughenv:, unlike theDOCKER_USERNAMEhandling in the earlier "Resolve chart metadata" step (lines 38-39). Passing${{ }}expressions throughenv:is the recommended pattern to avoid the value being spliced directly into the shell script.
🔒 Proposed fix for the login step
- name: Login to Docker Hub (OCI)
+ env:
+ DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
+ DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
- echo "${{ secrets.DOCKERHUB_TOKEN }}" \
+ echo "${DOCKERHUB_TOKEN}" \
| helm registry login registry-1.docker.io \
- --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin
+ --username "${DOCKER_USERNAME}" --password-stdinAlso applies to: 28-28, 47-51
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 24-25: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 25-25: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/helm-release.yml around lines 24 - 25, Harden the release
workflow by pinning both actions/checkout and azure/setup-helm to immutable
commit SHAs instead of mutable version tags, and update the Docker login step to
receive DOCKER_USERNAME and DOCKERHUB_TOKEN through its env block rather than
interpolating secrets directly in the run script; preserve the existing
metadata-step environment handling.
Source: Linters/SAST tools
| - name: Set up Helm | ||
| uses: azure/setup-helm@v4 | ||
| with: | ||
| version: v3.16.3 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
What is the latest Helm v3 patch release?
💡 Result:
The latest Helm v3 patch release is v3.21.3, which was released on July 9, 2026 [1][2]. Helm v3 is currently in support mode, receiving only bug and security fixes [3]. The next scheduled patch release for Helm v3 is v3.21.4, planned for August 12, 2026 [1][2].
Citations:
- 1: https://github.com/helm/helm/releases/tag/v3.21.3
- 2: https://github.com/helm/helm/releases
- 3: https://github.com/helm/helm
Bump the pinned Helm version.
version: v3.16.3 is several patch releases behind current Helm v3.x patch releases. Bump to the latest supported v3.x patch version to pick up fixes.
🧰 Tools
🪛 zizmor (1.28.0)
[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/helm-release.yml around lines 27 - 30, Update the version
value in the “Set up Helm” workflow step to the latest supported Helm v3.x patch
release, replacing the outdated v3.16.3 pin while preserving the existing
azure/setup-helm@v4 action configuration.
| # Access to the gateway is provided by Skaffold's port-forward (localhost:8080), | ||
| # so no NodePort/Ingress is required for the default workflow. The extra port | ||
| # mappings below are kept ready for an optional Ingress controller on 80/443. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd skaffold.yaml --exec cat -n {}Repository: ENTERPILOT/GoModel
Length of output: 2113
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- deploy/local/kind-cluster.yaml ---\n'
cat -n deploy/local/kind-cluster.yaml
printf '\n--- deploy/local/values.yaml relevant service config ---\n'
rg -n -C 4 'service:|type:|nodePort:|port:' deploy/local/values.yaml || true
printf '\n--- docs/dev/local-kubernetes.md relevant gateway text ---\n'
rg -n -C 3 'localhost:8080|NodePort|skaffold' docs/dev/local-kubernetes.md || trueRepository: ENTERPILOT/GoModel
Length of output: 247
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- deploy/local/kind-cluster.yaml ---'
cat -n deploy/local/kind-cluster.yaml
printf '%s\n' ''
printf '%s\n' '--- deploy/local/values.yaml relevant service config ---'
rg -n -C 4 'service:|type:|nodePort:|port:' deploy/local/values.yaml || true
printf '%s\n' ''
printf '%s\n' '--- docs/dev/local-kubernetes.md relevant gateway text ---'
rg -n -C 3 'localhost:8080|NodePort|skaffold' docs/dev/local-kubernetes.md || trueRepository: ENTERPILOT/GoModel
Length of output: 4512
Fix the stale comment describing the local port mapping.
extraPortMappings maps containerPort: 30080 to hostPort: 8080, which matches service.type: NodePort and service.nodePort: 30080 in deploy/local/values.yaml. The gateway is reachable through this NodePort even without skaffold dev; update the comments at lines 4-6 and 12 to describe the NodePort mapping instead of Ingress/80-443.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@deploy/local/kind-cluster.yaml` around lines 4 - 6, Update the comments in
the local kind cluster configuration, including the comment near
extraPortMappings, to describe gateway access through the NodePort mapping from
container port 30080 to host port 8080. Remove the stale claim that Skaffold
port-forwarding is required and that the mappings are reserved for an optional
80/443 Ingress controller.
|
|
||
| Develop GoModel against a local [kind](https://kind.sigs.k8s.io/) cluster using | ||
| [Skaffold](https://skaffold.dev/) for a build → deploy → watch loop. The app is | ||
| deployed through the same production [Helm chart](../../deploy/helm/gomodel) with dev overrides, |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use absolute GitHub URLs for links outside the docs/ tree.
Line 5 links to ../../deploy/helm/gomodel and line 103 links to ../../deploy/local/values.yaml. Both paths point outside the docs/ tree. Replace both with absolute GitHub URLs (e.g. https://github.com/ENTERPILOT/GoModel/blob/main/deploy/helm/gomodel).
Based on learnings, in the GoModel repo all Markdown files under the docs/ directory (including ADRs) that link to files outside the docs/ tree must use absolute GitHub URLs (e.g., https://github.com/ENTERPILOT/GoModel/blob/main/internal/...) instead of relative paths like ../../internal/....
Also applies to: 103-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/dev/local-kubernetes.md` at line 5, Update the external links in
docs/dev/local-kubernetes.md, including the Helm chart reference and the
deploy/local/values.yaml reference, to absolute GitHub URLs targeting the main
branch; preserve the existing link text and destinations.
Source: Learnings
| kind-up: | ||
| @kind get clusters | grep -qx "$(KIND_CLUSTER)" \ | ||
| || kind create cluster --config deploy/local/kind-cluster.yaml | ||
| @kubectl cluster-info --context kind-$(KIND_CLUSTER) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Makefile KIND references:"
if [ -f Makefile ]; then
nl -ba Makefile | sed -n '1,110p'
else
fd -a 'Makefile' . | sed -n '1,20p'
fi
echo
echo "Search KIND_CLUSTER and cluster-info/create commands:"
rg -n "KIND_CLUSTER|kind create cluster|cluster-info|kind-gomodel-dev|kind-\\$\\{KIND_CLUSTER\\}|kind-\\$\\(KIND_CLUSTER\\)" .Repository: ENTERPILOT/GoModel
Length of output: 222
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Makefile candidates:"
find . -name Makefile -o -name makefile -o -name GNUmakefile | sort
echo
echo "Relevant Makefile content:"
if [ -f Makefile ]; then
awk '{printf "%6d\t%s\n", NR, $0}' Makefile | sed -n '1,120p'
fi
echo
echo "Search KIND_CLUSTER and kind commands:"
rg -n "KIND_CLUSTER|kind create cluster|cluster-info|kind-gomodel-dev|kind-\\$\\(KIND_CLUSTER\\)" -S . || true
echo
echo "Kind documentation/name semantics from local installed docs:"
if command -v kind >/dev/null 2>&1; then
kind version 2>&1 || true
kind create cluster --help 2>&1 | grep -A80 "^Usage:" || true
else
echo "kind binary not installed"
fiRepository: ENTERPILOT/GoModel
Length of output: 7004
🌐 Web query:
kind create cluster --name default cluster name kubectl config set-context kind-name
💡 Result:
When creating a cluster using kind, the tool automatically manages the Kubernetes configuration file (typically located at ~/.kube/config) and creates a context for you [1][2]. To create a cluster with a specific name, use the --name flag: kind create cluster --name By default, when you create a cluster, kind assigns it a context name prefixed with "kind-". For example, if you create a cluster with --name my-cluster, the resulting context name in your kubeconfig will be kind-my-cluster [3]. If you need to manually set or switch your kubectl context to this cluster, use the following command: kubectl config set-context kind- To verify or switch to the context, you can also use: kubectl config use-context kind- Kind automatically sets the current context to the new cluster upon creation, so you generally do not need to run these commands immediately after creating the cluster [3]. If your context is not found, ensure that you are running kubectl as the same user that created the kind cluster, as the kubeconfig file is written based on the user's home directory [4].
Citations:
- 1: https://kind.sigs.k8s.io/docs/user/quick-start
- 2: https://kind.sigs.k8s.io/docs/user/quick-start/
- 3: kubectl config set-context does not persist kubernetes-sigs/kind#2572
- 4: No context found by
kubectlwhen starting cluster withkind create clusterkubernetes-sigs/kind#2174
Pass KIND_CLUSTER to kind create cluster.
The create command omits --name "$(KIND_CLUSTER)". If no gomodel-dev cluster exists, kind create cluster creates the default kind cluster and context. The following commands then use kind-gomodel-dev, so make kind-up fails on new setups.
Proposed fix
`@kind` get clusters | grep -qx "$(KIND_CLUSTER)" \
- || kind create cluster --config deploy/local/kind-cluster.yaml
+ || kind create cluster --name "$(KIND_CLUSTER)" --config deploy/local/kind-cluster.yaml📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| kind-up: | |
| @kind get clusters | grep -qx "$(KIND_CLUSTER)" \ | |
| || kind create cluster --config deploy/local/kind-cluster.yaml | |
| @kubectl cluster-info --context kind-$(KIND_CLUSTER) | |
| kind-up: | |
| `@kind` get clusters | grep -qx "$(KIND_CLUSTER)" \ | |
| || kind create cluster --name "$(KIND_CLUSTER)" --config deploy/local/kind-cluster.yaml | |
| `@kubectl` cluster-info --context kind-$(KIND_CLUSTER) |
🧰 Tools
🪛 checkmake (0.3.2)
[warning] 65-65: Target body for "kind-up" exceeds allowed length of 5 lines (9).
(maxbodylength)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 65 - 68, Update the kind create command in the kind-up
target to pass KIND_CLUSTER via the kind cluster name option, ensuring newly
created clusters and contexts match the existing kind-$(KIND_CLUSTER)
references.
| # Tear down the deployed release and dependencies. | ||
| undeploy-k8s: | ||
| skaffold delete --kube-context kind-$(KIND_CLUSTER) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Correct the teardown scope description.
skaffold delete removes the Helm release only. It does not remove the dependency manifests applied by kind-up. State that dependencies remain until make kind-down, or delete them explicitly in this target.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 89 - 91, Update the comment above the undeploy-k8s
target to clarify that skaffold delete removes only the Helm release, while
dependency manifests remain until make kind-down; do not change the command
unless explicitly adding dependency deletion to this target.
| # make kind-up # one-time: create the kind cluster + deploy dependencies | ||
| # make dev-k8s # build + deploy + watch + port-forward (skaffold dev) | ||
| # make deploy-k8s # one-shot build + deploy (skaffold run) | ||
| # make undeploy-k8s # remove the release (skaffold delete) | ||
| # | ||
| # The in-cluster dependencies (Redis, PostgreSQL, MongoDB) are deployed by | ||
| # `make kind-up` (deploy/local/deps.yaml), so they persist across app redeploys. | ||
| # The gateway is reachable at http://localhost:8080 (Skaffold port-forward and, | ||
| # as a fallback, the kind NodePort mapping 30080 -> 8080). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the local access instructions.
This configuration has no portForward block. make dev-k8s does not create Skaffold port forwarding. State that access uses the kind NodePort mapping, or add an explicit portForward configuration.
Also applies to: 44-46
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skaffold.yaml` around lines 3 - 11, Correct the local gateway access comments
in the skaffold configuration: remove the claim that make dev-k8s provides
Skaffold port-forwarding and state that access uses the kind NodePort mapping
30080 to 8080, unless an explicit portForward configuration is added.
Confidence Score: 3/5Not safe to merge: supported deployment configuration can break application availability, and the release workflow trusts mutable third-party code before registry publishing. The reproduced failures affect independent paths: application routing for listener-port overrides, connectivity to documented external datastores when network isolation is enabled, and integrity of the credentialed chart-release process. Files Needing Attention: deploy/helm/gomodel/templates/_pod.tpl, deploy/helm/gomodel/templates/networkpolicy.yaml, and .github/workflows/helm-release.yml
What T-Rex did
Comments Outside Diff (3)
Reviews (1): Last reviewed commit: "Merge branch 'main' into feature/helm-re..." | Re-trigger Greptile |
| {{- end }} | ||
| ports: | ||
| - name: http | ||
| containerPort: 8080 |
There was a problem hiding this comment.
Helm routing ignores the configured listener port
config.server.port and env.PORT both change the application's listener port, but this template always declares the named http container port as 8080. The Service targets http and all HTTP probes use it, so a release configured to listen on any other port receives probes and Service traffic on 8080 instead. Derive the named container port from the effective listener-port configuration and add non-8080 render coverage.
Artifacts
Focused Helm port mismatch check source
- Shell harness copied the focused Go check into the config package and executed it for default and configured port scenarios; it provides the repeatable verification entry point.
Focused Helm port mismatch Go check source
- Go source executes the real configuration loader for config-file and environment port inputs and evaluates the implicated Helm pod and Service template invariants; it confirms the mismatch condition.
Default 8080 port verification output
- Executed default-port run from `/home/user/repo` exited 0 and shows application configuration plus named-port, probe, and Service target all resolve to 8080; the default case is consistent.
Configured non-8080 port verification output
- Executed configured-port run from `/home/user/repo` exited 0 and shows application ports 19091 and 19092 while the named port, probes, and Service target remain 8080; the mismatch is confirmed.
| egress: | ||
| # DNS resolution. | ||
| - to: [] | ||
| ports: | ||
| - port: 53 | ||
| protocol: UDP | ||
| - port: 53 | ||
| protocol: TCP | ||
| # Outbound HTTPS to provider APIs and external datastores. | ||
| - to: [] | ||
| ports: | ||
| - port: 443 | ||
| protocol: TCP |
There was a problem hiding this comment.
Enabled NetworkPolicy blocks datastore connections
When networkPolicy.enabled=true, the default egress allowlist permits DNS and HTTPS only. The documented stateless deployment can use PostgreSQL, Redis, and MongoDB, but TCP ports 5432, 6379, and 27017 are not allowed, so those configured backends cannot connect unless every installation supplies matching extraEgress rules. Include the documented datastore ports in the defaults or derive the rules from the selected backend configuration.
Artifacts
Helm-independent NetworkPolicy render and egress evaluator source
- Authored executable evaluator that merges the chart defaults with stateless values, verifies the relevant template guards, renders the literal egress rules, and checks datastore ports; it provides the reproducible check.
Baseline stateless render with NetworkPolicy disabled
- Executed `python3 trex-artifacts/networkpolicy-stateless-check.py` in `/home/user/repo`; stateless defaults leave NetworkPolicy disabled and render no NetworkPolicy, establishing the default-enablement semantics.
Enabled NetworkPolicy render blocks PostgreSQL Redis and MongoDB
- Executed `python3 trex-artifacts/networkpolicy-stateless-check.py --enable-policy` in `/home/user/repo`; the rendered egress rules expose only ports 53 and 443 and the check reports TCP 5432, 6379, and 27017 blocked, confirming the defect.
| uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up Helm | ||
| uses: azure/setup-helm@v4 |
There was a problem hiding this comment.
Release setup action is not immutable
azure/setup-helm@v4 is a mutable tag and runs before this job reads Docker Hub credentials, authenticates to the registry, and publishes the OCI chart. Pin the action to the reviewed full commit SHA, retaining a version comment if useful, so a moved or compromised tag cannot execute unreviewed code in the release job.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Artifacts
Focused workflow pinning assertion source
- Python assertion source executed against the workflow and a SHA-pinned comparison fixture; it checks the action ref format and exact credential/push ordering, with the takeaway that the check is reproducible.
Current workflow check showing mutable Helm action tag
- Captured execution of the focused assertion on the current repository workflow; it reports `v4` at line 28 as a non-SHA tag before Docker credential use and OCI publishing, confirming the issue.
- Captured execution of the same assertion against a same-scope SHA-pinned workflow copy; it classifies the 40-character ref as immutable while preserving the workflow ordering, showing the required remediation shape.
This pull request introduces a comprehensive Helm chart for GoModel, along with a local Kubernetes development workflow using kind and Skaffold. It adds all necessary Helm templates, CI/CD automation for chart linting and publishing, and Makefile targets for local cluster management. The changes enable streamlined deployment, testing, and packaging of GoModel on Kubernetes, supporting both stateless (multi-replica) and persistent (SQLite) modes.
The most important changes are:
Helm Chart Introduction and Structure:
deploy/helm/gomodel, including templates, example values, documentation, and helper templates to support flexible, production-grade Kubernetes deployments. (deploy/helm/gomodel/Chart.yaml,README.md,templates/,ci/, etc.) [1] [2] [3] [4] [5] [6] [7] [8]CI/CD Automation for Helm:
.github/workflows/helm-ci.yml), and for packaging and publishing the chart to Docker Hub as an OCI artifact on tagged releases (.github/workflows/helm-release.yml). [1] [2]Local Kubernetes Development Workflow:
Dockerfile.dev, Makefile targets for cluster management (kind-up,kind-down,dev-k8s, etc.), and configuration for local dependencies and manifests. [1] [2] [3] [4]Configuration and Pre-commit Updates:
.pre-commit-config.yamlto match the new Helm chart directory structure for YAML checks.Repository Structure Adjustments:
helm/withdeploy/helm/, adding.dockerignoreentries, and updating deployment-related files.These changes provide a robust foundation for deploying, testing, and maintaining GoModel on Kubernetes in both development and production environments.
Summary by CodeRabbit
New Features
Documentation
Chores