Files
assist/scripts/quick_update.bat
2025-09-16 17:05:50 +01:00

286 lines
6.9 KiB
Batchfile

@echo off
REM TSP智能助手快速更新脚本 (Windows)
REM 支持热更新和完整更新
setlocal enabledelayedexpansion
REM 颜色定义
set "GREEN=[32m"
set "YELLOW=[33m"
set "RED=[31m"
set "NC=[0m"
REM 配置变量
set "APP_NAME=tsp_assistant"
set "DEPLOY_PATH=."
set "BACKUP_PATH=.\backups"
set "HEALTH_URL=http://localhost:5000/api/health"
REM 解析参数
set "ACTION=%1"
set "SOURCE_PATH=%2"
set "ENVIRONMENT=%3"
if "%ACTION%"=="" (
echo 用法: %0 {check^|hot-update^|full-update^|auto-update^|rollback} [源路径] [环境]
echo.
echo 命令说明:
echo check - 检查更新可用性
echo hot-update - 热更新(不重启服务)
echo full-update - 完整更新(重启服务)
echo auto-update - 自动更新(智能选择)
echo rollback - 回滚到指定备份
echo.
echo 环境: development, staging, production
exit /b 1
)
if "%ENVIRONMENT%"=="" set "ENVIRONMENT=production"
if "%SOURCE_PATH%"=="" set "SOURCE_PATH=."
REM 日志函数
:log_info
echo %GREEN%[INFO]%NC% %~1
goto :eof
:log_warn
echo %YELLOW%[WARN]%NC% %~1
goto :eof
:log_error
echo %RED%[ERROR]%NC% %~1
goto :eof
REM 检查更新可用性
:check_update
call :log_info "检查更新可用性..."
if not exist "%SOURCE_PATH%\version.json" (
call :log_error "源路径中未找到版本文件"
exit /b 1
)
REM 比较版本
for /f "tokens=2 delims=:" %%a in ('findstr "version" "%SOURCE_PATH%\version.json"') do (
set "NEW_VERSION=%%a"
set "NEW_VERSION=!NEW_VERSION: =!"
set "NEW_VERSION=!NEW_VERSION:"=!"
set "NEW_VERSION=!NEW_VERSION:,=!"
)
if exist "version.json" (
for /f "tokens=2 delims=:" %%a in ('findstr "version" "version.json"') do (
set "CURRENT_VERSION=%%a"
set "CURRENT_VERSION=!CURRENT_VERSION: =!"
set "CURRENT_VERSION=!CURRENT_VERSION:"=!"
set "CURRENT_VERSION=!CURRENT_VERSION:,=!"
)
) else (
set "CURRENT_VERSION=unknown"
)
if "!NEW_VERSION!"=="!CURRENT_VERSION!" (
call :log_info "没有更新可用 (当前版本: !CURRENT_VERSION!)"
) else (
call :log_info "发现更新: !CURRENT_VERSION! -> !NEW_VERSION!"
)
goto :eof
REM 创建备份
:create_backup
set "TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
set "TIMESTAMP=!TIMESTAMP: =0!"
set "BACKUP_NAME=%APP_NAME%_backup_!TIMESTAMP!"
call :log_info "创建备份: !BACKUP_NAME!"
if not exist "%BACKUP_PATH%" mkdir "%BACKUP_PATH%"
mkdir "%BACKUP_PATH%\!BACKUP_NAME!"
REM 备份应用文件
if exist "%DEPLOY_PATH%" (
call :log_info "备份应用文件..."
xcopy "%DEPLOY_PATH%\*" "%BACKUP_PATH%\!BACKUP_NAME!\" /E /I /Y
)
REM 备份数据库
if exist "%DEPLOY_PATH%\tsp_assistant.db" (
call :log_info "备份数据库..."
mkdir "%BACKUP_PATH%\!BACKUP_NAME!\database"
copy "%DEPLOY_PATH%\tsp_assistant.db" "%BACKUP_PATH%\!BACKUP_NAME!\database\"
)
call :log_info "备份完成: !BACKUP_NAME!"
echo !BACKUP_NAME!
goto :eof
REM 热更新
:hot_update
call :log_info "开始热更新..."
REM 支持热更新的文件列表
set "HOT_UPDATE_FILES=src\web\static\js\dashboard.js src\web\static\css\style.css src\web\templates\dashboard.html src\web\app.py"
set "UPDATED_COUNT=0"
for %%f in (%HOT_UPDATE_FILES%) do (
if exist "%SOURCE_PATH%\%%f" (
call :log_info "更新文件: %%f"
if not exist "%DEPLOY_PATH%\%%f" mkdir "%DEPLOY_PATH%\%%f" 2>nul
copy "%SOURCE_PATH%\%%f" "%DEPLOY_PATH%\%%f" /Y >nul
set /a UPDATED_COUNT+=1
)
)
if !UPDATED_COUNT! gtr 0 (
call :log_info "热更新完成,更新了 !UPDATED_COUNT! 个文件"
) else (
call :log_info "没有文件需要热更新"
)
goto :eof
REM 完整更新
:full_update
call :log_info "开始完整更新..."
REM 创建备份
call :create_backup
set "BACKUP_NAME=!BACKUP_NAME!"
REM 停止服务(如果运行中)
call :log_info "停止服务..."
taskkill /f /im python.exe 2>nul || echo 服务未运行
REM 更新文件
call :log_info "更新应用文件..."
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
mkdir "%DEPLOY_PATH%"
xcopy "%SOURCE_PATH%\*" "%DEPLOY_PATH%\" /E /I /Y
REM 安装依赖
call :log_info "安装依赖..."
cd "%DEPLOY_PATH%"
if exist "requirements.txt" (
pip install -r requirements.txt
)
REM 运行数据库迁移
call :log_info "运行数据库迁移..."
if exist "init_database.py" (
python init_database.py
)
REM 启动服务
call :log_info "启动服务..."
start /b python start_dashboard.py
REM 等待服务启动
call :log_info "等待服务启动..."
timeout /t 15 /nobreak >nul
REM 健康检查
call :log_info "执行健康检查..."
set "RETRY_COUNT=0"
set "MAX_RETRIES=10"
:health_check_loop
if !RETRY_COUNT! geq !MAX_RETRIES! (
call :log_error "健康检查失败,开始回滚..."
call :rollback !BACKUP_NAME!
exit /b 1
)
curl -f "%HEALTH_URL%" >nul 2>&1
if !errorlevel! equ 0 (
call :log_info "健康检查通过!"
call :log_info "更新成功!"
call :log_info "备份名称: !BACKUP_NAME!"
exit /b 0
) else (
call :log_warn "健康检查失败,重试中... (!RETRY_COUNT!/!MAX_RETRIES!)"
set /a RETRY_COUNT+=1
timeout /t 5 /nobreak >nul
goto :health_check_loop
)
REM 回滚
:rollback
set "BACKUP_NAME=%1"
if "%BACKUP_NAME%"=="" (
call :log_error "请指定备份名称"
exit /b 1
)
call :log_info "开始回滚到备份: !BACKUP_NAME!"
if not exist "%BACKUP_PATH%\!BACKUP_NAME!" (
call :log_error "备份不存在: !BACKUP_NAME!"
exit /b 1
)
REM 停止服务
call :log_info "停止服务..."
taskkill /f /im python.exe 2>nul || echo 服务未运行
REM 恢复文件
call :log_info "恢复文件..."
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
mkdir "%DEPLOY_PATH%"
xcopy "%BACKUP_PATH%\!BACKUP_NAME!\*" "%DEPLOY_PATH%\" /E /I /Y
REM 恢复数据库
if exist "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" (
call :log_info "恢复数据库..."
copy "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" "%DEPLOY_PATH%\"
)
REM 启动服务
call :log_info "启动服务..."
cd "%DEPLOY_PATH%"
start /b python start_dashboard.py
REM 等待服务启动
timeout /t 15 /nobreak >nul
REM 健康检查
curl -f "%HEALTH_URL%" >nul 2>&1
if !errorlevel! equ 0 (
call :log_info "回滚成功!"
) else (
call :log_error "回滚后健康检查失败"
exit /b 1
)
goto :eof
REM 自动更新
:auto_update
call :log_info "开始自动更新..."
REM 尝试热更新
call :hot_update
if !errorlevel! equ 0 (
call :log_info "热更新成功"
exit /b 0
)
REM 热更新失败,进行完整更新
call :log_info "热更新失败,进行完整更新..."
call :full_update
goto :eof
REM 主逻辑
if "%ACTION%"=="check" (
call :check_update
) else if "%ACTION%"=="hot-update" (
call :hot_update
) else if "%ACTION%"=="full-update" (
call :full_update
) else if "%ACTION%"=="auto-update" (
call :auto_update
) else if "%ACTION%"=="rollback" (
call :rollback "%SOURCE_PATH%"
) else (
call :log_error "未知操作: %ACTION%"
exit /b 1
)
endlocal