<# .SYNOPSIS 部署工具函数库 - 提供通用的部署辅助函数 .DESCRIPTION 包含日志记录、通知、健康检查等通用功能 #> $script:LOG_FILE = "deploy_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" $script:LOG_PATH = Join-Path $PWD.Path "logs" function Initialize-Logger { if (-not (Test-Path $LOG_PATH)) { New-Item -ItemType Directory -Path $LOG_PATH | Out-Null } $script:LOG_FILE = Join-Path $LOG_PATH "deploy_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" Write-Log "======================================" Write-Log "部署日志初始化" Write-Log "日期: $(Get-Date)" Write-Log "======================================" } function Write-Log { param( [string]$Message, [string]$Level = "INFO" ) $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' $logLine = "[$timestamp] [$Level] $Message" Add-Content -Path $script:LOG_FILE -Value $logLine -Encoding UTF8 switch ($Level) { "ERROR" { Write-Host $logLine -ForegroundColor Red } "WARN" { Write-Host $logLine -ForegroundColor Yellow } "SUCCESS" { Write-Host $logLine -ForegroundColor Green } default { Write-Host $logLine -ForegroundColor Cyan } } } function Invoke-WithRetry { param( [ScriptBlock]$Command, [int]$MaxRetries = 3, [int]$DelaySeconds = 5, [string]$OperationName ) $retryCount = 0 do { try { Write-Log "执行: $OperationName (尝试 $($retryCount + 1))" & $Command if ($LASTEXITCODE -eq 0) { Write-Log "$OperationName 成功" "SUCCESS" return $true } } catch { Write-Log "$OperationName 异常: $_" "ERROR" } $retryCount++ if ($retryCount -lt $MaxRetries) { Write-Log "等待 $DelaySeconds 秒后重试..." "WARN" Start-Sleep -Seconds $DelaySeconds } } while ($retryCount -lt $MaxRetries) Write-Log "$OperationName 失败,已重试 $MaxRetries 次" "ERROR" return $false } function Test-ServiceHealth { param( [string]$ServiceName, [string]$HealthUrl, [int]$TimeoutSeconds = 60 ) Write-Log "检查 $ServiceName 健康状态: $HealthUrl" $startTime = Get-Date while ((Get-Date) - $startTime -lt (New-TimeSpan -Seconds $TimeoutSeconds)) { try { $response = Invoke-WebRequest -Uri $HealthUrl -Method Get -TimeoutSec 10 if ($response.StatusCode -eq 200) { Write-Log "$ServiceName 健康检查通过" "SUCCESS" return $true } } catch { Write-Log "$ServiceName 健康检查中..." "INFO" } Start-Sleep -Seconds 5 } Write-Log "$ServiceName 健康检查超时" "ERROR" return $false } function Send-Notification { param( [string]$Message, [string]$Level = "INFO" ) Write-Log "发送通知: $Message" try { $webhookUrl = $env:NOTIFICATION_WEBHOOK if ($webhookUrl) { $body = @{ msgtype = "text" text = @{ content = $Message } } | ConvertTo-Json Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $body -ContentType "application/json" | Out-Null Write-Log "通知发送成功" } } catch { Write-Log "通知发送失败: $_" "WARN" } } function Get-Version { $versionOutput = & "$PSScriptRoot\auto-version.ps1" $version = $versionOutput | Where-Object { $_ -match '^\d+\.\d+\.\d+$' } if (-not $version) { $version = "1.1.0" Write-Log "获取版本失败,使用默认版本 v$version" "WARN" } return $version } function Get-ImageRegistry { return $env:IMAGE_REGISTRY ? $env:IMAGE_REGISTRY : "registry.fengzhongxing.com:5000/fzx" } function Update-PomVersion { param( [string]$ServiceName, [string]$Version, [string]$ProjectRoot ) $servicePath = Join-Path $ProjectRoot "services" $ServiceName $pomPath = Join-Path $servicePath "pom.xml" if (Test-Path $pomPath) { Write-Log "更新 $ServiceName pom.xml 版本为 v$Version" try { Push-Location $servicePath # 使用 Maven versions:set 插件更新版本号(大厂标准做法) mvn versions:set -DnewVersion=$Version -DprocessAllModules=true -DgenerateBackupPoms=false -q if ($LASTEXITCODE -eq 0) { Write-Log "$ServiceName Maven版本已更新为 v$Version" "SUCCESS" Pop-Location return $true } else { Write-Log "$ServiceName Maven版本更新失败" "ERROR" Pop-Location return $false } } catch { Write-Log "更新 $ServiceName pom.xml 失败: $_" "ERROR" Pop-Location return $false } } else { Write-Log "$pomPath 不存在" "WARN" return $false } } function Update-ComposeVersion { param( [string]$Version, [string]$ProjectRoot, [string]$Environment ) $composePath = Join-Path $ProjectRoot "infrastructure" "compose" "podman-compose.$Environment.yml" if (Test-Path $composePath) { Write-Log "更新 compose 文件版本: $composePath" $registry = Get-ImageRegistry $oldRegistryPattern = '(registry\.fengzhongxing\.com|8\.140\.221\.49):5000/fzx/' $content = Get-Content $composePath -Raw $content = $content -replace "$oldRegistryPattern(\w+-service):v\d+\.\d+\.\d+", "${registry}/`$1:v$Version" $content | Set-Content $composePath -NoNewline Write-Log "compose 文件版本已更新为 v$Version" "SUCCESS" return $true } else { Write-Log "$composePath 不存在" "WARN" return $false } } function Build-Service { param( [string]$ServiceName, [string]$ProjectRoot, [bool]$SkipTests ) $servicePath = Join-Path $ProjectRoot "services" $ServiceName if (Test-Path $servicePath) { Write-Log "构建服务: $ServiceName" $testArg = if ($SkipTests) { "-DskipTests" } else { "" } $result = Invoke-WithRetry -Command { Set-Location $servicePath mvn clean package $testArg -q } -OperationName "Maven构建 $ServiceName" -MaxRetries 2 if ($result) { Write-Log "$ServiceName 构建成功" "SUCCESS" return $true } else { Write-Log "$ServiceName 构建失败" "ERROR" return $false } } else { Write-Log "$servicePath 不存在" "WARN" return $false } } function Build-Image { param( [string]$ServiceName, [string]$Version, [string]$Environment, [string]$ProjectRoot ) $servicePath = Join-Path $ProjectRoot "services" $ServiceName if (Test-Path $servicePath) { $registry = Get-ImageRegistry $imageTag = "${registry}/$ServiceName-$Environment:v$Version" Write-Log "构建镜像: $imageTag" $result = Invoke-WithRetry -Command { podman build -t $imageTag -f "$servicePath/Containerfile" $ProjectRoot } -OperationName "构建镜像 $ServiceName" -MaxRetries 2 if ($result) { Write-Log "$ServiceName 镜像构建成功" "SUCCESS" return $true } else { Write-Log "$ServiceName 镜像构建失败" "ERROR" return $false } } else { Write-Log "$servicePath 不存在" "WARN" return $false } } function Push-Image { param( [string]$ServiceName, [string]$Version, [string]$Environment ) $registry = Get-ImageRegistry $imageTag = "${registry}/$ServiceName-$Environment:v$Version" Write-Log "推送镜像: $imageTag" $result = Invoke-WithRetry -Command { podman push --tls-verify=false $imageTag } -OperationName "推送镜像 $ServiceName" -MaxRetries 3 if ($result) { Write-Log "$ServiceName 镜像推送成功" "SUCCESS" return $true } else { Write-Log "$ServiceName 镜像推送失败" "ERROR" return $false } } function Deploy-Service { param( [string]$Environment, [string]$ProjectRoot ) $composePath = Join-Path $ProjectRoot "infrastructure" "compose" Write-Log "部署到 $Environment 环境" $result = Invoke-WithRetry -Command { Set-Location $composePath $env:COMPOSE_FILE = "podman-compose.$Environment.yml" podman-compose up -d } -OperationName "部署服务" -MaxRetries 2 if ($result) { Write-Log "部署成功" "SUCCESS" return $true } else { Write-Log "部署失败" "ERROR" return $false } } Export-ModuleMember -Function @( 'Initialize-Logger', 'Write-Log', 'Invoke-WithRetry', 'Test-ServiceHealth', 'Send-Notification', 'Get-Version', 'Get-ImageRegistry', 'Update-PomVersion', 'Update-ComposeVersion', 'Build-Service', 'Build-Image', 'Push-Image', 'Deploy-Service' )