#!/bin/bash # 合并前一致性检查脚本 set -e FEATURE_BRANCH="$1" TARGET_BRANCH="${2:-main}" if [[ -z "$FEATURE_BRANCH" ]]; then echo "❌ 用法: $0 [target-branch]" exit 1 fi echo "🔍 执行Feature一致性检查..." echo "分支: $FEATURE_BRANCH -> $TARGET_BRANCH" echo "================================" # 1. 基础检查 echo "1️⃣ 基础检查..." # 检查分支是否存在 if ! git rev-parse --verify "$FEATURE_BRANCH" >/dev/null 2>&1; then echo "❌ 分支 $FEATURE_BRANCH 不存在" exit 1 fi # 检查是否有未提交的更改 if ! git diff-index --quiet HEAD --; then echo "❌ 存在未提交的更改,请先提交" exit 1 fi # 2. 检查合并冲突 echo "2️⃣ 检查合并冲突..." CURRENT_BRANCH=$(git branch --show-current) git checkout "$TARGET_BRANCH" >/dev/null 2>&1 git pull origin "$TARGET_BRANCH" >/dev/null 2>&1 # 尝试合并测试 if ! git merge --no-commit --no-ff "$FEATURE_BRANCH" >/dev/null 2>&1; then echo "❌ 检测到合并冲突,请先解决冲突" git merge --abort >/dev/null 2>&1 git checkout "$CURRENT_BRANCH" >/dev/null 2>&1 exit 1 else echo "✅ 无合并冲突" git merge --abort >/dev/null 2>&1 fi git checkout "$CURRENT_BRANCH" >/dev/null 2>&1 # 3. TypeScript编译检查 echo "3️⃣ TypeScript编译检查..." if command -v tsc >/dev/null 2>&1; then if ! npx tsc --noEmit --skipLibCheck; then echo "❌ TypeScript编译失败" exit 1 fi echo "✅ TypeScript编译通过" else echo "⚠️ 未找到TypeScript编译器,跳过编译检查" fi # 4. 共享组件版本检查 echo "4️⃣ 共享组件版本检查..." check_component_compatibility() { local component_file="$1" local component_name="$2" if [[ -f "$component_file" ]]; then # 检查是否有破坏性变更 git checkout "$TARGET_BRANCH" >/dev/null 2>&1 local main_hash="" if [[ -f "$component_file" ]]; then main_hash=$(git rev-parse HEAD:"$component_file" 2>/dev/null || echo "") fi git checkout "$CURRENT_BRANCH" >/dev/null 2>&1 local feature_hash="" if [[ -f "$component_file" ]]; then feature_hash=$(git rev-parse HEAD:"$component_file" 2>/dev/null || echo "") fi if [[ -n "$main_hash" && -n "$feature_hash" && "$main_hash" != "$feature_hash" ]]; then echo " ⚠️ $component_name 在feature分支中被修改" # 检查是否为向后兼容的修改 git checkout "$TARGET_BRANCH" >/dev/null 2>&1 local main_exports=$(grep -E "^export " "$component_file" 2>/dev/null | sort || true) git checkout "$CURRENT_BRANCH" >/dev/null 2>&1 local feature_exports=$(grep -E "^export " "$component_file" 2>/dev/null | sort || true) if [[ "$main_exports" != "$feature_exports" ]]; then echo " ❌ $component_name 的导出接口发生变化,可能不兼容" return 1 else echo " ✅ $component_name 导出接口保持兼容" fi else echo " ✅ $component_name 无变更" fi fi return 0 } COMPATIBILITY_ISSUES=0 # 检查关键共享组件 check_component_compatibility "src/modules/account/AccountManager.ts" "AccountManager" || COMPATIBILITY_ISSUES=1 check_component_compatibility "src/modules/trading/PriceManager.ts" "PriceManager" || COMPATIBILITY_ISSUES=1 check_component_compatibility "src/exchanges/pacifica/PacificaProxyClient.ts" "PacificaProxyClient" || COMPATIBILITY_ISSUES=1 if [[ $COMPATIBILITY_ISSUES -eq 0 ]]; then echo "✅ 共享组件兼容性检查通过" fi # 5. 配置文件冲突检查 echo "5️⃣ 配置文件冲突检查..." check_config_conflicts() { local config_files=( "package.json" "tsconfig.json" ".env.example" "CLAUDE.md" ) local conflicts_found=0 for config_file in "${config_files[@]}"; do if [[ -f "$config_file" ]]; then git checkout "$TARGET_BRANCH" >/dev/null 2>&1 local main_config="" if [[ -f "$config_file" ]]; then main_config=$(cat "$config_file" 2>/dev/null || echo "") fi git checkout "$CURRENT_BRANCH" >/dev/null 2>&1 local feature_config="" if [[ -f "$config_file" ]]; then feature_config=$(cat "$config_file" 2>/dev/null || echo "") fi if [[ "$main_config" != "$feature_config" ]]; then echo " ⚠️ $config_file 在feature分支中被修改" # 特殊处理package.json - 检查是否只是添加依赖 if [[ "$config_file" == "package.json" ]]; then # 检查是否只是添加了新的依赖而没有修改现有的 echo " 📦 检查package.json依赖变更..." fi else echo " ✅ $config_file 无冲突" fi fi done return $conflicts_found } check_config_conflicts # 6. 运行测试 echo "6️⃣ 运行测试套件..." if [[ -f "package.json" ]] && grep -q '"test"' package.json; then if ! npm test; then echo "❌ 测试失败" exit 1 fi echo "✅ 测试通过" else echo "⚠️ 未找到测试配置,跳过测试" fi # 7. Feature特定检查 echo "7️⃣ Feature特定检查..." # 检查spec文档是否完整 SPEC_DIR="specs/${FEATURE_BRANCH}" if [[ -d "$SPEC_DIR" ]]; then local required_files=("spec.md" "plan.md" "data-model.md" "quickstart.md") local missing_files=() for file in "${required_files[@]}"; do if [[ ! -f "$SPEC_DIR/$file" ]]; then missing_files+=("$file") fi done if [[ ${#missing_files[@]} -eq 0 ]]; then echo "✅ Feature文档完整" else echo "❌ Feature文档不完整,缺失: ${missing_files[*]}" exit 1 fi else echo "❌ Feature spec目录不存在: $SPEC_DIR" exit 1 fi # 8. 最终检查总结 echo "================================" if [[ $COMPATIBILITY_ISSUES -eq 0 ]]; then echo "✅ 所有一致性检查通过" echo "🚀 $FEATURE_BRANCH 可以安全合并到 $TARGET_BRANCH" else echo "❌ 发现兼容性问题,请解决后再合并" exit 1 fi echo "" echo "📋 合并建议:" echo "1. git checkout $TARGET_BRANCH" echo "2. git pull origin $TARGET_BRANCH" echo "3. git merge --no-ff $FEATURE_BRANCH" echo "4. 运行完整测试: npm test" echo "5. git push origin $TARGET_BRANCH"