Bundle PyQtWebEngine on macOS and ship the app as a DMG
release / gui-build (linux) (push) Successful in 1m13s
release / gui-build (macos) (push) Successful in 1m15s
release / gui-build (windows) (push) Failing after 1s

pywebview[qt] no longer depends on PyQtWebEngine, so fresh CI builds
produced a macOS app without its Chromium engine that crashed on launch.
Package MediaHive.app as a compressed DMG instead of zipping the raw
onedir folder; release.py accepts .dmg artifacts.
This commit is contained in:
2026-09-22 04:07:30 +00:00
parent ff10c86e84
commit 5300fd0c9c
3 changed files with 55 additions and 20 deletions
+35 -5
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env -S uv run
"""Build the desktop GUI application and package it as a version-numbered ZIP.
"""Build the desktop GUI application and package it as a versioned ZIP/DMG.
Usage:
uv run scripts/winbuild.py
@@ -13,7 +13,7 @@ This script:
3. On Windows, downloads the latest ffmpeg.exe for bundling
4. On macOS arm64, downloads a prebuilt ffmpeg binary for bundling
4. Builds MediaHive using PyInstaller
5. Creates a ZIP file with the version number
5. Creates a versioned ZIP (Windows/Linux) or DMG (macOS) artifact
"""
import io
@@ -238,6 +238,33 @@ def create_zip(version: str) -> Path:
return zip_path
def create_dmg(version: str) -> Path:
"""Create a version-numbered DMG containing MediaHive.app (macOS only)."""
repo_root = _REPO_ROOT
app_bundle = repo_root / "build" / "MediaHive.app"
if not app_bundle.exists():
raise FileNotFoundError(f"App bundle not found: {app_bundle}")
dmg_path = repo_root / "build" / f"MediaHive-{version}-{_platform_zip_suffix()}.dmg"
dmg_path.parent.mkdir(parents=True, exist_ok=True)
dmg_path.unlink(missing_ok=True)
cmd = [
"hdiutil", "create",
"-volname", "MediaHive",
"-srcfolder", str(app_bundle),
"-ov",
"-format", "UDZO",
str(dmg_path),
]
print(f"Running: {' '.join(cmd)}")
result = subprocess.run(cmd, cwd=repo_root)
if result.returncode != 0:
raise RuntimeError(f"hdiutil failed with exit code {result.returncode}")
return dmg_path
def main() -> None:
# Windows consoles default to cp1252, which can't encode ✓/✗
sys.stdout.reconfigure(errors="replace")
@@ -258,10 +285,13 @@ def main() -> None:
)
build_wheel()
build_executable()
zip_path = create_zip(version)
if sys.platform == "darwin":
artifact_path = create_dmg(version)
else:
artifact_path = create_zip(version)
print(f"✓ Built successfully: {zip_path}")
print(f" Size: {zip_path.stat().st_size / (1024 * 1024):.1f} MB")
print(f"✓ Built successfully: {artifact_path}")
print(f" Size: {artifact_path.stat().st_size / (1024 * 1024):.1f} MB")
except (FileNotFoundError, OSError, RuntimeError, ValueError) as e:
print(f"✗ Build failed: {e}", file=sys.stderr)
sys.exit(1)