-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathMakefile
More file actions
335 lines (277 loc) · 13.8 KB
/
Makefile
File metadata and controls
335 lines (277 loc) · 13.8 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
CODE_QUALITY_DIRS := fred-core agentic-backend knowledge-flow-backend control-plane-backend
TEST_DIRS := agentic-backend knowledge-flow-backend control-plane-backend
DOCKER_BUILD_DIRS := agentic-backend knowledge-flow-backend control-plane-backend frontend
.DEFAULT_GOAL := help
##@ Code quality
.PHONY: code-quality
code-quality: ## Run code quality checks in all submodules
@set -e; \
for dir in $(CODE_QUALITY_DIRS); do \
echo "************ Running code-quality in $$dir ************"; \
$(MAKE) -C $$dir code-quality; \
done
.PHONY: code-quality-fix
code-quality-fix: ## Auto-fix formatting/imports/linting in all submodules
@set -e; \
for dir in $(CODE_QUALITY_DIRS); do \
echo "************ Running code-quality fixes in $$dir ************"; \
$(MAKE) -C $$dir lint-fix import-order-fix format-fix; \
done
.PHONY: clean
clean: ## Clean all submodules
@set -e; \
for dir in $(CODE_QUALITY_DIRS); do \
echo "************ Cleaning $$dir ************"; \
$(MAKE) -C $$dir clean; \
done
##@ Tests
.PHONY: test
test: ## Run non-integration test suites in backend submodules
@set -e; \
for dir in $(TEST_DIRS); do \
echo "************ Running tests in $$dir ************"; \
env -u VIRTUAL_ENV $(MAKE) -C $$dir test; \
done
##@ Run
.PHONY: run-frontend
run-frontend: ## Run frontend only
$(MAKE) -C frontend run
.PHONY: run-agentic
run-agentic: ## Run agentic backend API only
$(MAKE) -C agentic-backend run
.PHONY: run-knowledge-flow
run-knowledge-flow: ## Run knowledge-flow backend API only
$(MAKE) -C knowledge-flow-backend run
.PHONY: run-control-plane
run-control-plane: ## Run control-plane backend API only
$(MAKE) -C control-plane-backend run
.PHONY: dev
dev: ## Start development environment in all submodules
@set -e; \
for dir in $(CODE_QUALITY_DIRS); do \
echo "************ Starting dev environment in $$dir ************"; \
$(MAKE) -C $$dir dev & \
done; \
wait
##@ Docker
.PHONY: docker-build
docker-build: ## Build Docker images for agentic, knowledge-flow, control-plane, and frontend
@set -e; \
for dir in $(DOCKER_BUILD_DIRS); do \
echo "************ Building Docker image in $$dir ************"; \
$(MAKE) -C $$dir docker-build; \
done
##@ Configuration
MISTRAL_API_KEY ?=
.PHONY: use-mistral
use-mistral: ## Switch all config files to use Mistral as LLM provider (usage: make use-mistral [MISTRAL_API_KEY=<key>])
python3 scripts/use_mistral.py
@if [ -n "$(MISTRAL_API_KEY)" ]; then \
echo "--- .env files: setting OPENAI_API_KEY to Mistral API key ---"; \
for env_file in agentic-backend/config/.env knowledge-flow-backend/config/.env control-plane-backend/config/.env; do \
if [ -f "$$env_file" ]; then \
if grep -q '^OPENAI_API_KEY=' "$$env_file"; then \
sed -i 's|^OPENAI_API_KEY=.*|OPENAI_API_KEY="$(MISTRAL_API_KEY)"|' "$$env_file"; \
else \
echo 'OPENAI_API_KEY="$(MISTRAL_API_KEY)"' >> "$$env_file"; \
fi; \
echo " Updated $$env_file"; \
fi; \
done; \
fi
@echo ""
@echo "Done. Reminder: Mistral uses OPENAI_API_KEY as its API key (OpenAI-compatible provider)."
@if [ -z "$(MISTRAL_API_KEY)" ]; then \
echo " OPENAI_API_KEY was NOT updated. Pass MISTRAL_API_KEY=<key> to also set it in .env files."; \
fi
##@ Tools
.PHONY: install-wtf
install-wtf: ## Install the wtf worktree CLI locally (uv tool install, or fallback to pip)
@if command -v uv >/dev/null 2>&1; then \
uv tool install --editable scripts/wtf; \
else \
pip install --editable scripts/wtf; \
fi
##@ Release
VERSION ?=
.PHONY: set-version
set-version: ## Update project version everywhere (usage: make set-version VERSION=x.y.z)
@if [ -z "$(VERSION)" ]; then echo "ERROR: VERSION is required. Usage: make set-version VERSION=x.y.z"; exit 1; fi
$(eval PY_VERSION := $(shell echo "$(VERSION)" | sed 's/-/+/'))
@echo "Setting version to $(VERSION) (Python: $(PY_VERSION))..."
@echo "--- Helm chart ---"
sed -i 's/^version: .*/version: $(VERSION)/' deploy/charts/fred/Chart.yaml
sed -i 's/^appVersion: .*/appVersion: $(VERSION)/' deploy/charts/fred/Chart.yaml
@echo "--- fred-core ---"
sed -i 's/^version = .*/version = "$(PY_VERSION)"/' fred-core/pyproject.toml
cd fred-core && uv lock
@echo "--- agentic-backend ---"
sed -i 's/^version = .*/version = "$(PY_VERSION)"/' agentic-backend/pyproject.toml
cd agentic-backend && uv lock
@echo "--- knowledge-flow-backend ---"
sed -i 's/^version = .*/version = "$(PY_VERSION)"/' knowledge-flow-backend/pyproject.toml
cd knowledge-flow-backend && uv lock
@echo "--- control-plane-backend ---"
sed -i 's/^version = .*/version = "$(PY_VERSION)"/' control-plane-backend/pyproject.toml
cd control-plane-backend && uv lock
@echo "--- frontend ---"
cd frontend && npm version $(VERSION) --no-git-tag-version
@echo "Version updated to $(VERSION) in all components."
##@ Migration Schema Snapshots
SNAPSHOTS_DIR ?= $(CURDIR)/target/migration-snapshots
.PHONY: db-snapshots
db-snapshots: ## Dump schema after each migration for all backends into target/migration-snapshots/
@set -e; \
for dir in agentic-backend control-plane-backend knowledge-flow-backend; do \
echo "************ Snapshotting $$dir ************"; \
$(MAKE) -C $$dir db-snapshots DB_SNAPSHOTS_DIR=$(SNAPSHOTS_DIR); \
done
##@ Database Migrations (combined)
MIGRATION_COMPOSE := scripts/docker-compose.postgres.yml
PG_COMBINED_URL := postgresql+asyncpg://test:test@localhost:5433/test_migrations
SQLITE_COMBINED_DB := /tmp/fred_combined_migrations.db
AGENTIC_UV := agentic-backend/.venv/bin/uv
CP_UV := control-plane-backend/.venv/bin/uv
KF_UV := knowledge-flow-backend/.venv/bin/uv
.PHONY: db-check-combined-heads
db-check-combined-heads: ## assert each backend has exactly one Alembic head (no branch conflicts)
$(MAKE) -C agentic-backend db-check-heads
$(MAKE) -C control-plane-backend db-check-heads
$(MAKE) -C knowledge-flow-backend db-check-heads
.PHONY: db-check-combined-postgres-up
db-check-combined-postgres-up: ## start the PostgreSQL container for combined migration checks
docker compose -f $(MIGRATION_COMPOSE) up -d --wait
.PHONY: db-check-combined-postgres-down
db-check-combined-postgres-down: ## stop and wipe the PostgreSQL container for combined migration checks
docker compose -f $(MIGRATION_COMPOSE) down -v
.PHONY: db-check-combined-sqlite
db-check-combined-sqlite: ## upgrade all backends against the same SQLite DB, check for drift, then downgrade
@echo "=== Combined SQLite migration check: upgrade ==="
@rm -f $(SQLITE_COMBINED_DB)
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(AGENTIC_UV) run --directory agentic-backend alembic upgrade head
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(CP_UV) run --directory control-plane-backend alembic upgrade head
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(KF_UV) run --directory knowledge-flow-backend alembic upgrade head
@echo "=== Combined SQLite migration check: drift check ==="
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(AGENTIC_UV) run --directory agentic-backend alembic check
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(CP_UV) run --directory control-plane-backend alembic check
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(KF_UV) run --directory knowledge-flow-backend alembic check
@echo "=== Combined SQLite migration check: downgrade ==="
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(KF_UV) run --directory knowledge-flow-backend alembic downgrade base
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(CP_UV) run --directory control-plane-backend alembic downgrade base
DATABASE_URL="sqlite+aiosqlite:///$(SQLITE_COMBINED_DB)" $(AGENTIC_UV) run --directory agentic-backend alembic downgrade base
@rm -f $(SQLITE_COMBINED_DB)
@echo "=== Combined SQLite migration check passed ==="
.PHONY: db-check-combined-postgres
db-check-combined-postgres: db-check-combined-postgres-down db-check-combined-postgres-up ## upgrade all backends against the same DB, check for drift, then downgrade
@echo "=== Combined migration check: upgrade ==="
DATABASE_URL="$(PG_COMBINED_URL)" $(AGENTIC_UV) run --directory agentic-backend alembic upgrade head
DATABASE_URL="$(PG_COMBINED_URL)" $(CP_UV) run --directory control-plane-backend alembic upgrade head
DATABASE_URL="$(PG_COMBINED_URL)" $(KF_UV) run --directory knowledge-flow-backend alembic upgrade head
@echo "=== Combined migration check: drift check ==="
DATABASE_URL="$(PG_COMBINED_URL)" $(AGENTIC_UV) run --directory agentic-backend alembic check
DATABASE_URL="$(PG_COMBINED_URL)" $(CP_UV) run --directory control-plane-backend alembic check
DATABASE_URL="$(PG_COMBINED_URL)" $(KF_UV) run --directory knowledge-flow-backend alembic check
@echo "=== Combined migration check: downgrade ==="
DATABASE_URL="$(PG_COMBINED_URL)" $(KF_UV) run --directory knowledge-flow-backend alembic downgrade base
DATABASE_URL="$(PG_COMBINED_URL)" $(CP_UV) run --directory control-plane-backend alembic downgrade base
DATABASE_URL="$(PG_COMBINED_URL)" $(AGENTIC_UV) run --directory agentic-backend alembic downgrade base
@echo "=== Combined migration check passed ==="
$(MAKE) db-check-combined-postgres-down
include scripts/makefiles/help.mk
# =============================================================================
# k3d local deployment
# =============================================================================
K3D_CLUSTER ?= fred
K3D_NAMESPACE ?= fred
HELM_RELEASE ?= fred-app
HELM_CHART ?= deploy/charts/fred
HELM_VALUES ?= deploy/local/k3d/values-local.yaml
HELM_VALUES_BENCH ?= deploy/local/k3d/values-bench.yaml
# Image names (must match values-local.yaml)
AGENTIC_IMAGE ?= ghcr.io/thalesgroup/fred-agent/agentic-backend:0.1
KF_IMAGE ?= ghcr.io/thalesgroup/fred-agent/knowledge-flow-backend:0.1
FRONTEND_IMAGE ?= ghcr.io/thalesgroup/fred-agent/frontend:0.1
CP_IMAGE ?= ghcr.io/thalesgroup/fred-agent/control-plane-backend:0.1
##@ k3d Deployment
.PHONY: k3d-build
k3d-build: ## Build Docker images for all services (in parallel)
@echo "🔨 Building all images in parallel..."
@$(MAKE) -j4 build-agentic build-kf build-frontend build-cp
.PHONY: build-agentic
build-agentic:
$(MAKE) -C agentic-backend docker-build
.PHONY: build-kf
build-kf:
$(MAKE) -C knowledge-flow-backend docker-build
.PHONY: build-frontend
build-frontend:
$(MAKE) -C frontend docker-build
.PHONY: build-cp
build-cp:
$(MAKE) -C control-plane-backend docker-build
.PHONY: k3d-import
k3d-import: ## Import Docker images into k3d cluster
@echo "📦 Importing images into k3d cluster '$(K3D_CLUSTER)'..."
k3d image import $(AGENTIC_IMAGE) $(KF_IMAGE) $(FRONTEND_IMAGE) $(CP_IMAGE) -c $(K3D_CLUSTER)
.PHONY: k3d-deploy
k3d-deploy: k3d-build k3d-import k3d-deploy-only ## Build, import, and deploy all services to k3d
.PHONY: k3d-deploy-only
k3d-deploy-only: ## Deploy/upgrade Helm chart (images must already be in k3d)
@echo "🚀 Deploying $(HELM_RELEASE) to namespace $(K3D_NAMESPACE)..."
helm upgrade --install $(HELM_RELEASE) $(HELM_CHART) \
--namespace $(K3D_NAMESPACE) \
--create-namespace \
-f $(HELM_VALUES)
@echo "🔄 Forcing pods to restart to pick up newest local images..."
kubectl rollout restart deployment -n $(K3D_NAMESPACE) agentic-backend knowledge-flow-backend frontend control-plane-backend
.PHONY: k3d-deploy-only-bench
k3d-deploy-only-bench: ## Deploy/upgrade Helm chart with local + bench values (images must already be in k3d)
@echo "🚀 Deploying $(HELM_RELEASE) bench to namespace $(K3D_NAMESPACE)..."
helm upgrade --install $(HELM_RELEASE) $(HELM_CHART) \
--namespace $(K3D_NAMESPACE) \
--create-namespace \
-f $(HELM_VALUES) \
-f $(HELM_VALUES_BENCH)
@echo "🔄 Forcing pods to restart to pick up newest local images..."
kubectl rollout restart deployment -n $(K3D_NAMESPACE) agentic-backend knowledge-flow-backend frontend control-plane-backend
# --- Selective Turbo Deploy Targets ---
.PHONY: k3d-turbo-backend
k3d-turbo-backend: build-agentic ## Turbo: build, import and roll agentic-backend ONLY
k3d image import $(AGENTIC_IMAGE) -c $(K3D_CLUSTER)
kubectl rollout restart deployment -n $(K3D_NAMESPACE) agentic-backend
.PHONY: k3d-turbo-kf
k3d-turbo-kf: build-kf ## Turbo: build, import and roll knowledge-flow-backend ONLY
k3d image import $(KF_IMAGE) -c $(K3D_CLUSTER)
kubectl rollout restart deployment -n $(K3D_NAMESPACE) knowledge-flow-backend
.PHONY: k3d-turbo-frontend
k3d-turbo-frontend: build-frontend ## Turbo: build, import and roll frontend ONLY
k3d image import $(FRONTEND_IMAGE) -c $(K3D_CLUSTER)
kubectl rollout restart deployment -n $(K3D_NAMESPACE) frontend
.PHONY: k3d-turbo-cp
k3d-turbo-cp: build-cp ## Turbo: build, import and roll control-plane-backend ONLY
k3d image import $(CP_IMAGE) -c $(K3D_CLUSTER)
kubectl rollout restart deployment -n $(K3D_NAMESPACE) control-plane-backend
.PHONY: k3d-turbo-all
k3d-turbo-all: k3d-build ## Turbo: build and import all images, then roll all deployments
k3d image import $(AGENTIC_IMAGE) $(KF_IMAGE) $(FRONTEND_IMAGE) $(CP_IMAGE) -c $(K3D_CLUSTER)
kubectl rollout restart deployment -n $(K3D_NAMESPACE) agentic-backend knowledge-flow-backend frontend control-plane-backend
.PHONY: k3d-undeploy
k3d-undeploy: ## Uninstall the Helm release
@echo "🗑️ Uninstalling $(HELM_RELEASE)..."
helm uninstall $(HELM_RELEASE) --namespace $(K3D_NAMESPACE)
.PHONY: k3d-status
k3d-status: ## Show status of pods in the fred namespace
@echo "📊 Pod status in namespace $(K3D_NAMESPACE):"
kubectl get pods -n $(K3D_NAMESPACE) -o wide
@echo ""
@echo "📊 Services:"
kubectl get svc -n $(K3D_NAMESPACE)
.PHONY: k3d-logs-agentic
k3d-logs-agentic: ## Tail logs for agentic-backend
kubectl logs -n $(K3D_NAMESPACE) -l app=agentic-backend -f --tail=100
.PHONY: k3d-logs-kf
k3d-logs-kf: ## Tail logs for knowledge-flow-backend
kubectl logs -n $(K3D_NAMESPACE) -l app=knowledge-flow-backend -f --tail=100
.PHONY: k3d-logs-frontend
k3d-logs-frontend: ## Tail logs for frontend
kubectl logs -n $(K3D_NAMESPACE) -l app=frontend -f --tail=100