mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-07-27 07:18:28 -06:00
Initial Attempts at Packaging Server into EXE
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@ Borealis-Server.exe
|
|||||||
|
|
||||||
# Pyinstaller Files
|
# Pyinstaller Files
|
||||||
/Data/Agent/Packaging_Data/
|
/Data/Agent/Packaging_Data/
|
||||||
/Data/Server/Packaging_Data/
|
/Data/Server/Packaging_Server/
|
||||||
|
|
||||||
# Development Folders
|
# Development Folders
|
||||||
/Server/
|
/Server/
|
||||||
|
@ -1,75 +1,88 @@
|
|||||||
#////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: <ProjectRoot>/Data/Server/Package-Borealis-Server.ps1
|
#////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: <ProjectRoot>/Data/Server/Package-Borealis-Server.ps1
|
||||||
|
|
||||||
# ------------------- CONFIGURATION -------------------
|
# ------------- Configuration -------------
|
||||||
$venvDir = "Pyinstaller_Virtual_Environment"
|
# (all paths are made absolute via Join-Path and $scriptDir)
|
||||||
$serverScript = "Server\Borealis\server.py"
|
$scriptDir = Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
$outputName = "Borealis-Server"
|
$projectRoot = Resolve-Path (Join-Path $scriptDir "..\..") # go up two levels to <ProjectRoot>\Borealis
|
||||||
$distExePath = "dist\$outputName.exe"
|
$packagingDir = Join-Path $scriptDir "Packaging_Server"
|
||||||
$buildDir = "Pyinstaller_Server_Build"
|
$venvDir = Join-Path $packagingDir "Pyinstaller_Virtual_Environment"
|
||||||
$specFile = "$outputName.spec"
|
$distDir = Join-Path $packagingDir "dist"
|
||||||
|
$buildDir = Join-Path $packagingDir "build"
|
||||||
|
$specPath = $packagingDir
|
||||||
|
|
||||||
$reactBuild = "Server\web-interface\build"
|
$serverScript = Join-Path $scriptDir "server.py"
|
||||||
$tesseractDir = "Server\Borealis\Python_API_Endpoints\Tesseract-OCR"
|
$outputName = "Borealis-Server"
|
||||||
|
$finalExeName = "$outputName.exe"
|
||||||
|
$requirementsPath = Join-Path $scriptDir "server-requirements.txt"
|
||||||
|
$iconPath = Join-Path $scriptDir "Borealis.ico"
|
||||||
|
|
||||||
# ------------------- ENV SETUP -------------------
|
# Static assets to bundle:
|
||||||
Write-Host "`n[INFO] Preparing virtual environment and dependencies..." -ForegroundColor Cyan
|
# - the compiled React build under Server/web-interface/build
|
||||||
|
$staticBuildSrc = Join-Path $projectRoot "Server\web-interface\build"
|
||||||
|
$staticBuildDst = "web-interface/build"
|
||||||
|
# - Tesseract-OCR folder must be nested under 'Borealis/Python_API_Endpoints/Tesseract-OCR'
|
||||||
|
$ocrSrc = Join-Path $scriptDir "Python_API_Endpoints\Tesseract-OCR"
|
||||||
|
$ocrDst = "Borealis/Python_API_Endpoints/Tesseract-OCR"
|
||||||
|
$soundsSrc = Join-Path $scriptDir "Sounds"
|
||||||
|
$soundsDst = "Sounds"
|
||||||
|
|
||||||
$activateScript = "$venvDir\Scripts\Activate.ps1"
|
# Embedded Python shipped under Dependencies\Python\python.exe
|
||||||
|
$embeddedPython = Join-Path $projectRoot "Dependencies\Python\python.exe"
|
||||||
|
|
||||||
if (-Not (Test-Path $activateScript)) {
|
# ------------- Prepare packaging folder -------------
|
||||||
|
if (-Not (Test-Path $packagingDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $packagingDir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1) Create or upgrade virtual environment
|
||||||
|
if (-Not (Test-Path (Join-Path $venvDir "Scripts\python.exe"))) {
|
||||||
Write-Host "[SETUP] Creating virtual environment at $venvDir"
|
Write-Host "[SETUP] Creating virtual environment at $venvDir"
|
||||||
python -m venv $venvDir
|
& $embeddedPython -m venv --upgrade-deps $venvDir
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------- ACTIVATE -------------------
|
# helper to invoke venv's python
|
||||||
Write-Host "[INFO] Activating virtual environment..."
|
$venvPy = Join-Path $venvDir "Scripts\python.exe"
|
||||||
. $activateScript
|
|
||||||
|
|
||||||
# ------------------- INSTALL DEPENDENCIES -------------------
|
# 2) Bootstrap & upgrade pip
|
||||||
Write-Host "[INFO] Installing project dependencies into virtual environment..."
|
Write-Host "[INFO] Bootstrapping pip"
|
||||||
pip install --upgrade pip > $null
|
& $venvPy -m ensurepip --upgrade
|
||||||
pip install -r requirements.txt
|
& $venvPy -m pip install --upgrade pip
|
||||||
|
|
||||||
# ------------------- INSTALL PYINSTALLER -------------------
|
# 3) Install server dependencies
|
||||||
Write-Host "[INFO] Installing PyInstaller..."
|
Write-Host "[INFO] Installing server dependencies"
|
||||||
pip install pyinstaller > $null
|
& $venvPy -m pip install -r $requirementsPath
|
||||||
|
# Ensure dnspython is available for Eventlet's greendns support
|
||||||
|
& $venvPy -m pip install dnspython
|
||||||
|
|
||||||
# Resolve PyInstaller path
|
# 4) Install PyInstaller
|
||||||
$pyInstallerPath = "$venvDir\Scripts\pyinstaller.exe"
|
Write-Host "[INFO] Installing PyInstaller"
|
||||||
|
& $venvPy -m pip install pyinstaller
|
||||||
|
|
||||||
if (-Not (Test-Path $pyInstallerPath)) {
|
# 5) Clean previous artifacts
|
||||||
Write-Host "[ERROR] PyInstaller not found even after install. Aborting." -ForegroundColor Red
|
Write-Host "[INFO] Cleaning previous artifacts"
|
||||||
exit 1
|
Remove-Item -Recurse -Force $distDir, $buildDir, "$specPath\$outputName.spec" -ErrorAction SilentlyContinue
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------- CLEANUP OLD BUILD -------------------
|
# 6) Run PyInstaller, bundling server code and assets
|
||||||
Write-Host "[INFO] Cleaning previous build artifacts..." -ForegroundColor Gray
|
# Collect all Eventlet and DNS submodules to avoid missing dynamic imports
|
||||||
Remove-Item -Recurse -Force "dist", "build", $specFile -ErrorAction SilentlyContinue
|
Write-Host "[INFO] Running PyInstaller"
|
||||||
|
& $venvPy -m PyInstaller `
|
||||||
|
--onefile `
|
||||||
|
--name $outputName `
|
||||||
|
--icon $iconPath `
|
||||||
|
--collect-submodules eventlet `
|
||||||
|
--collect-submodules dns `
|
||||||
|
--distpath $distDir `
|
||||||
|
--workpath $buildDir `
|
||||||
|
--specpath $specPath `
|
||||||
|
--add-data "$staticBuildSrc;$staticBuildDst" `
|
||||||
|
--add-data "$ocrSrc;$ocrDst" `
|
||||||
|
--add-data "$soundsSrc;$soundsDst" `
|
||||||
|
$serverScript
|
||||||
|
|
||||||
# ------------------- BUILD PYINSTALLER CMD -------------------
|
# 7) Copy the final EXE back to Data/Server
|
||||||
$reactStaticAssets = "$reactBuild;web-interface/build"
|
if (Test-Path (Join-Path $distDir $finalExeName)) {
|
||||||
$tesseractAssets = "$tesseractDir;Borealis/Python_API_Endpoints/Tesseract-OCR"
|
Copy-Item (Join-Path $distDir $finalExeName) (Join-Path $scriptDir $finalExeName) -Force
|
||||||
|
Write-Host "[SUCCESS] Server packaged at $finalExeName"
|
||||||
$cmdArgs = @(
|
|
||||||
"--onefile",
|
|
||||||
"--noconfirm",
|
|
||||||
"--name", "$outputName",
|
|
||||||
"--add-data", "`"$reactStaticAssets`"",
|
|
||||||
"--add-data", "`"$tesseractAssets`"",
|
|
||||||
"--hidden-import=eventlet",
|
|
||||||
"--clean",
|
|
||||||
"`"$serverScript`""
|
|
||||||
)
|
|
||||||
|
|
||||||
$arguments = $cmdArgs -join " "
|
|
||||||
|
|
||||||
Write-Host "`n[INFO] Running PyInstaller with Start-Process..." -ForegroundColor Yellow
|
|
||||||
Start-Process -FilePath $pyInstallerPath -ArgumentList $arguments -Wait -NoNewWindow
|
|
||||||
|
|
||||||
# ------------------- DONE -------------------
|
|
||||||
if (Test-Path $distExePath) {
|
|
||||||
Write-Host "`n[SUCCESS] Packaging complete!"
|
|
||||||
Write-Host " Output: $distExePath" -ForegroundColor Green
|
|
||||||
} else {
|
} else {
|
||||||
Write-Host "`n[FAILURE] Packaging failed." -ForegroundColor Red
|
Write-Host "[FAILURE] Packaging failed." -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
Folder Structure:
|
#////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: <ProjectRoot>/project_directory_tree.txt
|
||||||
|
|
||||||
|
Folder Structure:
|
||||||
├── Dependencies
|
├── Dependencies
|
||||||
├── Launch-Borealis.ps1
|
├── Launch-Borealis.ps1
|
||||||
├── Launch-Borealis.sh
|
├── Launch-Borealis.sh
|
||||||
|
Reference in New Issue
Block a user