Files
roa2web-service-auto/deployment/windows/scripts/Setup-AutoDeploy.ps1
Marius Mutu 87859e5510 Add deployment automation system with build/publish workflow and fix path resolution
This commit introduces a complete deployment automation system for Windows Server deployment:

New Features:
- Publish-And-Deploy.ps1: Interactive console for building locally and transferring to server
  * Supports auto-detection of transfer method (Windows Share or SSH)
  * Configurable via deploy-config.json
  * Integrated with Build-ROA2WEB.ps1 for consistent builds
- Check-And-Deploy.ps1: Server-side auto-deployment script
  * Monitors transfer directory for new packages
  * Automatically deploys when new version detected
  * Integrates with ROA2WEB-Console.ps1 for deployment
- Setup-AutoDeploy.ps1: Configures scheduled task for auto-deployment
- DEPLOYMENT_AUTOMATION.md: Complete documentation for automation workflow

Bug Fixes:
- Fix path resolution in Publish-And-Deploy.ps1: Added Resolve-FullPath function to correctly resolve ../deploy-package path
- Fix ROA2WEB-Console.ps1 exit codes: Properly return boolean values and exit codes in non-interactive mode
- Fix Build-ROA2WEB.ps1 script copying: Added debug output and force deletion to avoid caching issues

Enhancements:
- ROA2WEB-Console.ps1: Support for ROA2WEB_SOURCE environment variable for flexible source paths
- Build-ROA2WEB.ps1: Enhanced debug output for troubleshooting script copying issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 14:59:47 +02:00

473 lines
16 KiB
PowerShell

