generated from nhcarrigan/template
3c8a46e5a6
- Add Python backend structure with FastAPI for transcription/summarization - Add React UI with audio recording, transcript, and summary views - Configure Tauri to manage Python backend lifecycle - Set up Windows cross-compilation with cargo-xwin - Add Gitea CI workflow for lint, test, and multi-platform builds - Configure ESLint, Prettier, and Vitest for code quality Note: App scaffolding only - Python env and models not yet set up
128 lines
3.4 KiB
Python
128 lines
3.4 KiB
Python
"""Build script to create a Windows executable with bundled Python environment.
|
|
|
|
This script should be run ON WINDOWS, not cross-compiled from Linux.
|
|
"""
|
|
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def main():
|
|
"""Create a Windows executable bundle for Chronara."""
|
|
project_root = Path(__file__).parent.parent
|
|
dist_dir = project_root / "dist-bundle"
|
|
|
|
print("🔨 Chronara Windows Build Script")
|
|
print("=" * 50)
|
|
print("\n⚠️ NOTE: This script must be run on Windows!")
|
|
print(" Cross-compilation from Linux is not supported.\n")
|
|
|
|
if sys.platform != "win32":
|
|
print("❌ This script must be run on Windows.")
|
|
print(" Please run this on a Windows machine or in a Windows VM.")
|
|
sys.exit(1)
|
|
|
|
# Clean previous builds
|
|
if dist_dir.exists():
|
|
print("Cleaning previous build...")
|
|
shutil.rmtree(dist_dir)
|
|
|
|
dist_dir.mkdir(exist_ok=True)
|
|
|
|
# Step 1: Create Python bundle using PyInstaller
|
|
print("\n📦 Creating Python bundle...")
|
|
|
|
# Create a temporary spec file for PyInstaller
|
|
spec_content = f"""
|
|
# -*- mode: python ; coding: utf-8 -*-
|
|
|
|
a = Analysis(
|
|
['{project_root / "src" / "backend" / "main.py"}'],
|
|
pathex=['{project_root / "src"}'],
|
|
binaries=[],
|
|
datas=[
|
|
('{project_root / "models" / "*.gguf"}', 'models'),
|
|
],
|
|
hiddenimports=['uvicorn', 'fastapi', 'whisperx', 'llama_cpp'],
|
|
hookspath=[],
|
|
hooksconfig={{}},
|
|
runtime_hooks=[],
|
|
excludes=[],
|
|
noarchive=False,
|
|
)
|
|
pyz = PYZ(a.pure)
|
|
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
a.binaries,
|
|
a.datas,
|
|
[],
|
|
name='chronara-backend',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=False,
|
|
upx_exclude=[],
|
|
runtime_tmpdir=None,
|
|
console=True,
|
|
disable_windowed_traceback=False,
|
|
argv_emulation=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
)
|
|
"""
|
|
|
|
spec_path = project_root / "chronara-backend.spec"
|
|
spec_path.write_text(spec_content)
|
|
|
|
try:
|
|
subprocess.run([
|
|
sys.executable,
|
|
"-m",
|
|
"PyInstaller",
|
|
str(spec_path),
|
|
"--clean",
|
|
"--noconfirm",
|
|
"--distpath", str(dist_dir / "backend")
|
|
], check=True)
|
|
except subprocess.CalledProcessError:
|
|
print("⚠️ PyInstaller not found. Installing...")
|
|
subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True)
|
|
subprocess.run([
|
|
sys.executable,
|
|
"-m",
|
|
"PyInstaller",
|
|
str(spec_path),
|
|
"--clean",
|
|
"--noconfirm",
|
|
"--distpath", str(dist_dir / "backend")
|
|
], check=True)
|
|
|
|
# Clean up spec file
|
|
spec_path.unlink()
|
|
|
|
# Step 2: Build Tauri app (creates NSIS installer on Windows)
|
|
print("\n🦀 Building Tauri app with NSIS installer...")
|
|
subprocess.run(
|
|
"pnpm tauri build",
|
|
cwd=project_root,
|
|
check=True,
|
|
shell=True
|
|
)
|
|
|
|
print("\n✅ Build complete!")
|
|
print("\nWindows installer (.exe) location:")
|
|
print(" src-tauri/target/release/bundle/nsis/Chronara_0.1.0_x64_en-US.exe")
|
|
print("\nThis installer includes:")
|
|
print(" - Tauri app with React frontend")
|
|
print(" - Python backend (bundled)")
|
|
print(" - Llama model files")
|
|
print(" - All dependencies")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |