Files
acc-server-manager/scripts/deploy.ps1
Fran Jurmanović b1792e1c71 deploy CI
2025-07-04 19:25:34 +02:00

311 lines
9.9 KiB
PowerShell

param(
[Parameter(Mandatory=$true)]
[string]$ServerHost,
[Parameter(Mandatory=$true)]
[string]$ServerUser,
[Parameter(Mandatory=$true)]
[string]$DeployPath,
[string]$ServiceName = "ACC Server Manager",
[string]$BinaryName = "acc-server-manager",
[string]$MigrateBinaryName = "acc-migrate",
[switch]$SkipBuild,
[switch]$SkipTests,
[switch]$WhatIf
)
# Configuration
$ErrorActionPreference = "Stop"
$LocalBuildPath = ".\build"
$RemoteTempPath = "C:\temp"
function Write-Status {
param([string]$Message, [string]$Color = "Green")
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] $Message" -ForegroundColor $Color
}
function Write-Error-Status {
param([string]$Message)
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] ERROR: $Message" -ForegroundColor Red
}
function Write-Warning-Status {
param([string]$Message)
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] WARNING: $Message" -ForegroundColor Yellow
}
function Test-Prerequisites {
Write-Status "Checking prerequisites..."
# Check if Go is installed
if (-not (Get-Command go -ErrorAction SilentlyContinue)) {
throw "Go is not installed or not in PATH"
}
# Check if we can connect to the server
$testConnection = Test-NetConnection -ComputerName $ServerHost -Port 22 -WarningAction SilentlyContinue
if (-not $testConnection.TcpTestSucceeded) {
Write-Warning-Status "Cannot connect to $ServerHost on port 22. Make sure SSH is enabled."
}
Write-Status "Prerequisites check completed"
}
function Build-Application {
if ($SkipBuild) {
Write-Status "Skipping build (SkipBuild flag set)"
return
}
Write-Status "Building application..."
# Clean build directory
if (Test-Path $LocalBuildPath) {
Remove-Item -Path $LocalBuildPath -Recurse -Force
}
New-Item -ItemType Directory -Path $LocalBuildPath -Force | Out-Null
# Run tests
if (-not $SkipTests) {
Write-Status "Running tests..."
& go test -v ./...
if ($LASTEXITCODE -ne 0) {
throw "Tests failed"
}
}
# Build API for Windows
Write-Status "Building API binary..."
$env:GOOS = "windows"
$env:GOARCH = "amd64"
& go build -o "$LocalBuildPath\$BinaryName.exe" .\cmd\api
if ($LASTEXITCODE -ne 0) {
throw "Failed to build API binary"
}
# Build migration tool for Windows
Write-Status "Building migration binary..."
& go build -o "$LocalBuildPath\$MigrateBinaryName.exe" .\cmd\migrate
if ($LASTEXITCODE -ne 0) {
throw "Failed to build migration binary"
}
# Reset environment variables
Remove-Item Env:\GOOS -ErrorAction SilentlyContinue
Remove-Item Env:\GOARCH -ErrorAction SilentlyContinue
Write-Status "Build completed successfully"
}
function Copy-FilesToServer {
Write-Status "Copying files to server..."
if ($WhatIf) {
Write-Status "WHAT-IF: Would copy files to $ServerHost" -Color "Cyan"
return
}
# Copy binaries to server
scp -o StrictHostKeyChecking=no "$LocalBuildPath\$BinaryName.exe" "${ServerUser}@${ServerHost}:${RemoteTempPath}/"
if ($LASTEXITCODE -ne 0) {
throw "Failed to copy API binary to server"
}
scp -o StrictHostKeyChecking=no "$LocalBuildPath\$MigrateBinaryName.exe" "${ServerUser}@${ServerHost}:${RemoteTempPath}/"
if ($LASTEXITCODE -ne 0) {
throw "Failed to copy migration binary to server"
}
Write-Status "Files copied successfully"
}
function Deploy-ToServer {
Write-Status "Deploying to server..."
if ($WhatIf) {
Write-Status "WHAT-IF: Would deploy to $ServerHost" -Color "Cyan"
return
}
# Create deployment script
$deployScript = @"
Write-Host "Starting deployment process..." -ForegroundColor Green
# Check if service exists and stop it
`$service = Get-Service -Name '$ServiceName' -ErrorAction SilentlyContinue
if (`$service) {
Write-Host "Stopping service: $ServiceName" -ForegroundColor Yellow
Stop-Service -Name '$ServiceName' -Force
# Wait for service to stop
`$timeout = 30
`$elapsed = 0
while (`$service.Status -ne 'Stopped' -and `$elapsed -lt `$timeout) {
Start-Sleep -Seconds 1
`$elapsed++
`$service.Refresh()
}
if (`$service.Status -ne 'Stopped') {
Write-Error "Failed to stop service within timeout"
exit 1
}
Write-Host "Service stopped successfully" -ForegroundColor Green
} else {
Write-Host "Service not found: $ServiceName" -ForegroundColor Yellow
}
# Create backup of current deployment
`$backupPath = "$DeployPath\backup_`$(Get-Date -Format 'yyyyMMdd_HHmmss')"
if (Test-Path "$DeployPath\$BinaryName.exe") {
Write-Host "Creating backup at: `$backupPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path `$backupPath -Force | Out-Null
Copy-Item "$DeployPath\*" -Destination `$backupPath -Recurse -Force
}
# Copy new binaries
Write-Host "Copying new binaries to: $DeployPath" -ForegroundColor Yellow
if (-not (Test-Path "$DeployPath")) {
New-Item -ItemType Directory -Path "$DeployPath" -Force | Out-Null
}
Copy-Item "$RemoteTempPath\$BinaryName.exe" -Destination "$DeployPath\$BinaryName.exe" -Force
Copy-Item "$RemoteTempPath\$MigrateBinaryName.exe" -Destination "$DeployPath\$MigrateBinaryName.exe" -Force
# Run migrations
Write-Host "Running database migrations..." -ForegroundColor Yellow
try {
`$migrateResult = & "$DeployPath\$MigrateBinaryName.exe" 2>&1
Write-Host "Migration output: `$migrateResult" -ForegroundColor Cyan
} catch {
Write-Warning "Migration failed: `$_"
}
# Start service
if (`$service) {
Write-Host "Starting service: $ServiceName" -ForegroundColor Yellow
Start-Service -Name '$ServiceName'
# Wait for service to start
`$timeout = 30
`$elapsed = 0
while (`$service.Status -ne 'Running' -and `$elapsed -lt `$timeout) {
Start-Sleep -Seconds 1
`$elapsed++
`$service.Refresh()
}
if (`$service.Status -ne 'Running') {
Write-Error "Failed to start service within timeout"
# Rollback
Write-Host "Rolling back deployment..." -ForegroundColor Red
if (Test-Path `$backupPath) {
Copy-Item "`$backupPath\*" -Destination "$DeployPath" -Recurse -Force
Start-Service -Name '$ServiceName'
}
exit 1
}
Write-Host "Service started successfully" -ForegroundColor Green
} else {
Write-Host "Service not configured. Manual start required." -ForegroundColor Yellow
}
# Cleanup old backups (keep last 5)
`$backupDir = Split-Path "$DeployPath" -Parent
Get-ChildItem -Path `$backupDir -Directory -Name "backup_*" |
Sort-Object -Descending |
Select-Object -Skip 5 |
ForEach-Object { Remove-Item -Path "`$backupDir\`$_" -Recurse -Force }
# Cleanup temp files
Remove-Item "$RemoteTempPath\$BinaryName.exe" -Force -ErrorAction SilentlyContinue
Remove-Item "$RemoteTempPath\$MigrateBinaryName.exe" -Force -ErrorAction SilentlyContinue
Write-Host "Deployment completed successfully!" -ForegroundColor Green
"@
# Save script to temp file
$tempScript = [System.IO.Path]::GetTempFileName() + ".ps1"
$deployScript | Out-File -FilePath $tempScript -Encoding UTF8
try {
# Copy deployment script to server
scp -o StrictHostKeyChecking=no $tempScript "${ServerUser}@${ServerHost}:${RemoteTempPath}/deploy_script.ps1"
if ($LASTEXITCODE -ne 0) {
throw "Failed to copy deployment script to server"
}
# Execute deployment script on server
ssh -o StrictHostKeyChecking=no "${ServerUser}@${ServerHost}" "powershell.exe -ExecutionPolicy Bypass -File ${RemoteTempPath}/deploy_script.ps1"
if ($LASTEXITCODE -ne 0) {
throw "Deployment script failed on server"
}
# Cleanup deployment script
ssh -o StrictHostKeyChecking=no "${ServerUser}@${ServerHost}" "del ${RemoteTempPath}/deploy_script.ps1"
} finally {
# Remove temp script
Remove-Item $tempScript -Force -ErrorAction SilentlyContinue
}
Write-Status "Deployment completed successfully"
}
function Show-Usage {
Write-Host @"
ACC Server Manager Deployment Script
Usage: .\deploy.ps1 -ServerHost <host> -ServerUser <user> -DeployPath <path> [options]
Parameters:
-ServerHost Target Windows server hostname or IP
-ServerUser Username for SSH connection
-DeployPath Deployment directory on target server
-ServiceName Windows service name (default: "ACC Server Manager")
-BinaryName Main binary name (default: "acc-server-manager")
-MigrateBinaryName Migration binary name (default: "acc-migrate")
-SkipBuild Skip the build process
-SkipTests Skip running tests
-WhatIf Show what would be done without executing
Examples:
.\deploy.ps1 -ServerHost "192.168.1.100" -ServerUser "admin" -DeployPath "C:\AccServerManager"
.\deploy.ps1 -ServerHost "server.example.com" -ServerUser "deploy" -DeployPath "C:\Services\AccServerManager" -SkipTests
.\deploy.ps1 -ServerHost "192.168.1.100" -ServerUser "admin" -DeployPath "C:\AccServerManager" -WhatIf
Requirements:
- Go installed locally
- SSH client (OpenSSH)
- SCP utility
- PowerShell on target Windows server
- SSH server running on target Windows server
"@ -ForegroundColor Cyan
}
# Main execution
try {
Write-Status "Starting ACC Server Manager deployment" -Color "Cyan"
Write-Status "Target: $ServerUser@$ServerHost"
Write-Status "Deploy Path: $DeployPath"
Write-Status "Service Name: $ServiceName"
if ($WhatIf) {
Write-Status "WHAT-IF MODE: No changes will be made" -Color "Cyan"
}
Test-Prerequisites
Build-Application
Copy-FilesToServer
Deploy-ToServer
Write-Status "Deployment completed successfully!" -Color "Green"
} catch {
Write-Error-Status $_.Exception.Message
Write-Host "Deployment failed. Check the error above for details." -ForegroundColor Red
exit 1
}