Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
146 lines (109 loc) · 5.52 KB
/
Copy pathMakefile
File metadata and controls
146 lines (109 loc) · 5.52 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
# BuyPilot-AI 运维 Makefile
# 从项目根目录执行
SHELL := /bin/bash
COMPOSE := docker compose -f deploy/docker-compose.yml -f deploy/docker-compose.cloudflare.yml --env-file .env
.PHONY: help up down rebuild restart logs logs-all ps wipe-db reset seed-image seed-text smoke health db-stats shell db-shell test test-local lint protocol-check cd-setup cd-status cd-run cd-logs cd-uninstall
help: ## 显示帮助
@echo "BuyPilot-AI 运维命令"
@echo ""
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
# ── 生命周期 ──────────────────────────────────────
up: ## 启动所有服务(不重建镜像)
$(COMPOSE) up -d
down: ## 停止所有服务(保留数据卷)
$(COMPOSE) down
rebuild: ## 重建镜像并启动
$(COMPOSE) up --build -d
restart: ## 重启 api 服务
$(COMPOSE) restart api
logs: ## 查看 api 日志(tail 50)
$(COMPOSE) logs --tail=50 api
logs-all: ## 查看所有服务日志
$(COMPOSE) logs --tail=100
ps: ## 查看容器状态
$(COMPOSE) ps
# ── 数据库 ────────────────────────────────────────
wipe-db: ## 删除数据库卷(⚠️ 丢失所有数据)
$(COMPOSE) down -v
@echo "数据库卷已删除,重新 rebuild 将自动 seed"
reset: ## 删库 + 重建镜像 + seed(全量重置)
$(COMPOSE) down -v
$(COMPOSE) up --build -d
@echo "等待 api 健康..."
@sleep 15
$(COMPOSE) logs --tail=30 api
# ── 数据与索引 ────────────────────────────────────
seed-image: ## 构建图片 embedding 索引(需要百炼 API Key)
$(COMPOSE) exec api python -m src.scripts.reindex_image_embeddings
seed-text: ## 重建 text chunk embedding(通常不需要,auto seed 已覆盖)
$(COMPOSE) exec api python -m src.scripts.reindex_embeddings
# ── 验证 ──────────────────────────────────────────
smoke: ## 运行 live RAG smoke test
$(COMPOSE) exec api python -m src.scripts.smoke_live_rag
health: ## 检查 API 健康状态
@curl -sf http://localhost:8000/health | python3 -m json.tool || echo "❌ API 不可达"
eval: ## 触发评测(需要 Docker 已启动)
@curl -sf http://localhost:8000/health > /dev/null || \
(echo "❌ API 不可达,先运行 make rebuild" && exit 1); \
curl -s -X POST "http://localhost:8000/admin/eval/runs" \
-H "Authorization: Bearer $$(grep ADMIN_API_KEY .env | cut -d= -f2)" \
-H "Content-Type: application/json" \
-d '{"strategy_tag": "baseline"}' | python3 -m json.tool; \
echo ""; \
echo "评测结果: http://localhost:8000/admin/eval/runs"
define DB_STATS_PY
import asyncio
from sqlmodel import select, func
from src.repos.database import get_session
from src.repos.models import Product, ProductChunk, Conversation
async def s():
async for db in get_session():
for m,n in [(Product,'products'),(ProductChunk,'chunks'),(Conversation,'conversations')]:
r = await db.exec(select(func.count()).select_from(m))
print(f' {n}: {r.one()}')
try:
from src.repos.models import ProductImageEmbedding
r = await db.exec(select(func.count()).select_from(ProductImageEmbedding))
print(f' image_embeddings: {r.one()}')
except Exception:
print(' image_embeddings: table not found')
break
asyncio.run(s())
endef
export DB_STATS_PY
db-stats: ## 查看数据库表行数统计
$(COMPOSE) exec api python -c "$$DB_STATS_PY"
# ── 调试 ──────────────────────────────────────────
shell: ## 进入 api 容器 shell
$(COMPOSE) exec api bash
db-shell: ## 进入 postgres psql
$(COMPOSE) exec postgres psql -U buypilot -d buypilot
# ── 测试 ──────────────────────────────────────────
test: ## 在容器内运行测试
$(COMPOSE) exec api python -m pytest -q
test-local: ## 在本地 venv 运行测试
cd backend && uv run pytest -q
lint: ## 本地 ruff 检查
cd backend && uv run ruff check src tests
protocol-check: ## 三端协议一致性校验(Schema ↔ Python ↔ Kotlin)
python scripts/check_sse_protocol.py
# ── 自动部署(CD)───────────────────────────────────
cd-setup: ## 安装 cron 定时任务(每 3 分钟检测 origin/main 变更)
@chmod +x scripts/auto-deploy.sh
@(crontab -l 2>/dev/null | grep -v 'auto-deploy.sh'; echo "*/3 * * * * $(CURDIR)/scripts/auto-deploy.sh") | crontab -
@echo "✅ cron 已安装:每 3 分钟检测一次"
@echo " 查看: crontab -l"
@echo " 卸载: make cd-uninstall"
cd-status: ## 查看 CD 状态(cron 任务 + 最近日志)
@echo "── cron 任务 ──"
@crontab -l 2>/dev/null | grep auto-deploy || echo " 未安装(运行 make cd-setup)"
@echo ""
@echo "── 最近 10 条日志 ──"
@tail -10 deploy/auto-deploy.log 2>/dev/null || echo " 暂无日志"
cd-run: ## 手动触发一次检测(调试用)
scripts/auto-deploy.sh
cd-logs: ## 查看 CD 完整日志
tail -50 deploy/auto-deploy.log
cd-uninstall: ## 卸载 cron 定时任务
@(crontab -l 2>/dev/null | grep -v 'auto-deploy.sh') | crontab -
@echo "✅ cron 已卸载"