chore: 提交和推送前增加前端 TypeScript 检查
与 Docker 构建的 tsc -b 对齐,避免类型错误在服务器构建才暴露。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
# 提交前做轻量检查:Python 格式 + 前端 TypeScript。
|
||||
# 全量 pytest 放在 pre-push,避免每次 commit 都跑一遍。
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
if [ "${SKIP_TESTS:-0}" = "1" ]; then
|
||||
echo "[pre-commit] SKIP_TESTS=1,跳过检查"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
staged="$(git diff --cached --name-only --diff-filter=ACMR)"
|
||||
|
||||
python_files=()
|
||||
frontend_changed=0
|
||||
while IFS= read -r path; do
|
||||
[ -z "$path" ] && continue
|
||||
case "$path" in
|
||||
*.py)
|
||||
[ -f "$path" ] && python_files+=("$path")
|
||||
;;
|
||||
web/frontend/*)
|
||||
frontend_changed=1
|
||||
;;
|
||||
esac
|
||||
done <<< "$staged"
|
||||
|
||||
if [ "${#python_files[@]}" -gt 0 ]; then
|
||||
echo "[pre-commit] 检查 Python 格式..."
|
||||
uv run --group dev ruff format --check "${python_files[@]}"
|
||||
echo "[pre-commit] Python 格式通过"
|
||||
fi
|
||||
|
||||
if [ "$frontend_changed" -eq 1 ]; then
|
||||
.githooks/run-frontend-tsc.sh
|
||||
fi
|
||||
+16
-3
@@ -17,18 +17,27 @@ if [ "${SKIP_TESTS:-0}" = "1" ]; then
|
||||
fi
|
||||
|
||||
python_files=()
|
||||
frontend_changed=0
|
||||
while read -r local_ref local_sha remote_ref remote_sha; do
|
||||
[ -z "$local_sha" ] && continue
|
||||
if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
|
||||
changed_paths="$(git diff-tree --no-commit-id --name-only -r --root "$local_sha" -- '*.py')"
|
||||
changed_paths="$(git diff-tree --no-commit-id --name-only -r --root "$local_sha")"
|
||||
else
|
||||
changed_paths="$(git diff --name-only "$remote_sha..$local_sha" -- '*.py')"
|
||||
changed_paths="$(git diff --name-only "$remote_sha..$local_sha")"
|
||||
fi
|
||||
while IFS= read -r path; do
|
||||
[ -n "$path" ] && [ -f "$path" ] && python_files+=("$path")
|
||||
[ -z "$path" ] && continue
|
||||
case "$path" in
|
||||
*.py)
|
||||
[ -f "$path" ] && python_files+=("$path")
|
||||
;;
|
||||
web/frontend/*)
|
||||
frontend_changed=1
|
||||
;;
|
||||
esac
|
||||
done <<< "$changed_paths"
|
||||
done <<< "$push_lines"
|
||||
|
||||
@@ -38,6 +47,10 @@ if [ "${#python_files[@]}" -gt 0 ]; then
|
||||
echo "[pre-push] Python 格式通过"
|
||||
fi
|
||||
|
||||
if [ "$frontend_changed" -eq 1 ]; then
|
||||
.githooks/run-frontend-tsc.sh
|
||||
fi
|
||||
|
||||
if [ "${TYPECHECK:-0}" = "1" ]; then
|
||||
echo "[pre-push] 运行 Pyright 类型检查..."
|
||||
uv run --group dev pyright
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# 与 Docker 构建第一步对齐:tsc -b。失败则阻止提交/推送。
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(git rev-parse --show-toplevel)"
|
||||
FRONTEND="$ROOT/web/frontend"
|
||||
|
||||
if ! command -v npm >/dev/null 2>&1; then
|
||||
echo "[git-hook] 未找到 npm,无法做前端 TypeScript 检查。"
|
||||
echo "请安装 Node.js,或紧急用 git push --no-verify 绕过。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$FRONTEND"
|
||||
if [ ! -x node_modules/.bin/tsc ]; then
|
||||
echo "[git-hook] 前端依赖缺失,正在 npm ci..."
|
||||
npm ci
|
||||
fi
|
||||
|
||||
echo "[git-hook] 检查前端 TypeScript..."
|
||||
npm exec -- tsc -b --pretty false
|
||||
echo "[git-hook] TypeScript 通过"
|
||||
@@ -113,13 +113,17 @@ docker compose --profile test run --rm test
|
||||
|
||||
测试各自建 SQLite 内存库;根目录 `conftest.py` 兜底 `DATABASE_URL` / `APP_ENCRYPTION_KEY`,防止误连开发/生产库。迁移链冒烟见 `tests/test_migrations.py`。兑换、下单、支付属于写操作,默认用 mock 做契约测试,不打真实支付。
|
||||
|
||||
启用推送前门禁(Ruff + pytest):
|
||||
启用提交/推送门禁(改过前端会跑 TypeScript,与 Docker `npm run build` 的 `tsc -b` 一致):
|
||||
|
||||
```bash
|
||||
./scripts/install-git-hooks.sh
|
||||
./dev.sh frontend-check # 单独跑前端 TypeScript
|
||||
```
|
||||
|
||||
需要把 Pyright 也纳入时:`TYPECHECK=1 git push`。紧急绕过:`git push --no-verify` 或 `SKIP_TESTS=1 git push`。
|
||||
- **pre-commit**:暂存的 Python 文件做 Ruff 格式检查;改了 `web/frontend/` 则跑 `tsc -b`
|
||||
- **pre-push**:上述检查 + 全量 pytest
|
||||
- Pyright 默认不开(噪音大):`TYPECHECK=1 git push`
|
||||
- 紧急绕过:`git push --no-verify` 或 `SKIP_TESTS=1 git push`
|
||||
|
||||
## 技术栈
|
||||
|
||||
|
||||
@@ -96,6 +96,11 @@ if [ "${1:-}" = "type-check" ]; then
|
||||
exec uv run --group dev python -m pyright "$@"
|
||||
fi
|
||||
|
||||
# 与 Docker 镜像构建第一步对齐:tsc -b。
|
||||
if [ "${1:-}" = "frontend-check" ]; then
|
||||
exec "$ROOT_DIR/.githooks/run-frontend-tsc.sh"
|
||||
fi
|
||||
|
||||
BACKEND_PID=""
|
||||
FRONTEND_PID=""
|
||||
WORKER_PID=""
|
||||
|
||||
@@ -3,4 +3,8 @@ set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
git -C "$ROOT_DIR" config core.hooksPath .githooks
|
||||
echo "已启用 .githooks(Ruff 格式检查 + pytest pre-push 门禁;TYPECHECK=1 可启用 Pyright)"
|
||||
echo "已启用 .githooks:"
|
||||
echo " pre-commit: 暂存的 Python 格式 + 前端 TypeScript"
|
||||
echo " pre-push: 上述检查 + pytest"
|
||||
echo " TYPECHECK=1 git push 可额外跑 Pyright"
|
||||
echo "紧急绕过:git push --no-verify 或 SKIP_TESTS=1 git push"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"typecheck": "tsc -b",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user