Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
GO_VERSION: "1.24.3"
NODE_VERSION: "20"

jobs:
ci:
name: Build
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
cache-dependency-path: ui/pnpm-lock.yaml

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true

- name: Install deps
run: make deps
- name: Build
run: make build
- name: lint
run: make pre-commit
- name: Test
run: ./kite -h
1 change: 1 addition & 0 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ github.ref_name == 'main' && 'latest' || github.ref_name }}
Expand Down
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

# Variables
BINARY_NAME=kite
STATIC_DIR=static
UI_DIR=ui
DOCKER_IMAGE=kite
DOCKER_TAG=latest
Expand Down Expand Up @@ -35,7 +34,6 @@ deps: ## Install frontend and backend dependencies
# Build targets
build: frontend backend ## Build both frontend and backend
@echo "✅ Build completed successfully!"
@echo "📁 Static files are in ./$(STATIC_DIR)/"
@echo "🚀 Run './$(BINARY_NAME)' to start the server"

frontend: ## Build frontend only
Expand Down Expand Up @@ -65,7 +63,7 @@ dev: ## Run in development mode
echo "🛑 Stopping backend server..."; \
kill $$BACKEND_PID 2>/dev/null

lint: ## Run linters
lint: golangci-lint ## Run linters
Copy link

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lint target now depends on a golangci-lint rule which isn't defined in the Makefile, causing make lint to fail. Add a golangci-lint target or remove this dependency.

Copilot uses AI. Check for mistakes.

@echo "🔍 Running linters..."
@echo "Backend linting..."
go vet ./...
Expand Down
2 changes: 1 addition & 1 deletion pkg/kube/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (session *TerminalSession) Start(ctx context.Context, subResource string) e
})

if err != nil {
Copy link

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Replacing the server-side klog.Errorf with only a client error message may reduce observability. Consider retaining a klog.Errorf call alongside SendErrorMessage.

Suggested change
if err != nil {
if err != nil {
klog.Errorf("Error during exec stream for pod %s in namespace %s: %v", session.podName, session.namespace, err)

Copilot uses AI. Check for mistakes.

klog.Errorf("Exec session error: %v", err)
session.SendErrorMessage(err.Error())
return err
}

Expand Down
2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"kubernetes-types": "^1.30.0",
"lucide-react": "^0.511.0",
"next-themes": "^0.4.6",
"prettier": "^3.5.3",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router-dom": "^7.6.1",
Expand All @@ -55,6 +54,7 @@
"tailwindcss": "^4.1.7"
},
"devDependencies": {
"prettier": "^3.5.3",
"@eslint/js": "^9.25.0",
"@ianvs/prettier-plugin-sort-imports": "^4.4.2",
"@types/node": "^22.15.21",
Expand Down
6 changes: 3 additions & 3 deletions ui/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions ui/src/components/configmap-selector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useMemo } from 'react'
import { ConfigMap } from 'kubernetes-types/core/v1'

import { useResources } from '@/lib/api'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'

export function ConfigMapSelector({
selectedConfigMap,
onConfigMapChange,
namespace,
placeholder = 'Select a configmap',
className,
}: {
selectedConfigMap?: string
onConfigMapChange: (configMap: string) => void
namespace?: string
placeholder?: string
className?: string
}) {
const { data, isLoading } = useResources('configmaps', namespace)

const sortedConfigMaps = useMemo(() => {
Copy link

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The sorting and rendering logic here duplicates the one in SecretSelector. Consider extracting a generic selector component to avoid code duplication.

Copilot uses AI. Check for mistakes.

return data?.slice().sort((a, b) => {
const nameA = a.metadata?.name?.toLowerCase() || ''
const nameB = b.metadata?.name?.toLowerCase() || ''
return nameA.localeCompare(nameB)
})
}, [data])

return (
<Select value={selectedConfigMap} onValueChange={onConfigMapChange}>
<SelectTrigger className={className}>
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent>
{isLoading && (
<SelectItem disabled value="_loading">
Loading configmaps...
</SelectItem>
)}
{sortedConfigMaps?.map((configMap: ConfigMap) => (
<SelectItem
key={configMap.metadata!.name}
value={configMap.metadata!.name!}
>
{configMap.metadata!.name}
</SelectItem>
))}
{!isLoading && (!sortedConfigMaps || sortedConfigMaps.length === 0) && (
<SelectItem disabled value="_empty">
No configmaps found
</SelectItem>
)}
</SelectContent>
</Select>
)
}
Loading
Loading