Files
pgsql-jellyfin/PublishAndDeploy.ps1
T
wjones 77e30685bb Complete multi-instance support: Phases 3–6 & deployment
- Implements Phases 3–6: session isolation, cache coordination, primary election, and file system monitor coordination for Jellyfin with PostgreSQL.
- Adds new database entities (Instance, DistributedLock, FileSystemChange) and EF model configurations.
- Includes SQL migration scripts and EF migration for all required tables, columns, and helper functions.
- Updates Device entity and JellyfinDbContext for multi-instance tracking.
- Integrates new DI services for instance registry, distributed locks, cache coordinator, and primary election.
- Adds publishing profiles (Win/Linux/FrameworkDependent) and automation script for deployment.
- Extensive documentation for architecture, setup, and publishing.
- All changes are backward compatible and build successfully.
2026-03-05 16:10:26 -05:00

270 lines
8.9 KiB
PowerShell

# PublishAndDeploy.ps1
# Automated publish and deployment script for Jellyfin multi-instance builds
param(
[ValidateSet("MultiInstance-Win-x64", "MultiInstance-Linux-x64", "MultiInstance-FrameworkDependent")]
[string]$Profile = "MultiInstance-Win-x64",
[string]$DeployPath = "D:\Program Files\Jellyfin-multiinstance",
[switch]$SkipDeploy,
[switch]$CreatePackage,
[string]$PackageOutput = ".",
[switch]$Verbose
)
$ErrorActionPreference = "Stop"
# Colors
function Write-Step {
param([string]$Message)
Write-Host "[>] $Message" -ForegroundColor Cyan
}
function Write-Success {
param([string]$Message)
Write-Host "[+] $Message" -ForegroundColor Green
}
function Write-Warning {
param([string]$Message)
Write-Host "[!] $Message" -ForegroundColor Yellow
}
function Write-Failure {
param([string]$Message)
Write-Host "[X] $Message" -ForegroundColor Red
}
# Header
Write-Host ""
Write-Host "================================================================" -ForegroundColor Cyan
Write-Host " Jellyfin Multi-Instance Publisher & Deployer" -ForegroundColor Cyan
Write-Host "================================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Profile: $Profile" -ForegroundColor White
Write-Host "Deploy Path: $DeployPath" -ForegroundColor White
Write-Host "Skip Deploy: $SkipDeploy" -ForegroundColor White
Write-Host "Create Pkg: $CreatePackage`n" -ForegroundColor White
# Validate project exists
$projectPath = "Jellyfin.Server\Jellyfin.Server.csproj"
if (-not (Test-Path $projectPath)) {
Write-Failure "Project not found: $projectPath"
Write-Host "Please run this script from the solution root directory.`n" -ForegroundColor Yellow
exit 1
}
Write-Success "Found project: $projectPath"
# Step 1: Clean
Write-Step "Cleaning previous builds..."
dotnet clean $projectPath --configuration Release --verbosity minimal
if ($LASTEXITCODE -ne 0) {
Write-Failure "Clean failed!"
exit 1
}
Write-Success "Clean completed"
# Step 2: Restore
Write-Step "Restoring NuGet packages..."
dotnet restore $projectPath --verbosity minimal
if ($LASTEXITCODE -ne 0) {
Write-Failure "Restore failed!"
exit 1
}
Write-Success "Restore completed"
# Step 3: Publish
Write-Step "Publishing with profile: $Profile..."
$verbosityArg = if ($Verbose) { "normal" } else { "minimal" }
dotnet publish $projectPath `
-p:PublishProfile=$Profile `
--configuration Release `
--verbosity $verbosityArg `
--nologo
if ($LASTEXITCODE -ne 0) {
Write-Failure "Publish failed!"
exit 1
}
Write-Success "Publish completed"
# Step 4: Verify output
$publishDir = "Jellyfin.Server\bin\Publish\$Profile"
Write-Step "Verifying publish output at: $publishDir"
if (-not (Test-Path $publishDir)) {
Write-Failure "Publish directory not found: $publishDir"
exit 1
}
$exeName = if ($Profile -like "*Win*") { "jellyfin.exe" } else { "jellyfin" }
$exePath = Join-Path $publishDir $exeName
if (-not (Test-Path $exePath)) {
Write-Failure "Executable not found: $exePath"
exit 1
}
# Verify SQL scripts
$sqlPath = Join-Path $publishDir "sql\add_multi_instance_support.sql"
if (-not (Test-Path $sqlPath)) {
Write-Warning "SQL script not found (expected at: $sqlPath)"
} else {
Write-Success "SQL scripts included"
}
# Verify documentation
$docsPath = Join-Path $publishDir "docs"
if (Test-Path $docsPath) {
$docCount = (Get-ChildItem $docsPath -Filter "*.md").Count
Write-Success "Documentation included ($docCount files)"
} else {
Write-Warning "Documentation directory not found"
}
# Get publish size
$publishSize = (Get-ChildItem $publishDir -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Success "Publish output verified (Size: $($publishSize.ToString('N2')) MB)"
# Step 5: Create package (optional)
if ($CreatePackage) {
Write-Step "Creating deployment package..."
$version = Get-Date -Format "yyyyMMdd-HHmmss"
$packageName = "Jellyfin-MultiInstance-$version.zip"
$packagePath = Join-Path $PackageOutput $packageName
Compress-Archive -Path "$publishDir\*" `
-DestinationPath $packagePath `
-CompressionLevel Optimal `
-Force
if (Test-Path $packagePath) {
$packageSize = (Get-Item $packagePath).Length / 1MB
Write-Success "Package created: $packagePath ($($packageSize.ToString('N2')) MB)"
} else {
Write-Failure "Failed to create package"
exit 1
}
}
# Step 6: Deploy (optional)
if (-not $SkipDeploy) {
Write-Step "Deploying to: $DeployPath"
# Check if jellyfin is running
$jellyfinProcess = Get-Process -Name "jellyfin" -ErrorAction SilentlyContinue
if ($jellyfinProcess) {
Write-Warning "Jellyfin is currently running (PID: $($jellyfinProcess.Id))"
$response = Read-Host "Stop Jellyfin and continue? (y/N)"
if ($response -eq 'y' -or $response -eq 'Y') {
Write-Step "Stopping Jellyfin..."
$jellyfinProcess | Stop-Process -Force
Start-Sleep -Seconds 2
Write-Success "Jellyfin stopped"
} else {
Write-Warning "Deployment cancelled by user"
exit 0
}
}
# Backup existing installation
if (Test-Path $DeployPath) {
$backupPath = "$DeployPath.backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
Write-Step "Backing up existing installation to: $backupPath"
try {
Copy-Item -Path $DeployPath -Destination $backupPath -Recurse -Force
Write-Success "Backup created"
} catch {
Write-Warning "Backup failed: $_"
$response = Read-Host "Continue without backup? (y/N)"
if ($response -ne 'y' -and $response -ne 'Y') {
exit 1
}
}
}
# Create deploy directory
if (-not (Test-Path $DeployPath)) {
New-Item -ItemType Directory -Path $DeployPath -Force | Out-Null
}
# Copy files
Write-Step "Copying files to deployment directory..."
try {
Copy-Item -Path "$publishDir\*" -Destination $DeployPath -Recurse -Force
Write-Success "Files copied successfully"
} catch {
Write-Failure "Deployment failed: $_"
exit 1
}
# Verify deployment
$deployedExe = Join-Path $DeployPath $exeName
if (Test-Path $deployedExe) {
Write-Success "Deployment verified"
} else {
Write-Failure "Deployment verification failed"
exit 1
}
Write-Success "Deployment complete!"
# Post-deployment instructions
Write-Host ""
Write-Host "================================================================" -ForegroundColor Green
Write-Host " Deployment Successful!" -ForegroundColor Green
Write-Host "================================================================" -ForegroundColor Green
Write-Host ""
Write-Host "Next Steps:" -ForegroundColor Yellow
Write-Host "1. Create database.xml in config directory" -ForegroundColor White
Write-Host " Location: " -NoNewline -ForegroundColor White
Write-Host "$DeployPath\config\database.xml" -ForegroundColor Cyan
Write-Host "`n2. Run multi-instance SQL setup (first deployment only):" -ForegroundColor White
Write-Host " psql -h YOUR_SERVER -U jellyfin -d jellyfin -f $DeployPath\sql\add_multi_instance_support.sql" -ForegroundColor Cyan
Write-Host "`n3. Start Jellyfin:" -ForegroundColor White
Write-Host " cd `"$DeployPath`"" -ForegroundColor Cyan
Write-Host " .\$exeName" -ForegroundColor Cyan
Write-Host ""
} else {
Write-Step "Skipping deployment (use -SkipDeploy:`$false to deploy)"
Write-Host ""
Write-Host "================================================================" -ForegroundColor Green
Write-Host " Publish Successful!" -ForegroundColor Green
Write-Host "================================================================" -ForegroundColor Green
Write-Host ""
Write-Host "Publish Directory:" -ForegroundColor Yellow
Write-Host " $publishDir" -ForegroundColor Cyan
Write-Host "`nTo deploy manually:" -ForegroundColor Yellow
Write-Host " Copy-Item -Path `"$publishDir\*`" -Destination `"YOUR_PATH`" -Recurse -Force" -ForegroundColor Cyan
Write-Host ""
}
# Summary
Write-Host "================================================================" -ForegroundColor Gray
Write-Host "Profile: $Profile" -ForegroundColor White
Write-Host "Published: $publishDir" -ForegroundColor White
Write-Host "Size: $($publishSize.ToString('N2')) MB" -ForegroundColor White
if ($CreatePackage) {
Write-Host "Package: $packagePath" -ForegroundColor White
}
if (-not $SkipDeploy) {
Write-Host "Deployed to: $DeployPath" -ForegroundColor White
}
Write-Host "================================================================" -ForegroundColor Gray
Write-Host ""
exit 0