-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
389 lines (321 loc) · 14.7 KB
/
Copy pathMakefile
File metadata and controls
389 lines (321 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
# AI Dev Control Plane — Root Makefile
# ======================================
# Cross-platform (Linux/macOS) build orchestration for local development.
# Uses docker-compose v1 syntax for maximum compatibility.
# --- Phony targets -----------------------------------------------------------
.PHONY: dev dev-web dev-api dev-worker dev-runner \
docker-up docker-down docker-logs docker-status \
migrate db-reset gen-db \
test test-api test-cli test-packages test-race test-sdk \
lint lint-go lint-web lint-fix-web lint-sdk \
build build-api build-cli build-worker build-runner build-web build-sdk \
clean help install-tools
# --- Variables ---------------------------------------------------------------
# Load local .env file if present so app defaults match the project config
ifneq (,$(wildcard ./.env))
include .env
export
endif
# Detect OS for cross-platform compatibility
UNAME_S := $(shell uname -s)
# Default environment variables (override in .env or shell)
export DATABASE_URL ?= file:./data/dev.db?_journal_mode=WAL
export NATS_URL ?= nats://localhost:4222
export PORT ?= 8080
export WEB_PORT ?= 3000
export RUNNER_PORT ?= 8082
export JWT_SECRET ?= dev-secret-change-me-min-32-chars-long
export LOG_LEVEL ?= info
export TEMPORAL_HOST ?= localhost:7233
export BIFROST_URL ?= http://localhost:8081
export WORKSPACE_BASE_DIR ?= ./data/workspaces
# Directories
DATA_DIR := ./data
MIGRATIONS_DIR := ./packages/db/migrations
BIN_DIR := ./bin
# Docker Compose command (prefer v2, fall back to v1)
DOCKER_COMPOSE := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose")
# Derive Go modules from the workspace; fall back to explicit lists if introspection fails.
GO_MODULES := $(shell go list -f '{{.Dir}}' -m all 2>/dev/null | sed -n 's|$(CURDIR)/||p' | grep -E '^(packages|apps)/')
GO_PACKAGES := $(filter packages/%,$(GO_MODULES))
GO_APPS := $(filter apps/%,$(GO_MODULES))
# Fallback explicit lists (used when workspace introspection is unavailable).
ifeq ($(GO_PACKAGES),)
GO_PACKAGES := packages/db packages/agents packages/runtimes packages/repo-intel packages/events packages/models packages/policies packages/gateway packages/prfactory packages/reviewer packages/securityscan
endif
ifeq ($(GO_APPS),)
GO_APPS := apps/api apps/worker apps/runner
endif
# Colors for output (Linux/macOS compatible)
BLUE := $(shell tput setaf 6 2>/dev/null || echo "")
GREEN := $(shell tput setaf 2 2>/dev/null || echo "")
RESET := $(shell tput sgr0 2>/dev/null || echo "")
# --- Development targets -----------------------------------------------------
dev: ## Start all services (docker-up, migrate, then web/api/worker in parallel)
@echo "$(GREEN)Starting AI Dev Control Plane in dev mode...$(RESET)"
@$(MAKE) docker-up
@echo "$(BLUE)Waiting for NATS to be ready...$(RESET)"
@i=0; \
while [ $$i -lt 30 ]; do \
if curl -fsS http://localhost:8222/healthz >/dev/null 2>&1 || \
wget --spider -q http://localhost:8222/healthz >/dev/null 2>&1; then \
echo "$(GREEN)NATS is ready.$(RESET)"; \
break; \
fi; \
i=$$((i + 1)); \
if [ $$i -eq 30 ]; then \
echo "$(BLUE)NATS health check timed out after 30s; continuing anyway...$(RESET)"; \
fi; \
sleep 1; \
done
@mkdir -p $(DATA_DIR)
@$(MAKE) migrate
@echo "$(GREEN)All dependencies ready. Starting applications...$(RESET)"
@trap 'echo "$(BLUE)Shutting down dev servers...$(RESET)"; kill %1 %2 %3 %4 2>/dev/null; wait' EXIT INT TERM; \
$(MAKE) dev-web & \
$(MAKE) dev-api & \
$(MAKE) dev-worker & \
$(MAKE) dev-runner & \
wait
dev-web: ## Start Next.js dev server
@echo "$(BLUE)[web]$(RESET) Starting Next.js dev server on port $(WEB_PORT)..."
cd apps/web && PORT=$(WEB_PORT) npm run dev
dev-api: ## Start Go API server (with hot reload via Air if available)
@echo "$(BLUE)[api]$(RESET) Starting Go API server on port $(PORT)..."
ifeq ($(shell which air 2>/dev/null),)
cd apps/api && go run cmd/api/main.go
else
cd apps/api && air -c .air.toml
endif
dev-worker: ## Start Go worker service
@echo "$(BLUE)[worker]$(RESET) Starting Go worker..."
cd apps/worker && go run cmd/worker/main.go
dev-runner: ## Start Go runner (runtime) service
@echo "$(BLUE)[runner]$(RESET) Starting Go runner service on port $(RUNNER_PORT)..."
cd apps/runner && RUNNER_PORT=$(RUNNER_PORT) go run cmd/runner/main.go
# --- Docker service targets --------------------------------------------------
docker-up: ## Start Docker services (NATS, optional Temporal)
@echo "$(BLUE)[docker]$(RESET) Starting Docker services..."
$(DOCKER_COMPOSE) up -d
docker-down: ## Stop Docker services
@echo "$(BLUE)[docker]$(RESET) Stopping Docker services..."
$(DOCKER_COMPOSE) down
docker-logs: ## Follow Docker service logs
$(DOCKER_COMPOSE) logs -f
docker-status: ## Show Docker service status
$(DOCKER_COMPOSE) ps
docker-logs-nats: ## Follow NATS logs only
$(DOCKER_COMPOSE) logs -f nats
docker-logs-temporal: ## Follow Temporal logs only
$(DOCKER_COMPOSE) logs -f temporal
docker-down-volumes: ## Stop Docker services and remove volumes (DESTRUCTIVE)
@echo "$(BLUE)[docker]$(RESET) Stopping services and removing volumes..."
$(DOCKER_COMPOSE) down -v
# --- Database targets --------------------------------------------------------
migrate: ## Run database migrations (Goose)
@echo "$(BLUE)[db]$(RESET) Running migrations..."
@mkdir -p $(DATA_DIR)
goose -dir $(MIGRATIONS_DIR) sqlite3 "$(DATABASE_URL)" up
db-reset: ## Delete DB files and recreate (DESTRUCTIVE)
@echo "$(BLUE)[db]$(RESET) Resetting database..."
@rm -f $(DATA_DIR)/dev.db $(DATA_DIR)/dev.db-shm $(DATA_DIR)/dev.db-wal
@mkdir -p $(DATA_DIR)
@$(MAKE) migrate
@echo "$(GREEN)Database reset complete.$(RESET)"
db-status: ## Show current migration status
@goose -dir $(MIGRATIONS_DIR) sqlite3 "$(DATABASE_URL)" status
db-version: ## Show current migration version
@goose -dir $(MIGRATIONS_DIR) sqlite3 "$(DATABASE_URL)" version
# --- Code generation targets -------------------------------------------------
gen-db: ## Generate SQLC typed database code
@echo "$(BLUE)[gen]$(RESET) Generating SQLC code..."
cd packages/db && sqlc generate
@echo "$(GREEN)SQLC generation complete.$(RESET)"
gen-mock: ## Generate Go mocks (if mockgen is installed)
@echo "$(BLUE)[gen]$(RESET) Generating mocks..."
go generate ./...
# --- Testing targets ---------------------------------------------------------
test: ## Run ALL Go tests across all packages and SDK
@echo "$(GREEN)Running all tests...$(RESET)"
@for pkg in $(GO_PACKAGES); do \
echo "$(BLUE)[test]$(RESET) $$pkg"; \
cd $$pkg && go test ./... && cd - > /dev/null || exit 1; \
done
@for app in $(GO_APPS); do \
echo "$(BLUE)[test]$(RESET) $$app"; \
cd $$app && go test ./... && cd - > /dev/null || exit 1; \
done
@$(MAKE) test-cli
@$(MAKE) test-sdk
@echo "$(GREEN)All tests passed.$(RESET)"
test-api: ## Run API-specific tests with verbose output
@echo "$(BLUE)[test]$(RESET) Running API tests..."
cd apps/api && go test ./... -v
test-cli: ## Run CLI-specific tests
@echo "$(BLUE)[test]$(RESET) Running CLI tests..."
cd apps/cli && go test ./... -v
test-worker: ## Run worker-specific tests
@echo "$(BLUE)[test]$(RESET) Running worker tests..."
cd apps/worker && go test ./... -v
test-packages: ## Run package tests only (no apps)
@echo "$(GREEN)Running package tests...$(RESET)"
@for pkg in $(GO_PACKAGES); do \
echo "$(BLUE)[test]$(RESET) $$pkg"; \
cd $$pkg && go test ./... && cd - > /dev/null || exit 1; \
done
test-race: ## Run Go tests with race detector
@echo "$(GREEN)Running tests with race detector...$(RESET)"
@for pkg in $(GO_PACKAGES); do \
echo "$(BLUE)[test]$(RESET) $$pkg"; \
cd $$pkg && go test ./... -race && cd - > /dev/null || exit 1; \
done
@for app in $(GO_APPS); do \
echo "$(BLUE)[test]$(RESET) $$app"; \
cd $$app && go test ./... -race && cd - > /dev/null || exit 1; \
done
test-sdk: ## Install deps and test TypeScript SDK (typecheck + tests)
@echo "$(BLUE)[test]$(RESET) Installing and testing TypeScript SDK..."
cd packages/sdk/typescript && npm ci && npm run typecheck && npm test
@echo "$(GREEN)SDK tests passed.$(RESET)"
integration-test: ## Run credential-dependent integration tests (skip if no credentials)
@echo "$(GREEN)Running integration tests...$(RESET)"
cd packages/gateway && go test -tags=integration ./... -run Integration -timeout 60s
cd apps/api && go test -tags=integration ./internal/modelrouter/... -run Integration -timeout 60s
live-e2e: ## Run live end-to-end gates (requires model provider key, GitHub token, NATS, Docker)
@echo "$(GREEN)Running live end-to-end integration gates...$(RESET)"
cd apps/worker && RUN_LIVE_E2E=1 go test ./internal/integration/... -v -timeout 20m
test-coverage: ## Run tests with coverage report
@echo "$(GREEN)Running tests with coverage...$(RESET)"
@mkdir -p $(BIN_DIR)
@rm -f $(BIN_DIR)/coverage.*.out $(BIN_DIR)/coverage.out $(BIN_DIR)/coverage.html
@ABS_BIN=$$(cd $(BIN_DIR) && pwd); \
idx=0; \
for pkg in $(GO_PACKAGES) $(GO_APPS); do \
idx=$$((idx + 1)); \
outfile="$$ABS_BIN/coverage.$$idx.$$(basename $$pkg).out"; \
echo "$(BLUE)[coverage]$(RESET) $$pkg"; \
cd $$pkg && go test ./... -coverprofile=$$outfile >/dev/null 2>&1 || exit 1; \
cd - > /dev/null; \
done; \
mode=""; \
for f in $(BIN_DIR)/coverage.*.out; do \
if [ -z "$$mode" ]; then \
mode=$$(head -n1 "$$f"); \
echo "$$mode" > $(BIN_DIR)/coverage.out; \
fi; \
tail -n +2 "$$f" >> $(BIN_DIR)/coverage.out; \
done; \
go tool cover -html=$(BIN_DIR)/coverage.out -o $(BIN_DIR)/coverage.html
@echo "$(GREEN)Coverage report: $(BIN_DIR)/coverage.html$(RESET)"
# --- Linting targets ---------------------------------------------------------
lint: lint-go lint-web ## Run all linters (Go + frontend)
lint-go: ## Run golangci-lint across all Go modules
@echo "$(BLUE)[lint]$(RESET) Running golangci-lint..."
@for pkg in $(GO_PACKAGES); do \
echo " --> $$pkg"; \
cd $$pkg && golangci-lint run ./... && cd - > /dev/null || exit 1; \
done
@for app in $(GO_APPS); do \
echo " --> $$app"; \
cd $$app && golangci-lint run ./... && cd - > /dev/null || exit 1; \
done
@echo "$(BLUE)[lint]$(RESET) Running Go vet as secondary check..."
@for pkg in $(GO_PACKAGES); do \
echo " --> $$pkg"; \
cd $$pkg && go vet ./... && cd - > /dev/null || exit 1; \
done
@for app in $(GO_APPS); do \
echo " --> $$app"; \
cd $$app && go vet ./... && cd - > /dev/null || exit 1; \
done
@echo "$(GREEN)Go linting complete.$(RESET)"
lint-web: ## Run npm lint in frontend
@echo "$(BLUE)[lint]$(RESET) Running web lint..."
cd apps/web && npm run lint
lint-fix-web: ## Run web linter with auto-fix
@echo "$(BLUE)[lint]$(RESET) Running web lint with auto-fix..."
cd apps/web && npm run lint:fix
lint-sdk: ## Run TypeScript SDK typecheck
@echo "$(BLUE)[lint]$(RESET) Running SDK typecheck..."
cd packages/sdk/typescript && npm ci && npm run typecheck
@echo "$(GREEN)SDK lint complete.$(RESET)"
lint-fix: ## Run linters with auto-fix
@echo "$(BLUE)[lint]$(RESET) Running auto-fix..."
cd apps/web && npm run lint -- --fix 2>/dev/null || true
@echo "$(GREEN)Auto-fix complete.$(RESET)"
# --- Build targets -----------------------------------------------------------
build: build-api build-cli build-worker build-runner build-sdk build-web ## Build all binaries, SDK, and frontend
build-api: ## Build API binary --> bin/api
@echo "$(BLUE)[build]$(RESET) Building API..."
@mkdir -p $(BIN_DIR)
cd apps/api && go build -ldflags="-s -w" -o ../../$(BIN_DIR)/api cmd/api/main.go
@echo "$(GREEN)API binary: $(BIN_DIR)/api$(RESET)"
build-cli: ## Build CLI binary --> bin/dev-plane
@echo "$(BLUE)[build]$(RESET) Building CLI..."
@mkdir -p $(BIN_DIR)
cd apps/cli && go build -ldflags="-s -w" -o ../../$(BIN_DIR)/dev-plane ./cmd/dev-plane
@echo "$(GREEN)CLI binary: $(BIN_DIR)/dev-plane$(RESET)"
build-worker: ## Build worker binary --> bin/worker
@echo "$(BLUE)[build]$(RESET) Building worker..."
@mkdir -p $(BIN_DIR)
cd apps/worker && go build -ldflags="-s -w" -o ../../$(BIN_DIR)/worker cmd/worker/main.go
@echo "$(GREEN)Worker binary: $(BIN_DIR)/worker$(RESET)"
build-runner: ## Build runner binary --> bin/runner
@echo "$(BLUE)[build]$(RESET) Building runner..."
@mkdir -p $(BIN_DIR)
cd apps/runner && go build -ldflags="-s -w" -o ../../$(BIN_DIR)/runner cmd/runner/main.go
@echo "$(GREEN)Runner binary: $(BIN_DIR)/runner$(RESET)"
build-web: build-sdk ## Build Next.js for production
@echo "$(BLUE)[build]$(RESET) Building Next.js..."
cd apps/web && npm run build
@echo "$(GREEN)Next.js build complete.$(RESET)"
build-sdk: ## Install deps and build TypeScript SDK
@echo "$(BLUE)[build]$(RESET) Building TypeScript SDK..."
cd packages/sdk/typescript && npm ci && npm run build
@echo "$(GREEN)SDK build complete.$(RESET)"
# --- Clean targets -----------------------------------------------------------
clean: ## Remove bin/ and .next/ build artifacts
@echo "$(BLUE)[clean]$(RESET) Removing build artifacts..."
@rm -rf $(BIN_DIR)/*
@cd apps/web && rm -rf .next/
@echo "$(GREEN)Clean complete.$(RESET)"
clean-all: clean ## Remove all artifacts including Docker volumes (DESTRUCTIVE)
@echo "$(BLUE)[clean]$(RESET) Removing Docker volumes..."
$(DOCKER_COMPOSE) down -v 2>/dev/null || true
@rm -rf $(DATA_DIR)/*
@echo "$(GREEN)Full clean complete.$(RESET)"
# --- Utility targets ---------------------------------------------------------
install-tools: ## Install development tools (Air, Goose, SQLC, golangci-lint)
@echo "$(BLUE)[tools]$(RESET) Installing dev tools..."
go install github.com/air-verse/air@latest
go install github.com/pressly/goose/v3/cmd/goose@latest
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
@echo "$(GREEN)Dev tools installed.$(RESET)"
deps: ## Download and verify Go module dependencies
@echo "$(BLUE)[deps]$(RESET) Downloading Go dependencies..."
@for pkg in $(GO_PACKAGES); do \
echo " --> $$pkg"; \
cd $$pkg && go mod download && cd - > /dev/null; \
done
@for app in $(GO_APPS); do \
echo " --> $$app"; \
cd $$app && go mod download && cd - > /dev/null; \
done
@echo "$(GREEN)Dependencies downloaded.$(RESET)"
fmt: ## Format all Go code
@echo "$(BLUE)[fmt]$(RESET) Formatting Go code..."
gofmt -w packages/ apps/
@echo "$(GREEN)Formatting complete.$(RESET)"
# --- Help target -------------------------------------------------------------
help: ## Show this self-documenting help
@echo ""
@echo " $(GREEN)AI Dev Control Plane$(RESET) -- Available Commands"
@echo " ============================================"
@echo ""
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " $(BLUE)%-18s$(RESET) %s\n", $$1, $$2}' | \
sort
@echo ""
# Default target
.DEFAULT_GOAL := help