Skip to content

Commit 98a2208

Browse files
authored
chore: helm chart configuration (#12)
* chore: wip helm chart configuration * leftover * refactor: remove ingress * chore: use kind and test helm chart on ci * fix: gh action version and k8s kind version * fix(ci): correct action hashes, upgrade kind to v1.13.0, add security permissions * leftover * fix(helm): add maintainer email to pass chart-testing validation * fix: remove unneeded config * fix: remove unneeded config * chore: rename job title * fix(ci): simplify helm lint workflow and fix Chart.yaml - Remove ct lint step (too restrictive, requires maintainers) - Remove chart-testing-action setup (unused) - Add --kube-version 1.28.0 to helm template for compatibility - Fix Chart.yaml URLs to point to stacklok/toolhive-cloud-ui - Remove maintainers field (not required without ct lint) - Align with toolhive operator chart structure * refactor: review copilot * refactor(makefile): use RELEASE_NAME variable for helm commands - Add RELEASE_NAME variable to avoid hardcoded deployment name - Use variable in kind-deploy, kind-uninstall, kind-logs, kind-port-forward - Improves flexibility and maintainability - Addresses Copilot review suggestion
1 parent 6b9fa9c commit 98a2208

File tree

15 files changed

+715
-3
lines changed

15 files changed

+715
-3
lines changed

.github/workflows/helm-test.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Helm Chart Test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "helm/**"
8+
- ".github/workflows/helm-test.yml"
9+
pull_request:
10+
branches: [main]
11+
paths:
12+
- "helm/**"
13+
- ".github/workflows/helm-test.yml"
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
test-helm-chart:
20+
name: Test Helm Chart
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
26+
27+
- name: Set up Docker Buildx
28+
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
29+
30+
- name: Build Docker image
31+
uses: docker/build-push-action@c382f710d39a5bb4e430307530a720f50c2d3318 # v6.0.0
32+
with:
33+
context: .
34+
load: true
35+
tags: toolhive-cloud-ui:latest
36+
cache-from: type=gha
37+
cache-to: type=gha,mode=max
38+
39+
- name: Create Kind cluster
40+
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
41+
42+
- name: Load image into Kind
43+
run: |
44+
kind load docker-image toolhive-cloud-ui:latest --name chart-testing
45+
46+
- name: Install Helm chart
47+
run: |
48+
helm upgrade --install toolhive-cloud-ui ./helm \
49+
-f ./helm/values-dev.yaml \
50+
--wait \
51+
--timeout=5m
52+
53+
- name: Check deployment status
54+
run: |
55+
kubectl get pods -l app.kubernetes.io/name=toolhive-cloud-ui
56+
kubectl get svc -l app.kubernetes.io/name=toolhive-cloud-ui
57+
58+
- name: Verify application is responding
59+
run: |
60+
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=toolhive-cloud-ui --timeout=120s
61+
kubectl port-forward svc/toolhive-cloud-ui 8080:80 &
62+
sleep 5
63+
curl -f http://localhost:8080 || (kubectl logs -l app.kubernetes.io/name=toolhive-cloud-ui && exit 1)
64+
65+
- name: Run Helm tests (if any)
66+
run: |
67+
helm test toolhive-cloud-ui || echo "No tests defined"
68+
69+
- name: Show logs on failure
70+
if: failure()
71+
run: |
72+
kubectl get all -l app.kubernetes.io/name=toolhive-cloud-ui
73+
kubectl describe pods -l app.kubernetes.io/name=toolhive-cloud-ui
74+
kubectl logs -l app.kubernetes.io/name=toolhive-cloud-ui --tail=100

.github/workflows/lint-helm.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Lint Helm Chart
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "helm/**"
8+
- ".github/workflows/lint-helm.yml"
9+
pull_request:
10+
branches: [main]
11+
paths:
12+
- "helm/**"
13+
- ".github/workflows/lint-helm.yml"
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
lint-chart:
20+
name: Lint Helm Chart
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Set up Helm
30+
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
31+
with:
32+
version: "latest"
33+
34+
- name: Run Helm lint
35+
run: |
36+
helm lint ./helm
37+
helm lint ./helm -f ./helm/values-dev.yaml
38+
39+
- name: Validate templates
40+
run: |
41+
helm template toolhive-cloud-ui ./helm --kube-version 1.28.0 --debug
42+
helm template toolhive-cloud-ui ./helm -f ./helm/values-dev.yaml --kube-version 1.28.0 --debug

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,8 @@ yarn-error.log*
3939
# typescript
4040
*.tsbuildinfo
4141
next-env.d.ts
42+
43+
# helm
44+
*.tgz
45+
helm/charts/
46+
helm/*.lock

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN corepack enable && corepack prepare [email protected] --activate
1010

1111
WORKDIR /app
1212

13-
# Install dependencies based on the preferred package manager
13+
# Install dependencies
1414
COPY package.json pnpm-lock.yaml* ./
1515
RUN pnpm install --frozen-lockfile
1616

Makefile

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,31 @@ IMAGE_NAME := toolhive-cloud-ui
55
IMAGE_TAG := latest
66
CONTAINER_NAME := toolhive-cloud-ui
77
PORT := 3000
8+
RELEASE_NAME := toolhive-cloud-ui
89

910
## Show this help message
1011
help:
11-
@echo "Available commands:"
12-
@grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## //' | awk 'NR%2==1{printf "\033[36m%-15s\033[0m ",$$1} NR%2==0{print}'
12+
@echo "ToolHive Cloud UI - Available Commands"
13+
@echo ""
14+
@echo "Docker (Local Development):"
15+
@echo " make build - Build production Docker image"
16+
@echo " make start - Start Docker container"
17+
@echo " make stop - Stop Docker container"
18+
@echo " make logs - View container logs"
19+
@echo " make clean - Remove container and image"
20+
@echo " make rebuild - Clean and rebuild"
21+
@echo ""
22+
@echo "Kind (Kubernetes):"
23+
@echo " make kind-setup - Create cluster and deploy (first time)"
24+
@echo " make kind-create - Create Kind cluster"
25+
@echo " make kind-deploy - Build and deploy to Kind"
26+
@echo " make kind-port-forward - Port-forward to localhost:8080"
27+
@echo " make kind-logs - View application logs"
28+
@echo " make kind-uninstall - Uninstall from Kind"
29+
@echo " make kind-delete - Delete Kind cluster"
30+
@echo ""
31+
@echo "Development:"
32+
@echo " make dev - Run Next.js dev server"
1333

1434
## Build the production docker image
1535
build:
@@ -51,3 +71,52 @@ shell:
5171
rebuild: clean build
5272
@echo "Rebuild complete"
5373

74+
## Create Kind cluster
75+
kind-create:
76+
@echo "Creating Kind cluster..."
77+
@kind create cluster --name toolhive || echo "Cluster already exists"
78+
@kubectl cluster-info --context kind-toolhive
79+
@echo "Kind cluster ready!"
80+
81+
## Delete Kind cluster
82+
kind-delete:
83+
@echo "Deleting Kind cluster..."
84+
@kind delete cluster --name toolhive
85+
@echo "Cluster deleted"
86+
87+
## Build and load image into Kind
88+
kind-build:
89+
@echo "Building Docker image..."
90+
@docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
91+
@echo "Loading image into Kind cluster..."
92+
@kind load docker-image $(IMAGE_NAME):$(IMAGE_TAG) --name toolhive
93+
@echo "Image loaded successfully"
94+
95+
## Deploy to Kind with Helm
96+
kind-deploy: kind-build
97+
@echo "Deploying to Kind..."
98+
@helm upgrade --install $(RELEASE_NAME) ./helm -f ./helm/values-dev.yaml --wait --timeout=5m
99+
@echo "Deployment complete!"
100+
@echo ""
101+
@echo "To access the application, run:"
102+
@echo " make kind-port-forward"
103+
@echo "Then open: http://localhost:8080"
104+
105+
## Uninstall from Kind
106+
kind-uninstall:
107+
@helm uninstall $(RELEASE_NAME) || true
108+
@echo "Uninstalled from Kind"
109+
110+
## View logs
111+
kind-logs:
112+
@kubectl logs -f deployment/$(RELEASE_NAME)
113+
114+
## Port-forward to localhost
115+
kind-port-forward:
116+
@echo "Forwarding to http://localhost:8080"
117+
@kubectl port-forward svc/$(RELEASE_NAME) 8080:80
118+
119+
## Full setup: create cluster and deploy
120+
kind-setup: kind-create kind-deploy
121+
@echo "Setup complete!"
122+

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,59 @@ make clean
4747

4848
# Rebuild from scratch
4949
make rebuild
50+
```
5051

5152
The application will be available at [http://localhost:3000](http://localhost:3000).
5253

54+
## Kubernetes / Kind Deployment
55+
56+
This project includes a complete Helm chart for deploying to Kubernetes (optimized for Kind).
57+
58+
### Quick Start with Kind
59+
60+
```bash
61+
# Create cluster and deploy (first time)
62+
make kind-setup
63+
64+
# Or step by step:
65+
# 1. Create Kind cluster
66+
make kind-create
67+
68+
# 2. Deploy application
69+
make kind-deploy
70+
71+
# 3. Access the application
72+
make kind-port-forward
73+
# Then open: http://localhost:8080
74+
75+
# View logs
76+
make kind-logs
77+
78+
# Uninstall
79+
make kind-uninstall
80+
81+
# Delete cluster
82+
make kind-delete
83+
```
84+
85+
### Helm Chart
86+
87+
The Helm chart is located in the `helm/` directory and includes:
88+
89+
- Deployment with configurable replicas
90+
- Service (ClusterIP/NodePort/LoadBalancer)
91+
- Horizontal Pod Autoscaler (optional)
92+
- Configurable resource limits
93+
- Health checks (startup, liveness and readiness probes)
94+
- Security contexts following Pod Security Standards
95+
96+
### CI/CD
97+
98+
The chart is automatically tested on every push using GitHub Actions with Kind:
99+
100+
- **Helm Lint**: Validates chart syntax and best practices
101+
- **Integration Test**: Deploys to Kind cluster and verifies the app responds
102+
53103
## Learn More
54104

55105
To learn more about Next.js, take a look at the following resources:

helm/.helmignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
24+

helm/Chart.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v2
2+
name: toolhive-cloud-ui
3+
description: A Helm chart for ToolHive Cloud UI - Next.js application
4+
type: application
5+
version: 0.1.0
6+
appVersion: "0.1.0"
7+
keywords:
8+
- nextjs
9+
- react
10+
- frontend
11+
- ui
12+
home: https://github.com/stacklok/toolhive-cloud-ui
13+
sources:
14+
- https://github.com/stacklok/toolhive-cloud-ui
15+
kubeVersion: ">=1.24.0-0"

helm/templates/_helpers.tpl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "toolhive-cloud-ui.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
*/}}
11+
{{- define "toolhive-cloud-ui.fullname" -}}
12+
{{- if .Values.fullnameOverride }}
13+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
14+
{{- else }}
15+
{{- $name := default .Chart.Name .Values.nameOverride }}
16+
{{- if contains $name .Release.Name }}
17+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
18+
{{- else }}
19+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
20+
{{- end }}
21+
{{- end }}
22+
{{- end }}
23+
24+
{{/*
25+
Create chart name and version as used by the chart label.
26+
*/}}
27+
{{- define "toolhive-cloud-ui.chart" -}}
28+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
29+
{{- end }}
30+
31+
{{/*
32+
Common labels
33+
*/}}
34+
{{- define "toolhive-cloud-ui.labels" -}}
35+
helm.sh/chart: {{ include "toolhive-cloud-ui.chart" . }}
36+
{{ include "toolhive-cloud-ui.selectorLabels" . }}
37+
{{- if .Chart.AppVersion }}
38+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
39+
{{- end }}
40+
app.kubernetes.io/managed-by: {{ .Release.Service }}
41+
app.kubernetes.io/component: frontend
42+
app.kubernetes.io/part-of: toolhive
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "toolhive-cloud-ui.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "toolhive-cloud-ui.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "toolhive-cloud-ui.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "toolhive-cloud-ui.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
63+

0 commit comments

Comments
 (0)