202 lines
6.7 KiB
PowerShell
202 lines
6.7 KiB
PowerShell
#Requires -Version 5.1
|
||
# EasyAI Windows 更新脚本
|
||
# 拉取仓库最新代码,更新镜像并重启服务
|
||
# 用法: .\update.ps1
|
||
|
||
# 设置控制台编码为 UTF-8
|
||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
$script:LogDir = $PSScriptRoot
|
||
if (-not $script:LogDir) { $script:LogDir = $env:TEMP }
|
||
$script:LogFile = Join-Path $script:LogDir "update.ps1.log"
|
||
|
||
function Write-Log {
|
||
param([string]$Msg)
|
||
try {
|
||
$line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Msg"
|
||
Add-Content -Path $script:LogFile -Value $line -Encoding UTF8 -ErrorAction SilentlyContinue
|
||
} catch { }
|
||
}
|
||
|
||
trap {
|
||
$errMsg = $_.Exception.Message
|
||
try {
|
||
Add-Content -Path $script:LogFile -Value "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 错误: $errMsg" -Encoding UTF8 -ErrorAction SilentlyContinue
|
||
} catch { }
|
||
Write-Host ""
|
||
Write-Host "发生错误: $errMsg" -ForegroundColor Red
|
||
if ($env:CI -ne "true") { Read-Host "按 Enter 键退出" }
|
||
exit 1
|
||
}
|
||
|
||
function Wait-ForExit {
|
||
if ($env:CI -eq "true") { return }
|
||
Write-Host ""
|
||
Read-Host "按 Enter 键退出"
|
||
}
|
||
|
||
function Write-Step { param($Msg) Write-Host $Msg }
|
||
function Write-Ok { param($Msg) Write-Host " ✓ $Msg" -ForegroundColor Green }
|
||
function Write-Err { param($Msg) Write-Host "❌ $Msg" -ForegroundColor Red; throw $Msg }
|
||
function Write-Warn { param($Msg) Write-Host "⚠️ $Msg" -ForegroundColor Yellow }
|
||
|
||
# -h/--help
|
||
if ($args -contains "-h" -or $args -contains "--help") {
|
||
Write-Host "用法: .\update.ps1"
|
||
Write-Host ""
|
||
Write-Host "脚本将提示选择更新方式,默认拉取仓库并更新镜像。"
|
||
exit 0
|
||
}
|
||
|
||
# 进入项目目录
|
||
$scriptDir = $PSScriptRoot
|
||
if (-not $scriptDir) { Write-Err "无法获取脚本所在目录" }
|
||
$composePath = Join-Path $scriptDir "docker-compose.yml"
|
||
if (-not (Test-Path $composePath)) { Write-Err "未找到 docker-compose.yml,请在 easyai 目录下运行 update.ps1" }
|
||
Set-Location $scriptDir
|
||
Write-Step "📁 项目目录: $scriptDir"
|
||
|
||
# ==================== 命令行内选择 ====================
|
||
Write-Host ""
|
||
Write-Host "请选择更新方式:"
|
||
Write-Host " [1] 更新并拉取仓库(git pull)+ 更新镜像并重启(默认)"
|
||
Write-Host " [2] 仅更新镜像并重启(跳过 git pull)"
|
||
$choice = Read-Host "请选择 [1/2,回车默认 1]"
|
||
if ([string]::IsNullOrWhiteSpace($choice)) { $choice = "1" }
|
||
|
||
$skipRepoUpdate = $false
|
||
switch ($choice) {
|
||
"2" { $skipRepoUpdate = $true }
|
||
"1" { }
|
||
default {
|
||
Write-Warn "无效选择,将使用默认:更新并拉取仓库"
|
||
$skipRepoUpdate = $false
|
||
}
|
||
}
|
||
|
||
# ==================== 拉取仓库 ====================
|
||
if (-not $skipRepoUpdate) {
|
||
Write-Host ""
|
||
Write-Host "==========================="
|
||
Write-Host "📥 拉取仓库最新代码"
|
||
Write-Host "==========================="
|
||
|
||
if (-not (Test-Path ".git")) {
|
||
Write-Err "当前目录不是 Git 仓库,请使用 git clone 克隆项目后使用 update.ps1"
|
||
}
|
||
|
||
Write-Step "📥 正在执行 git pull..."
|
||
try {
|
||
$output = git pull 2>&1
|
||
if ($LASTEXITCODE -ne 0) { throw "git pull 返回 $LASTEXITCODE" }
|
||
Write-Ok "仓库已更新到最新版本"
|
||
} catch {
|
||
Write-Err "git pull 失败,请检查网络或远程仓库配置"
|
||
}
|
||
|
||
# 确保环境配置文件存在
|
||
Write-Host ""
|
||
Write-Step "📝 检查环境配置文件..."
|
||
if (-not (Test-Path ".env") -and (Test-Path ".env.sample")) {
|
||
Copy-Item ".env.sample" ".env"
|
||
Write-Ok ".env"
|
||
}
|
||
if (-not (Test-Path ".env.tools") -and (Test-Path ".env.tools.sample")) {
|
||
Copy-Item ".env.tools.sample" ".env.tools"
|
||
Write-Ok ".env.tools"
|
||
}
|
||
if (-not (Test-Path ".env.ASG") -and (Test-Path ".env.ASG.sample")) {
|
||
Copy-Item ".env.ASG.sample" ".env.ASG"
|
||
Write-Ok ".env.ASG"
|
||
}
|
||
if (-not (Test-Path ".env.AMS") -and (Test-Path ".env.AMS.sample")) {
|
||
Copy-Item ".env.AMS.sample" ".env.AMS"
|
||
Write-Ok ".env.AMS"
|
||
}
|
||
|
||
Write-Host ""
|
||
} else {
|
||
Write-Host ""
|
||
Write-Step "⏭️ 跳过仓库更新,仅更新镜像并重启"
|
||
Write-Host ""
|
||
}
|
||
|
||
# ==================== Docker 检查 ====================
|
||
function Test-DockerInstalled {
|
||
$docker = Get-Command docker -ErrorAction SilentlyContinue
|
||
if (-not $docker) { return $false }
|
||
try { $null = & docker --version 2>&1; return $true } catch { return $false }
|
||
}
|
||
|
||
function Test-DockerRunning {
|
||
param([int]$TimeoutSeconds = 10)
|
||
try {
|
||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
||
$psi.FileName = "docker"; $psi.Arguments = "info"
|
||
$psi.RedirectStandardOutput = $true; $psi.RedirectStandardError = $true
|
||
$psi.UseShellExecute = $false; $psi.CreateNoWindow = $true
|
||
$p = [System.Diagnostics.Process]::Start($psi)
|
||
$exited = $p.WaitForExit($TimeoutSeconds * 1000)
|
||
if (-not $exited) { try { $p.Kill() } catch { }; return $false }
|
||
return ($p.ExitCode -eq 0)
|
||
} catch { return $false }
|
||
}
|
||
|
||
function Ensure-DockerRunning {
|
||
if (-not (Test-DockerInstalled)) { return $false }
|
||
if (Test-DockerRunning) {
|
||
Write-Ok "Docker 引擎已运行"
|
||
$v = docker --version 2>$null; if ($v) { Write-Host " $v" }
|
||
return $true
|
||
}
|
||
Write-Warn "Docker 未运行,请手动启动 Docker Desktop 后重新执行"
|
||
return $false
|
||
}
|
||
|
||
Write-Host "==========================="
|
||
Write-Host "🚀 检查 Docker"
|
||
Write-Host "==========================="
|
||
Write-Host ""
|
||
|
||
if (-not (Test-DockerInstalled)) {
|
||
Write-Err "未检测到 Docker,请先运行 start.ps1 完成首次部署"
|
||
}
|
||
|
||
if (-not (Ensure-DockerRunning)) {
|
||
Write-Host ""
|
||
Write-Host "请启动 Docker Desktop,确认其完全就绪后再重新运行 update.ps1"
|
||
Wait-ForExit
|
||
exit 1
|
||
}
|
||
|
||
# 检测 docker compose
|
||
$hasComposeV2 = $false
|
||
try { $null = docker compose version 2>&1; $hasComposeV2 = $true } catch { }
|
||
|
||
# ==================== 更新并启动 ====================
|
||
Write-Host ""
|
||
Write-Step "🚀 重新启动 EasyAI..."
|
||
if ($hasComposeV2) {
|
||
docker compose pull
|
||
if ($LASTEXITCODE -ne 0) { Write-Err "docker compose pull 失败" }
|
||
docker compose up -d
|
||
if ($LASTEXITCODE -ne 0) { Write-Err "docker compose up 失败" }
|
||
} else {
|
||
docker-compose pull
|
||
if ($LASTEXITCODE -ne 0) { Write-Err "docker-compose pull 失败" }
|
||
docker-compose up -d
|
||
if ($LASTEXITCODE -ne 0) { Write-Err "docker-compose up 失败" }
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "================================"
|
||
Write-Host " 更新完成"
|
||
Write-Host "================================"
|
||
Write-Host "🎉 EasyAI 应用更新成功"
|
||
Write-Host "访问地址: http://127.0.0.1:3010"
|
||
Write-Host ""
|
||
Write-Log "=== 更新完成 ==="
|
||
Wait-ForExit
|