-
-
Notifications
You must be signed in to change notification settings - Fork 75
Rework Helm chart and add local dev support #558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
091da8b
c47fc28
ea8a9b3
4f4b67c
17d225d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| name: Helm Chart CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - "deploy/helm/**" | ||
| - "deploy/local/**" | ||
| - ".github/workflows/helm-ci.yml" | ||
| pull_request: | ||
| branches: [main] | ||
| paths: | ||
| - "deploy/helm/**" | ||
| - "deploy/local/**" | ||
| - ".github/workflows/helm-ci.yml" | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| lint-test: | ||
| name: Lint and template | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up Helm | ||
| uses: azure/setup-helm@v4 | ||
| with: | ||
| version: v3.16.3 | ||
|
|
||
| - name: Helm lint (strict) | ||
| run: helm lint --strict deploy/helm/gomodel | ||
|
|
||
| # Render every example value set to catch templating regressions that lint misses. | ||
| - name: Helm template (all value sets) | ||
| run: | | ||
| set -euo pipefail | ||
| helm template ci deploy/helm/gomodel > /dev/null | ||
| for f in deploy/helm/gomodel/ci/*-values.yaml; do | ||
| echo "Rendering with $f" | ||
| helm template ci deploy/helm/gomodel -f "$f" > /dev/null | ||
| done | ||
|
|
||
| - name: Helm template (local dev values) | ||
| run: helm template ci deploy/helm/gomodel -f deploy/local/values.yaml > /dev/null | ||
|
|
||
| - name: Set up chart-testing | ||
| uses: helm/chart-testing-action@v2 | ||
|
|
||
| - name: Run chart-testing (lint) | ||
| run: ct lint --charts deploy/helm/gomodel --validate-maintainers=false --target-branch ${{ github.event.repository.default_branch }} | ||
|
|
||
| kubeconform: | ||
| name: Validate against Kubernetes schemas | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up Helm | ||
| uses: azure/setup-helm@v4 | ||
| with: | ||
| version: v3.16.3 | ||
|
|
||
| - name: Install kubeconform | ||
| run: | | ||
| 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/ | ||
|
Comment on lines
+73
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 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 🤖 Prompt for AI Agents |
||
|
|
||
| # ServiceMonitor is a CRD, so skip resources kubeconform can't resolve. | ||
| - name: Render and validate manifests | ||
| run: | | ||
| set -euo pipefail | ||
| 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 | ||
|
Comment on lines
+82
to
+86
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 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 🤖 Prompt for AI Agents |
||
|
|
||
| - name: Validate local dev dependency manifests | ||
| run: | | ||
| kubeconform -strict -ignore-missing-schemas -summary \ | ||
| deploy/local/deps.yaml deploy/local/mockllm.yaml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| name: Helm Chart Release | ||
|
|
||
| # Publishes the GoModel Helm chart to the Docker Hub OCI registry. | ||
| # Trigger with a chart tag (decoupled from application releases), e.g. helm-v0.1.0, | ||
| # or run manually. The pushed chart version is read from Chart.yaml. | ||
| on: | ||
| push: | ||
| tags: | ||
| - "helm-v*" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: helm-release-${{ github.ref_name }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| release: | ||
| name: Package and push chart | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v7 | ||
|
Comment on lines
+24
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win Harden the checkout/setup-helm pinning and secret usage. Two independent hardening gaps:
🔒 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 AgentsSource: Linters/SAST tools |
||
|
|
||
| - name: Set up Helm | ||
| uses: azure/setup-helm@v4 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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! ArtifactsFocused workflow pinning assertion source
Current workflow check showing mutable Helm action tag
|
||
| with: | ||
| version: v3.16.3 | ||
|
Comment on lines
+27
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win 🧩 Analysis chain🌐 Web query:
💡 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:
Bump the pinned Helm version.
🧰 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 |
||
|
|
||
| - name: Lint chart | ||
| run: helm lint --strict deploy/helm/gomodel | ||
|
|
||
| - name: Resolve chart metadata | ||
| id: meta | ||
| shell: bash | ||
| env: | ||
| DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | ||
| run: | | ||
| version="$(helm show chart deploy/helm/gomodel | awk '/^version:/ {print $2}')" | ||
| { | ||
| echo "version=${version}" | ||
| echo "registry=registry-1.docker.io/${DOCKER_USERNAME}" | ||
| } >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Login to Docker Hub (OCI) | ||
| run: | | ||
| echo "${{ secrets.DOCKERHUB_TOKEN }}" \ | ||
| | helm registry login registry-1.docker.io \ | ||
| --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin | ||
|
|
||
| - name: Package chart | ||
| run: helm package deploy/helm/gomodel --destination "${RUNNER_TEMP}" | ||
|
|
||
| - name: Push chart to OCI registry | ||
| run: | | ||
| helm push \ | ||
| "${RUNNER_TEMP}/gomodel-${{ steps.meta.outputs.version }}.tgz" \ | ||
| "oci://${{ steps.meta.outputs.registry }}" | ||
|
|
||
| - name: Logout | ||
| if: always() | ||
| run: helm registry logout registry-1.docker.io || true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Development Dockerfile for the local Kubernetes (kind + Skaffold) workflow. | ||
| # Optimized for fast, repeated native-arch rebuilds — it skips cross-compilation | ||
| # and symbol stripping used by the production Dockerfile. Do NOT use for releases. | ||
| FROM golang:1.26.4-alpine3.23 AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| RUN apk add --no-cache ca-certificates | ||
|
|
||
| # Cache dependencies separately from source for fast incremental builds. | ||
| COPY go.mod go.sum ./ | ||
| RUN go mod download | ||
|
|
||
| COPY . . | ||
| # Build cache mounts keep incremental rebuilds quick under Skaffold. | ||
| RUN --mount=type=cache,target=/root/.cache/go-build \ | ||
| --mount=type=cache,target=/go/pkg/mod \ | ||
| CGO_ENABLED=0 go build -o /gomodel ./cmd/gomodel | ||
|
|
||
| RUN mkdir -p /app/.cache /app/data && touch /app/.cache/.keep /app/data/.keep | ||
|
|
||
| # Same distroless runtime as production for parity. | ||
| FROM gcr.io/distroless/static-debian12:nonroot | ||
|
|
||
| COPY --from=builder /gomodel /gomodel | ||
| COPY --from=builder /app/config/*.yaml /app/config/ | ||
| COPY --from=builder --chown=65532:65532 /app/.cache /app/.cache | ||
| COPY --from=builder --chown=65532:65532 /app/data /app/data | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| EXPOSE 8080 | ||
|
|
||
| ENTRYPOINT ["/gomodel"] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||||||||||||||
| .PHONY: all build run demo clean tidy test test-race test-dashboard test-e2e test-integration test-contract test-all lint lint-fix fix fix-check record-api swagger docs-openapi install-tools perf-check perf-bench infra image seed-demo-data | ||||||||||||||||||
| .PHONY: all build run demo clean tidy test test-race test-dashboard test-e2e test-integration test-contract test-all lint lint-fix fix fix-check record-api swagger docs-openapi install-tools perf-check perf-bench infra image seed-demo-data kind-up kind-down dev-k8s deploy-k8s undeploy-k8s | ||||||||||||||||||
|
|
||||||||||||||||||
| all: build | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -55,6 +55,41 @@ image: | |||||||||||||||||
| seed-demo-data: | ||||||||||||||||||
| bash tools/seed-demo-data.sh | ||||||||||||||||||
|
|
||||||||||||||||||
| # --------------------------------------------------------------------------- | ||||||||||||||||||
| # Local Kubernetes development (kind + Skaffold) | ||||||||||||||||||
| # See docs/dev/local-kubernetes.md | ||||||||||||||||||
| # --------------------------------------------------------------------------- | ||||||||||||||||||
| KIND_CLUSTER ?= gomodel-dev | ||||||||||||||||||
|
|
||||||||||||||||||
| # Create the local kind cluster and deploy in-cluster dependencies (idempotent). | ||||||||||||||||||
| 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) | ||||||||||||||||||
|
Comment on lines
+65
to
+68
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 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:
💡 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:
Pass The create command omits 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
Suggested change
🧰 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 |
||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) apply -f deploy/local/deps.yaml | ||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) apply -f deploy/local/mockllm.yaml | ||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) rollout status deploy/redis --timeout=120s | ||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) rollout status deploy/postgres --timeout=120s | ||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) rollout status deploy/mongodb --timeout=180s | ||||||||||||||||||
| kubectl --context kind-$(KIND_CLUSTER) rollout status deploy/mockllm --timeout=120s | ||||||||||||||||||
|
|
||||||||||||||||||
| # Delete the local kind cluster. | ||||||||||||||||||
| kind-down: | ||||||||||||||||||
| kind delete cluster --name $(KIND_CLUSTER) | ||||||||||||||||||
|
|
||||||||||||||||||
| # Inner dev loop: build image, load into kind, deploy via Helm, watch for changes. | ||||||||||||||||||
| # The gateway is reachable at http://localhost:8080 via the kind NodePort mapping. | ||||||||||||||||||
| dev-k8s: | ||||||||||||||||||
| skaffold dev --kube-context kind-$(KIND_CLUSTER) | ||||||||||||||||||
|
|
||||||||||||||||||
| # One-shot build + deploy (no watch). | ||||||||||||||||||
| deploy-k8s: | ||||||||||||||||||
| skaffold run --kube-context kind-$(KIND_CLUSTER) | ||||||||||||||||||
|
|
||||||||||||||||||
| # Tear down the deployed release and dependencies. | ||||||||||||||||||
| undeploy-k8s: | ||||||||||||||||||
| skaffold delete --kube-context kind-$(KIND_CLUSTER) | ||||||||||||||||||
|
Comment on lines
+89
to
+91
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Correct the teardown scope description.
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| # Run unit tests only | ||||||||||||||||||
| test: | ||||||||||||||||||
| go test ./cmd/... ./internal/... ./config/... -v | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Patterns to ignore when building packages. | ||
| .DS_Store | ||
| .git/ | ||
| .gitignore | ||
| *.tmpl | ||
| *.tgz | ||
| .helmignore | ||
| ci/ | ||
| README.md.gotmpl | ||
| # CI/development artifacts | ||
| .github/ | ||
| tests/ |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||||||
| apiVersion: v2 | ||||||||||
| name: gomodel | ||||||||||
| description: A high-performance, lightweight AI gateway that routes requests to multiple AI model providers through an OpenAI-compatible API. | ||||||||||
| type: application | ||||||||||
| # Chart version is independent of the application version and follows SemVer. | ||||||||||
| version: 0.1.0 | ||||||||||
| # appVersion tracks the GoModel application release this chart was tested against. | ||||||||||
| appVersion: "latest" | ||||||||||
|
Comment on lines
+7
to
+8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Pin
Set 🔧 Proposed change # appVersion tracks the GoModel application release this chart was tested against.
-appVersion: "latest"
+appVersion: "0.1.0"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| home: https://github.com/ENTERPILOT/GoModel | ||||||||||
| sources: | ||||||||||
| - https://github.com/ENTERPILOT/GoModel | ||||||||||
| keywords: | ||||||||||
| - ai | ||||||||||
| - gateway | ||||||||||
| - llm | ||||||||||
| - openai | ||||||||||
| - proxy | ||||||||||
| maintainers: | ||||||||||
| - name: GoModel Maintainers | ||||||||||
| url: https://github.com/ENTERPILOT/GoModel | ||||||||||
| icon: https://raw.githubusercontent.com/ENTERPILOT/GoModel/main/docs/logo.png | ||||||||||
| annotations: | ||||||||||
| category: AIMachineLearning | ||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: ENTERPILOT/GoModel
Length of output: 216
🏁 Script executed:
Repository: 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, andhelm/chart-testing-action@v2can 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
Source: Linters/SAST tools