|
@@ -0,0 +1,133 @@
|
|
|
|
|
+[CmdletBinding()]
|
|
|
|
|
+param(
|
|
|
|
|
+ [string]$OutputDirectory = '',
|
|
|
|
|
+ [switch]$IncludeUploads,
|
|
|
|
|
+ [switch]$IncludeDatabase,
|
|
|
|
|
+ [switch]$SkipBuild
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+$ErrorActionPreference = 'Stop'
|
|
|
|
|
+
|
|
|
|
|
+$ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
|
|
|
|
+if ([string]::IsNullOrWhiteSpace($OutputDirectory)) {
|
|
|
|
|
+ $OutputDirectory = Join-Path $ProjectRoot 'release'
|
|
|
|
|
+}
|
|
|
|
|
+$OutputDirectory = [System.IO.Path]::GetFullPath($OutputDirectory)
|
|
|
|
|
+
|
|
|
|
|
+function Require-File([string]$Path, [string]$Message) {
|
|
|
|
|
+ if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
|
|
|
|
|
+ throw "$Message`nMissing: $Path"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function Copy-OptionalFile([string]$Source, [string]$DestinationDirectory) {
|
|
|
|
|
+ if (Test-Path -LiteralPath $Source -PathType Leaf) {
|
|
|
|
|
+ Copy-Item -LiteralPath $Source -Destination $DestinationDirectory -Force
|
|
|
|
|
+ return $true
|
|
|
|
|
+ }
|
|
|
|
|
+ return $false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function Validate-YamlWindowsPaths([string]$Path) {
|
|
|
|
|
+ $lineNumber = 0
|
|
|
|
|
+ foreach ($line in Get-Content -LiteralPath $Path) {
|
|
|
|
|
+ $lineNumber++
|
|
|
|
|
+ if ($line -match ':\s*"[^"]*\\[^"]*"') {
|
|
|
|
|
+ throw "Invalid YAML path at $Path line $lineNumber. Use forward slashes (D:/data) or single quotes ('D:\data'), not a double-quoted backslash path."
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+if (-not $SkipBuild) {
|
|
|
|
|
+ if ($null -eq (Get-Command wails -ErrorAction SilentlyContinue)) {
|
|
|
|
|
+ throw 'Wails CLI was not found. Install Wails v2 before publishing.'
|
|
|
|
|
+ }
|
|
|
|
|
+ Write-Host 'Building Wails release...' -ForegroundColor Cyan
|
|
|
|
|
+ Push-Location $ProjectRoot
|
|
|
|
|
+ try {
|
|
|
|
|
+ & wails build
|
|
|
|
|
+ if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
+ throw "wails build failed with exit code $LASTEXITCODE"
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ Pop-Location
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+$BinDirectory = Join-Path $ProjectRoot 'build\bin'
|
|
|
|
|
+$Executable = Join-Path $BinDirectory 'smart-parking.exe'
|
|
|
|
|
+$Config = Join-Path $ProjectRoot 'config.yaml'
|
|
|
|
|
+Require-File $Executable 'The Wails executable was not found. Run without -SkipBuild or build the project first.'
|
|
|
|
|
+Require-File $Config 'Production config.yaml was not found.'
|
|
|
|
|
+Validate-YamlWindowsPaths $Config
|
|
|
|
|
+
|
|
|
|
|
+$ReleaseName = 'smart-parking-' + (Get-Date -Format 'yyyyMMdd-HHmmss')
|
|
|
|
|
+$ReleaseDirectory = Join-Path $OutputDirectory $ReleaseName
|
|
|
|
|
+New-Item -ItemType Directory -Path $ReleaseDirectory -Force | Out-Null
|
|
|
|
|
+
|
|
|
|
|
+Copy-Item -LiteralPath $Executable -Destination $ReleaseDirectory -Force
|
|
|
|
|
+Copy-Item -LiteralPath $Config -Destination $ReleaseDirectory -Force
|
|
|
|
|
+
|
|
|
|
|
+$PrinterDLL = Join-Path $BinDirectory 'CsnPrinterLibs.dll'
|
|
|
|
|
+if (-not (Copy-OptionalFile $PrinterDLL $ReleaseDirectory)) {
|
|
|
|
|
+ Write-Warning 'CsnPrinterLibs.dll was not found. Printing will be unavailable unless it is added before deployment.'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+if ($IncludeUploads) {
|
|
|
|
|
+ $Uploads = Join-Path $ProjectRoot 'uploads'
|
|
|
|
|
+ if (Test-Path -LiteralPath $Uploads -PathType Container) {
|
|
|
|
|
+ Copy-Item -LiteralPath $Uploads -Destination (Join-Path $ReleaseDirectory 'uploads') -Recurse -Force
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Write-Warning 'uploads directory was not found; no local images were included.'
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+if ($IncludeDatabase) {
|
|
|
|
|
+ $AppData = [Environment]::GetFolderPath([Environment+SpecialFolder]::ApplicationData)
|
|
|
|
|
+ $DatabaseDirectory = Join-Path $AppData 'smart-parking'
|
|
|
|
|
+ $Database = Join-Path $DatabaseDirectory 'lc_garage.db'
|
|
|
|
|
+ if (Test-Path -LiteralPath $Database -PathType Leaf) {
|
|
|
|
|
+ $DatabasePackageDirectory = Join-Path $ReleaseDirectory 'data\AppData\smart-parking'
|
|
|
|
|
+ New-Item -ItemType Directory -Path $DatabasePackageDirectory -Force | Out-Null
|
|
|
|
|
+ Copy-Item -LiteralPath $Database -Destination $DatabasePackageDirectory -Force
|
|
|
|
|
+ Copy-OptionalFile ($Database + '-wal') $DatabasePackageDirectory | Out-Null
|
|
|
|
|
+ Copy-OptionalFile ($Database + '-shm') $DatabasePackageDirectory | Out-Null
|
|
|
|
|
+ Write-Warning 'Database files were copied. Stop the source application before deployment to guarantee a consistent SQLite backup.'
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Write-Warning "Database was not found: $Database"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+$Readme = @"
|
|
|
|
|
+Smart Parking deployment package
|
|
|
|
|
+
|
|
|
|
|
+Contents:
|
|
|
|
|
+- smart-parking.exe: Wails desktop application
|
|
|
|
|
+- config.yaml: production configuration. Review it before first start.
|
|
|
|
|
+- CsnPrinterLibs.dll: required when the CSN ticket printer is used.
|
|
|
|
|
+
|
|
|
|
|
+Prerequisites:
|
|
|
|
|
+- Windows x64
|
|
|
|
|
+- Microsoft Edge WebView2 Evergreen Runtime
|
|
|
|
|
+- Allow inbound TCP 8888 when edge devices or the central payment machine connect to this host.
|
|
|
|
|
+
|
|
|
|
|
+Before starting:
|
|
|
|
|
+1. Set system.gate-simulator to false in config.yaml.
|
|
|
|
|
+2. Set the production MQTT, camera, and ffmpeg configuration in config.yaml.
|
|
|
|
|
+3. For Windows paths in YAML, use forward slashes (D:/SmartParking/data) or
|
|
|
|
|
+ single quotes ('D:\SmartParking\data'). Do not use double-quoted paths with
|
|
|
|
|
+ backslashes such as "D:\SmartParking\data"; YAML treats backslashes as escapes.
|
|
|
|
|
+4. Start smart-parking.exe with this folder as its working directory.
|
|
|
|
|
+
|
|
|
|
|
+Database:
|
|
|
|
|
+- Default path: %APPDATA%\smart-parking\lc_garage.db for the Windows account that starts the application.
|
|
|
|
|
+- If a data folder is included, copy data\AppData\smart-parking\* to that exact path after the application is stopped.
|
|
|
|
|
+
|
|
|
|
|
+Local images:
|
|
|
|
|
+- Copy the included uploads folder next to smart-parking.exe when historical local images must be retained.
|
|
|
|
|
+"@
|
|
|
|
|
+Set-Content -LiteralPath (Join-Path $ReleaseDirectory 'DEPLOYMENT.txt') -Value $Readme -Encoding UTF8
|
|
|
|
|
+
|
|
|
|
|
+Write-Host ''
|
|
|
|
|
+Write-Host "Release package created: $ReleaseDirectory" -ForegroundColor Green
|
|
|
|
|
+Write-Host 'Deploy the complete directory to the production machine.' -ForegroundColor Green
|