<#
.SYNOPSIS
ROA2WEB - Auto-Deploy Setup Wizard (Server-Side)
.DESCRIPTION
Interactive wizard to configure automatic deployment monitoring on Windows Server.
Creates scheduled task that runs Check-And-Deploy.ps1 at specified intervals.
.PARAMETER MonitorPath
Path to monitor for deployment packages (default: C:\Temp)
.PARAMETER ScriptsPath
Path where Check-And-Deploy.ps1 is located (default: C:\Temp\ROA2WEB-Scripts)
.PARAMETER CheckIntervalMinutes
How often to check for new packages in minutes (default: 5)
.PARAMETER AutoDeploy
Automatically deploy new packages when found (default: true)
.PARAMETER CreateScheduledTask
Create Windows Scheduled Task for automation (default: true)
.PARAMETER NonInteractive
Run in non-interactive mode with provided parameters
.EXAMPLE
.\Setup-AutoDeploy.ps1
Launch interactive setup wizard
.EXAMPLE
.\Setup-AutoDeploy.ps1 -NonInteractive -MonitorPath "C:\Temp" -CheckIntervalMinutes 5
Non-interactive setup with defaults
.NOTES
Author: ROA2WEB Team
Version: 1.0 (Auto-Deploy Setup)
Requires: Administrator privileges, PowerShell 5.1+
#>
[CmdletBinding()]
param(
[string]$MonitorPath = "C:\Temp",
[string]$ScriptsPath = "C:\Temp\ROA2WEB-Scripts",
[int]$CheckIntervalMinutes = 5,
[bool]$AutoDeploy = $true,
[bool]$CreateScheduledTask = $true,
[switch]$NonInteractive
)
$ErrorActionPreference = "Stop"
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
function Write-Step {
param([string]$Message)
Write-Host "`n[*] $Message" -ForegroundColor Cyan
}
function Write-Success {
param([string]$Message)
Write-Host " [OK] $Message" -ForegroundColor Green
}
function Write-Error {
param([string]$Message)
Write-Host " [ERROR] $Message" -ForegroundColor Red
}
function Write-Warning {
param([string]$Message)
Write-Host " [WARN] $Message" -ForegroundColor Yellow
}
function Write-Info {
param([string]$Message)
Write-Host " [*] $Message" -ForegroundColor Yellow
}
# =============================================================================
# WIZARD FUNCTIONS
# =============================================================================
function Show-WizardWelcome {
Clear-Host
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
Write-Host " ROA2WEB - Auto-Deploy Setup Wizard" -ForegroundColor Cyan
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host ""
Write-Host " This wizard will configure automatic deployment monitoring." -ForegroundColor Yellow
Write-Host ""
Write-Host " What it does:" -ForegroundColor White
Write-Host " • Creates directory structure for auto-deployment" -ForegroundColor Gray
Write-Host " • Copies Check-And-Deploy.ps1 to scripts folder" -ForegroundColor Gray
Write-Host " • Creates Windows Scheduled Task for monitoring" -ForegroundColor Gray
Write-Host " • Configures auto-deploy settings" -ForegroundColor Gray
Write-Host ""
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host ""
Write-Host "Press any key to continue or Ctrl+C to cancel..." -ForegroundColor Yellow
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
function Get-WizardInput {
param(
[string]$Prompt,
[string]$Default,
[switch]$IsNumber,
[switch]$IsYesNo
)
do {
Write-Host "`n$Prompt" -ForegroundColor Yellow
if ($Default) {
Write-Host " Default: $Default" -ForegroundColor Gray
}
Write-Host " > " -NoNewline -ForegroundColor Cyan
$input = Read-Host
# Use default if empty
if ([string]::IsNullOrWhiteSpace($input) -and $Default) {
return $Default
}
# Validate number
if ($IsNumber) {
$num = 0
if ([int]::TryParse($input, [ref]$num) -and $num -gt 0) {
return $num
} else {
Write-Host " Invalid number. Please enter a positive integer." -ForegroundColor Red
continue
}
}
# Validate Yes/No
if ($IsYesNo) {
$normalized = $input.ToUpper()
if ($normalized -eq "Y" -or $normalized -eq "YES") {
return $true
} elseif ($normalized -eq "N" -or $normalized -eq "NO") {
return $false
} else {
Write-Host " Invalid input. Please enter Y or N." -ForegroundColor Red
continue
}
}
return $input
} while ($true)
}
# =============================================================================
# SETUP FUNCTIONS
# =============================================================================
function Test-Prerequisites {
Write-Step "Checking prerequisites..."
# Check Administrator
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
$isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
throw "This script requires Administrator privileges"
}
Write-Success "Running as Administrator"
# Check PowerShell version
if ($PSVersionTable.PSVersion.Major -lt 5) {
throw "PowerShell 5.1 or higher is required"
}
Write-Success "PowerShell version: $($PSVersionTable.PSVersion)"
# Check if Check-And-Deploy.ps1 exists
$checkDeployScript = Join-Path $PSScriptRoot "Check-And-Deploy.ps1"
if (-not (Test-Path $checkDeployScript)) {
throw "Check-And-Deploy.ps1 not found in: $PSScriptRoot"
}
Write-Success "Check-And-Deploy.ps1 found"
return $true
}
function New-DirectoryStructure {
param(
[string]$MonitorPath,
[string]$ScriptsPath
)
Write-Step "Creating directory structure..."
# Create monitor path
if (-not (Test-Path $MonitorPath)) {
New-Item -ItemType Directory -Path $MonitorPath -Force | Out-Null
Write-Success "Created: $MonitorPath"
} else {
Write-Success "Already exists: $MonitorPath"
}
# Create scripts path
if (-not (Test-Path $ScriptsPath)) {
New-Item -ItemType Directory -Path $ScriptsPath -Force | Out-Null
Write-Success "Created: $ScriptsPath"
} else {
Write-Success "Already exists: $ScriptsPath"
}
# Create logs directory
$logsPath = Join-Path $ScriptsPath "Logs"
if (-not (Test-Path $logsPath)) {
New-Item -ItemType Directory -Path $logsPath -Force | Out-Null
Write-Success "Created: $logsPath"
} else {
Write-Success "Already exists: $logsPath"
}
return $true
}
function Copy-MonitorScript {
param(
[string]$SourcePath,
[string]$DestPath
)
Write-Step "Copying Check-And-Deploy.ps1 to scripts folder..."
$sourceScript = Join-Path $SourcePath "Check-And-Deploy.ps1"
$destScript = Join-Path $DestPath "Check-And-Deploy.ps1"
# Check if source and destination are the same file
$sourceFull = (Resolve-Path $sourceScript -ErrorAction SilentlyContinue).Path
$destFull = (Resolve-Path $destScript -ErrorAction SilentlyContinue).Path
if ($sourceFull -and $destFull -and ($sourceFull -eq $destFull)) {
Write-Success "Script already in target location: $destScript"
return $destScript
}
try {
Copy-Item -Path $sourceScript -Destination $destScript -Force
Write-Success "Script copied to: $destScript"
return $destScript
} catch {
Write-Error "Failed to copy script: $_"
return $null
}
}
function New-ScheduledTaskForAutoDeployNew {
param(
[string]$ScriptPath,
[int]$IntervalMinutes,
[string]$MonitorPath
)
Write-Step "Creating Windows Scheduled Task..."
$taskName = "ROA2WEB-AutoDeploy"
# Remove existing task if present
$existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
if ($existingTask) {
Write-Info "Removing existing task..."
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
}
try {
# Create action
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`" -WatchPath `"$MonitorPath`""
# Create trigger (repeat indefinitely every X minutes)
# Note: When RepetitionDuration is not specified, the task repeats indefinitely
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
-RepetitionInterval (New-TimeSpan -Minutes $IntervalMinutes)
# Create settings
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-StartWhenAvailable `
-RunOnlyIfNetworkAvailable:$false `
-DontStopOnIdleEnd `
-MultipleInstances IgnoreNew
# Register task (run as SYSTEM)
Register-ScheduledTask -TaskName $taskName `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-User "SYSTEM" `
-RunLevel Highest `
-Description "Monitors $MonitorPath for new deployment packages and auto-deploys them" | Out-Null
Write-Success "Scheduled task created: $taskName"
Write-Success "Interval: Every $IntervalMinutes minutes"
Write-Success "User: SYSTEM"
Write-Success "Status: Enabled"
return $true
} catch {
Write-Error "Failed to create scheduled task: $_"
return $false
}
}
function Show-SetupSummary {
param(
[hashtable]$Config
)
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
Write-Host " Setup Summary" -ForegroundColor Cyan
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host ""
Write-Host " Monitor Path: $($Config.MonitorPath)" -ForegroundColor Gray
Write-Host " Scripts Path: $($Config.ScriptsPath)" -ForegroundColor Gray
Write-Host " Check Interval: $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
Write-Host " Auto-Deploy: $($Config.AutoDeploy)" -ForegroundColor Gray
Write-Host " Scheduled Task: $($Config.CreateScheduledTask)" -ForegroundColor Gray
Write-Host ""
Write-Host ("=" * 70) -ForegroundColor Cyan
Write-Host ""
Write-Host "Proceed with setup? [Y/N]: " -ForegroundColor Yellow -NoNewline
$confirm = Read-Host
return ($confirm.ToUpper() -eq "Y" -or $confirm.ToUpper() -eq "YES")
}
# =============================================================================
# MAIN SETUP FLOW
# =============================================================================
function Invoke-Setup {
param([hashtable]$Config)
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
Write-Host " Starting Setup" -ForegroundColor Cyan
Write-Host ("=" * 70) -ForegroundColor Cyan
try {
# Test prerequisites
Test-Prerequisites | Out-Null
# Create directory structure
New-DirectoryStructure -MonitorPath $Config.MonitorPath -ScriptsPath $Config.ScriptsPath | Out-Null
# Copy monitor script
$scriptPath = Copy-MonitorScript -SourcePath $PSScriptRoot -DestPath $Config.ScriptsPath
if (-not $scriptPath) {
throw "Failed to copy monitor script"
}
# Create scheduled task if requested
if ($Config.CreateScheduledTask) {
$taskSuccess = New-ScheduledTaskForAutoDeployNew `
-ScriptPath $scriptPath `
-IntervalMinutes $Config.CheckIntervalMinutes `
-MonitorPath $Config.MonitorPath
if (-not $taskSuccess) {
throw "Failed to create scheduled task"
}
}
Write-Host "`n" + ("=" * 70) -ForegroundColor Green
Write-Host " SETUP COMPLETED SUCCESSFULLY" -ForegroundColor Green
Write-Host ("=" * 70) -ForegroundColor Green
Write-Host ""
Write-Host " Next Steps:" -ForegroundColor Yellow
Write-Host " 1. Deploy packages will be placed in: $($Config.MonitorPath)" -ForegroundColor Gray
Write-Host " 2. Server will check for updates every $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
Write-Host " 3. New packages will be deployed automatically" -ForegroundColor Gray
Write-Host ""
Write-Host " Manual Testing:" -ForegroundColor Yellow
Write-Host " - Test: cd $($Config.ScriptsPath) && .\\Check-And-Deploy.ps1 -Interactive" -ForegroundColor Gray
Write-Host " - View Task: Get-ScheduledTask -TaskName 'ROA2WEB-AutoDeploy'" -ForegroundColor Gray
Write-Host ""
Write-Host ("=" * 70) -ForegroundColor Green
return $true
} catch {
Write-Host "`n" + ("=" * 70) -ForegroundColor Red
Write-Host " SETUP FAILED" -ForegroundColor Red
Write-Host ("=" * 70) -ForegroundColor Red
Write-Host ""
Write-Error $_
Write-Host ""
Write-Host ("=" * 70) -ForegroundColor Red
return $false
}
}
# =============================================================================
# MAIN EXECUTION FLOW
# =============================================================================
function Main {
# Non-interactive mode
if ($NonInteractive) {
$config = @{
MonitorPath = $MonitorPath
ScriptsPath = $ScriptsPath
CheckIntervalMinutes = $CheckIntervalMinutes
AutoDeploy = $AutoDeploy
CreateScheduledTask = $CreateScheduledTask
}
Invoke-Setup -Config $config | Out-Null
return
}
# Interactive mode - Wizard
Show-WizardWelcome
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
Write-Host " Configuration Wizard" -ForegroundColor Cyan
Write-Host ("=" * 70) -ForegroundColor Cyan
# Step 1: Monitor Path
$monitorPath = Get-WizardInput -Prompt "[1/5] Deploy Folder Path`n Path to monitor for new deployment packages:" -Default $MonitorPath
# Step 2: Scripts Path
$scriptsPath = Get-WizardInput -Prompt "[2/5] Scripts Folder Path`n Path to store monitoring scripts:" -Default $ScriptsPath
# Step 3: Check Interval
$checkInterval = Get-WizardInput -Prompt "[3/5] Check Interval`n How often to check for updates (minutes):" -Default $CheckIntervalMinutes -IsNumber
# Step 4: Auto-Deploy
Write-Host "`n[4/5] Auto-Deploy Enabled" -ForegroundColor Yellow
Write-Host " Deploy automatically when new package found?" -ForegroundColor Yellow
Write-Host " [Y] Yes (recommended) [N] No (manual trigger only)" -ForegroundColor Gray
$autoDeploy = Get-WizardInput -Prompt " Your choice:" -Default "Y" -IsYesNo
# Step 5: Scheduled Task
Write-Host "`n[5/5] Create Scheduled Task" -ForegroundColor Yellow
Write-Host " Create Windows Scheduled Task for automatic monitoring?" -ForegroundColor Yellow
Write-Host " [Y] Yes [N] No" -ForegroundColor Gray
$createTask = Get-WizardInput -Prompt " Your choice:" -Default "Y" -IsYesNo
# Configuration object
$config = @{
MonitorPath = $monitorPath
ScriptsPath = $scriptsPath
CheckIntervalMinutes = [int]$checkInterval
AutoDeploy = $autoDeploy
CreateScheduledTask = $createTask
}
# Show summary and confirm
$confirmed = Show-SetupSummary -Config $config
if ($confirmed) {
Invoke-Setup -Config $config
} else {
Write-Host "`nSetup cancelled by user" -ForegroundColor Yellow
exit 0
}
Write-Host "`nPress any key to exit..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
# Run main
Main