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
85 changes: 85 additions & 0 deletions .github/workflows/dashboard-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Dashboard Test

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- main
push:
branches:
- main
workflow_dispatch: # Allow manual triggering

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

jobs:
# Use changes filter to detect dashboard changes
changes:
uses: ./.github/workflows/ci-changes.yml

dashboard-test:
needs: changes
if: >-
${{ !github.event.pull_request.draft
&& needs.changes.outputs.dashboard == 'true' }}
runs-on: ubuntu-latest
name: Dashboard Lint and Type Check

steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: "23"

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24"

- name: Cache Node.js dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
dashboard/frontend/node_modules
key: ${{ runner.os }}-node-dashboard-${{ hashFiles('dashboard/frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-dashboard-

- name: Cache Go dependencies
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
key: ${{ runner.os }}-go-dashboard-${{ hashFiles('dashboard/backend/go.sum') }}
restore-keys: |
${{ runner.os }}-go-dashboard-

- name: Set up golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.5.0
install-mode: binary
args: --help

- name: Run dashboard checks
run: make dashboard-check

- name: Build dashboard
run: make dashboard-build

- name: Show results on failure
if: failure()
run: |
echo "::error::Dashboard checks failed. Please fix the issues and commit again."
echo ""
echo "To run checks locally:"
echo " make dashboard-check"
echo ""
echo "To auto-fix lint issues:"
echo " make dashboard-lint-fix"
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ _run:
-f tools/make/rust.mk \
-f tools/make/build-run-test.mk \
-f tools/make/docs.mk \
-f tools/make/dashboard.mk \
-f tools/make/linter.mk \
-f tools/make/milvus.mk \
-f tools/make/redis.mk \
Expand Down
6 changes: 4 additions & 2 deletions dashboard/backend/handlers/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func UpdateConfigHandler(configPath string) http.HandlerFunc {
}

// Write to file
if err := os.WriteFile(configPath, yamlData, 0644); err != nil {
if err := os.WriteFile(configPath, yamlData, 0o644); err != nil {
log.Printf("Error writing config file: %v", err)
http.Error(w, fmt.Sprintf("Failed to write config file: %v", err), http.StatusInternalServerError)
return
Expand All @@ -80,6 +80,8 @@ func UpdateConfigHandler(configPath string) http.HandlerFunc {
log.Printf("Configuration updated successfully")
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "Configuration updated successfully"})
if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "Configuration updated successfully"}); err != nil {
log.Printf("Error encoding response: %v", err)
}
}
}
2 changes: 1 addition & 1 deletion dashboard/backend/handlers/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import (
func HealthCheck(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"healthy","service":"semantic-router-dashboard"}`))
_, _ = w.Write([]byte(`{"status":"healthy","service":"semantic-router-dashboard"}`))
}
10 changes: 5 additions & 5 deletions dashboard/backend/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func Setup(cfg *config.Config) *http.ServeMux {
mux.HandleFunc("/embedded/grafana/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(`{"error":"Grafana not configured","message":"TARGET_GRAFANA_URL environment variable is not set"}`))
_, _ = w.Write([]byte(`{"error":"Grafana not configured","message":"TARGET_GRAFANA_URL environment variable is not set"}`))
})
log.Printf("Warning: Grafana URL not configured")
}
Expand Down Expand Up @@ -253,7 +253,7 @@ func Setup(cfg *config.Config) *http.ServeMux {
mux.HandleFunc("/embedded/chatui/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(`{"error":"HuggingChat not configured","message":"TARGET_CHATUI_URL environment variable is not set"}`))
_, _ = w.Write([]byte(`{"error":"HuggingChat not configured","message":"TARGET_CHATUI_URL environment variable is not set"}`))
})
log.Printf("Info: HuggingChat not configured (optional)")
}
Expand Down Expand Up @@ -328,7 +328,7 @@ func Setup(cfg *config.Config) *http.ServeMux {
mux.HandleFunc("/embedded/prometheus/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(`{"error":"Prometheus not configured","message":"TARGET_PROMETHEUS_URL environment variable is not set"}`))
_, _ = w.Write([]byte(`{"error":"Prometheus not configured","message":"TARGET_PROMETHEUS_URL environment variable is not set"}`))
})
log.Printf("Warning: Prometheus URL not configured")
}
Expand Down Expand Up @@ -372,7 +372,7 @@ func Setup(cfg *config.Config) *http.ServeMux {
mux.HandleFunc("/embedded/jaeger/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(`{"error":"Jaeger not configured","message":"TARGET_JAEGER_URL environment variable is not set"}`))
_, _ = w.Write([]byte(`{"error":"Jaeger not configured","message":"TARGET_JAEGER_URL environment variable is not set"}`))
})
log.Printf("Info: Jaeger URL not configured (optional)")
}
Expand Down Expand Up @@ -400,7 +400,7 @@ func Setup(cfg *config.Config) *http.ServeMux {
mux.HandleFunc("/embedded/openwebui/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(`{"error":"Open WebUI not configured","message":"TARGET_OPENWEBUI_URL environment variable is not set or empty"}`))
_, _ = w.Write([]byte(`{"error":"Open WebUI not configured","message":"TARGET_OPENWEBUI_URL environment variable is not set or empty"}`))
})
log.Printf("Info: Open WebUI not configured (optional)")
}
Expand Down
36 changes: 36 additions & 0 deletions dashboard/frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default tseslint.config(
{ ignores: ["dist", "node_modules"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
// Temporarily relaxed rules for existing code - can be tightened later
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/ban-ts-comment": "warn",
"no-useless-escape": "warn",
},
}
);
Loading
Loading