108 lines
3.2 KiB
PowerShell
108 lines
3.2 KiB
PowerShell
param(
|
||
[string]$HostName = "1.13.22.133",
|
||
[string]$User = "root",
|
||
[string]$RemoteDir = "/opt/equipment-management",
|
||
[string]$RemoteArchive = "/tmp/equipment-management-release.tar.gz",
|
||
[switch]$SkipDeploy,
|
||
[switch]$SkipBackup
|
||
)
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||
$password = if ($env:DEPLOY_PASSWORD) { $env:DEPLOY_PASSWORD } else { "" }
|
||
$archiveName = "equipment-management-release.tar.gz"
|
||
$archivePath = Join-Path ([System.IO.Path]::GetTempPath()) $archiveName
|
||
$fileListPath = Join-Path ([System.IO.Path]::GetTempPath()) "equipment-management-files.txt"
|
||
|
||
function Get-CommandPath([string]$name) {
|
||
$cmd = Get-Command $name -ErrorAction SilentlyContinue
|
||
if (-not $cmd) {
|
||
throw "Command not found: $name"
|
||
}
|
||
return $cmd.Source
|
||
}
|
||
|
||
function Invoke-External {
|
||
param(
|
||
[string]$FilePath,
|
||
[string[]]$Arguments,
|
||
[switch]$IgnoreExitCode
|
||
)
|
||
|
||
& $FilePath @Arguments
|
||
if (-not $IgnoreExitCode -and $LASTEXITCODE -ne 0) {
|
||
throw "Command failed: $FilePath $($Arguments -join ' ')"
|
||
}
|
||
}
|
||
|
||
$tarExe = Get-CommandPath "tar"
|
||
$sshExe = Get-CommandPath "ssh"
|
||
$scpExe = Get-CommandPath "scp"
|
||
$sshpassExe = $null
|
||
|
||
if ($password) {
|
||
$sshpassExe = Get-CommandPath "sshpass"
|
||
}
|
||
|
||
Set-Location $projectRoot
|
||
|
||
$files = git ls-files --cached --others --exclude-standard
|
||
if (-not $files) {
|
||
throw "No files to publish."
|
||
}
|
||
|
||
$files | Set-Content -Path $fileListPath -Encoding utf8
|
||
|
||
if (Test-Path $archivePath) {
|
||
Remove-Item $archivePath -Force
|
||
}
|
||
|
||
Write-Host ">>> Packing repository files..."
|
||
Invoke-External -FilePath $tarExe -Arguments @("-czf", $archivePath, "-T", $fileListPath)
|
||
|
||
$remoteTarget = "$User@$HostName"
|
||
$sshBaseArgs = @("-o", "StrictHostKeyChecking=no")
|
||
$scpBaseArgs = @("-o", "StrictHostKeyChecking=no")
|
||
|
||
if ($password) {
|
||
Write-Host ">>> Using DEPLOY_PASSWORD for upload and remote execution..."
|
||
$scpArgs = @("-p", $password, $scpExe) + $scpBaseArgs + @($archivePath, "${remoteTarget}:$RemoteArchive")
|
||
Invoke-External -FilePath $sshpassExe -Arguments $scpArgs
|
||
} else {
|
||
Write-Host ">>> Using SSH key or interactive password..."
|
||
$scpArgs = $scpBaseArgs + @($archivePath, "${remoteTarget}:$RemoteArchive")
|
||
Invoke-External -FilePath $scpExe -Arguments $scpArgs
|
||
}
|
||
|
||
$skipBackupValue = if ($SkipBackup) { "1" } else { "0" }
|
||
$deployCommand = @"
|
||
set -e
|
||
mkdir -p '$RemoteDir'
|
||
cd '$RemoteDir'
|
||
rm -rf backend frontend scripts AGENTS.md BACKUP.md README.md deploy.sh docker-compose.yml Dockerfile
|
||
tar -xzf '$RemoteArchive' -C '$RemoteDir'
|
||
sed -i 's/\r$//' '$RemoteDir/deploy.sh' '$RemoteDir/scripts/backup-equipment.sh'
|
||
chmod +x '$RemoteDir/deploy.sh' '$RemoteDir/scripts/backup-equipment.sh'
|
||
if [ '$($SkipDeploy.IsPresent)' = 'True' ]; then
|
||
echo '>>> 已设置 SkipDeploy,仅同步文件,不执行部署'
|
||
else
|
||
if [ '$skipBackupValue' = '1' ]; then
|
||
SKIP_BACKUP=1 '$RemoteDir/deploy.sh'
|
||
else
|
||
'$RemoteDir/deploy.sh'
|
||
fi
|
||
fi
|
||
rm -f '$RemoteArchive'
|
||
"@
|
||
|
||
if ($password) {
|
||
$sshArgs = @("-p", $password, $sshExe) + $sshBaseArgs + @($remoteTarget, $deployCommand)
|
||
Invoke-External -FilePath $sshpassExe -Arguments $sshArgs
|
||
} else {
|
||
$sshArgs = $sshBaseArgs + @($remoteTarget, $deployCommand)
|
||
Invoke-External -FilePath $sshExe -Arguments $sshArgs
|
||
}
|
||
|
||
Write-Host ">>> Publish completed"
|