furniture-3d-system-Wu/scripts/deploy-yydd-prod-from-git.ps1

189 lines
4.6 KiB
PowerShell

param(
[string]$RepoRoot = $(Split-Path -Parent $PSScriptRoot),
[string]$Ref = "origin/main",
[string]$RemoteBase = "/opt/furniture-3d-system-prod",
[string]$ServerHost = "ltai5tdb2ogyj59fquyedh.yydd.ai",
[int]$SshPort = 60022,
[string]$ServerUser = "root",
[string]$ServerPassword = "",
[string]$HostKeyFingerprint = "SHA256:JPHcomdjuUZOTM7sNdBYg0/xRkQSXzbXe7FEfNtIFAU",
[int]$AppPort = 3001,
[string]$Pm2Name = "furniture-3d-system-prod",
[int]$KeepReleases = 5,
[switch]$KeepArtifacts
)
$ErrorActionPreference = 'Stop'
$createScript = Join-Path $RepoRoot 'scripts\create-yydd-prod-deploy.ps1'
$plinkPath = 'C:\Program Files\PuTTY\plink.exe'
$pscpPath = 'C:\Program Files\PuTTY\pscp.exe'
if (-not (Test-Path -LiteralPath $createScript)) {
throw "缺少打包脚本: $createScript"
}
if (-not (Test-Path -LiteralPath $plinkPath)) {
throw "缺少 plink.exe: $plinkPath"
}
if (-not (Test-Path -LiteralPath $pscpPath)) {
throw "缺少 pscp.exe: $pscpPath"
}
function Invoke-NativeCommand {
param(
[string]$FilePath,
[string[]]$Arguments,
[string]$WorkingDirectory = $RepoRoot
)
$previousErrorActionPreference = $ErrorActionPreference
try {
$ErrorActionPreference = 'Continue'
Push-Location -LiteralPath $WorkingDirectory
try {
$output = & $FilePath @Arguments 2>&1
$exitCode = $LASTEXITCODE
}
finally {
Pop-Location
}
$lines = @(
$output |
ForEach-Object {
if ($_ -is [System.Management.Automation.ErrorRecord]) {
$_.ToString()
}
else {
[string]$_
}
} |
Where-Object { $_.Length -gt 0 }
)
if ($exitCode -ne 0) {
throw (($lines -join [Environment]::NewLine).Trim())
}
return $lines
}
finally {
$ErrorActionPreference = $previousErrorActionPreference
}
}
function Invoke-Plink {
param(
[string]$Command
)
$arguments = @(
'-ssh'
'-batch'
'-hostkey'
$HostKeyFingerprint
'-P'
[string]$SshPort
)
if (-not [string]::IsNullOrWhiteSpace($ServerPassword)) {
$arguments += @('-pw', $ServerPassword)
}
$arguments += @(
('{0}@{1}' -f $ServerUser, $ServerHost)
$Command
)
return Invoke-NativeCommand -FilePath $plinkPath -Arguments $arguments -WorkingDirectory $RepoRoot
}
function Copy-WithPscp {
param(
[string]$LocalPath,
[string]$RemotePath
)
if (-not (Test-Path -LiteralPath $LocalPath)) {
throw "上传文件不存在: $LocalPath"
}
$arguments = @(
'-batch'
'-hostkey'
$HostKeyFingerprint
'-P'
[string]$SshPort
)
if (-not [string]::IsNullOrWhiteSpace($ServerPassword)) {
$arguments += @('-pw', $ServerPassword)
}
$arguments += @(
$LocalPath
('{0}@{1}:{2}' -f $ServerUser, $ServerHost, $RemotePath)
)
return Invoke-NativeCommand -FilePath $pscpPath -Arguments $arguments -WorkingDirectory $RepoRoot
}
$package = & $createScript `
-RepoRoot $RepoRoot `
-Ref $Ref `
-RemoteBase $RemoteBase `
-ServerHost $ServerHost `
-AppPort $AppPort `
-Pm2Name $Pm2Name `
-KeepReleases $KeepReleases
if (-not $package) {
throw '打包脚本未返回结果'
}
$archivePath = [string]$package.Archive
$scriptPath = [string]$package.Script
$remoteArchivePath = [string]$package.RemoteArchivePath
$remoteScriptPath = [string]$package.RemoteScriptPath
$remoteIncoming = ('{0}/incoming' -f $RemoteBase)
$mkdirIncomingCommand = "mkdir -p '{0}'" -f $remoteIncoming
$runDeployCommand = "chmod +x '{0}' && bash '{0}'" -f $remoteScriptPath
try {
Invoke-Plink $mkdirIncomingCommand | Out-Null
Copy-WithPscp -LocalPath $archivePath -RemotePath $remoteArchivePath | Out-Null
Copy-WithPscp -LocalPath $scriptPath -RemotePath $remoteScriptPath | Out-Null
$deployOutput = Invoke-Plink $runDeployCommand
}
finally {
if (-not $KeepArtifacts) {
try {
Invoke-Plink ("rm -f '{0}' '{1}'" -f $remoteArchivePath, $remoteScriptPath) | Out-Null
}
catch {
Write-Warning ("远端部署临时文件清理失败: {0}" -f $_.Exception.Message)
}
if (Test-Path -LiteralPath $archivePath) {
Remove-Item -LiteralPath $archivePath -Force
}
if (Test-Path -LiteralPath $scriptPath) {
Remove-Item -LiteralPath $scriptPath -Force
}
}
}
[PSCustomObject]@{
Mode = 'safe-git-release-deploy'
Ref = [string]$package.Ref
Commit = [string]$package.Commit
RemoteBase = $RemoteBase
RemoteArchivePath = $remoteArchivePath
RemoteScriptPath = $remoteScriptPath
ServerHost = $ServerHost
SshPort = $SshPort
Pm2Name = $Pm2Name
Output = ($deployOutput -join [Environment]::NewLine)
}