Files
zyt/app/packaging
2026-08-27 16:02:38 +08:00
..
2026-08-10 17:29:05 +08:00
2026-08-27 16:02:38 +08:00
2026-08-27 14:54:18 +08:00
2026-08-22 10:46:13 +08:00
2026-08-11 09:12:51 +08:00

Video-enabled desktop packaging

The spec creates an onedir build and embeds video_companion/dist as video_companion_dist. Explicit QtWebEngine imports activate PyInstaller's maintained PySide6 hooks; the build scripts then fail if the resulting artifact does not contain QtWebEngineProcess or Chromium .pak resources.

PySide6.QtMultimedia and PySide6.QtMultimediaWidgets are also explicit hidden imports. Their maintained PyInstaller hooks collect the Python extension modules, Qt6Multimedia/Qt6MultimediaWidgets DLLs, dylibs or frameworks, plugins/multimedia, and the platform media backends. The build scripts assert those frozen files before accepting an artifact.

Both build scripts launch the frozen executable twice. --media-smoke-test is handled by a PyInstaller runtime hook before the normal application entry point: it imports both multimedia modules, constructs QMediaPlayer, QAudioOutput, and QVideoWidget, checks that a decoder backend exposes formats, runs one offscreen event-loop turn, and returns non-zero on any failure. The existing --smoke-test then validates the packaged application bootstrap. Each process uses a temporary user/config directory, loopback-only proxy settings, and a 30-second deadline; a non-zero exit or an unhandled exception in its logs fails the build.

Run the build on the target operating system. PyInstaller cannot cross-build Windows and macOS artifacts.

Brand assets

The approved source artwork is kept byte-for-byte at resources/branding/brand-master.png. app-icon.png, the multi-size Windows app-icon.ico, the macOS app-icon.icns, the login-page brand-lockup.png, and the video companion favicon are deterministic derivatives of that master. Regenerate them after replacing the approved master:

uv run --no-project --with pillow==11.3.0 python scripts/generate_brand_assets.py

The full lockup is reserved for large brand placements. Window, taskbar, shortcut, installer, uninstaller, Dock, and browser icons use the text-free pictorial mark so the identity remains legible at 1664 pixels.

Windows

.\scripts\build_windows.ps1

The default interpreter is .venv-build\Scripts\python.exe; override it with -Python C:\path\to\python.exe.

For the one-click Windows installer, portable ZIP, and SHA-256 manifest, run Build_DoctorWorkstation.bat (or double-click 一键打包_医生工作站.bat). It prepares locked dependencies, invokes the build/file/smoke gates, then compiles DoctorWorkstation-Setup-Windows-x64-<version>.exe with a pinned Inno Setup compiler. The compiler is downloaded from the official release on first use and accepted only after both its pinned SHA-256 and Authenticode signer pass validation. The portable ZIP is retained as a secondary artifact.

The current Python 3.11+/PySide6/Qt 6 runtime requires Windows 10 version 1809 or newer, so the installer declares MinVersion=10.0.17763. Do not lower that installer value to claim Windows 7 compatibility: Qt 6 does not support Windows 7. A real Windows 7 SP1 build requires a separately maintained legacy runtime (Python 3.8.10, PySide2/Qt 5.15, and a compatible freezer), plus clean Windows 7 SP1 VM validation for QtWebEngine, multimedia, installation, upgrade, and uninstall behavior.

After packaging, scripts/smoke_windows_installer.ps1 silently installs the newest Setup artifact for the current user into an isolated temporary directory, runs the installed executable's smoke gate, silently uninstalls it, and verifies that the executable was removed. It intentionally retains only its small logs and isolated user-data directory under %TEMP% for diagnosis.

To publish an automatic Windows update, open System settings → Doctor workstation update in the admin site and select Windows installer (Inno Setup EXE). Upload the generated DoctorWorkstation-Setup-Windows-x64-<version>.exe (or use an HTTPS CDN URL), then copy its SHA-256, byte size, and filename from the packaging output. New clients download and verify the installer, close themselves, run Inno Setup silently, and restart only after the installer succeeds. Existing ZIP metadata remains supported for older releases.

Automatic installer execution requires an HTTPS download with certificate verification (loopback development URLs are the only exception). Production Setup artifacts should also be Authenticode-signed before publication; the current local build can create an unsigned installer when no organization signing certificate is configured.

macOS

bash ./scripts/build_macos.sh

The default interpreter is .venv-build/bin/python. For release signing, export MACOS_CODESIGN_IDENTITY before building. The generated app includes camera/microphone usage descriptions and the main-process entitlements in macos/entitlements.plist.

For the one-click release ZIP and SHA-256 file, use package_macos.command (or 一键打包.command). All root .command files and operational scripts/*.sh files must be tracked with mode 100755; scripts/check_macos_entrypoints.sh verifies both filesystem executability and Git index mode before packaging.

Before notarization, verify the nested QtWebEngineProcess.app signature and preserve its Qt-provided helper entitlements. Sign nested code before the outer app, then notarize and staple the final distribution artifact.

.env.example is a source/deployment template and is intentionally not included in the release archives. Production endpoints and non-secret policy values should be injected into the process environment by the managed launcher/MDM. Never place passwords, tokens, UserSig, TRTC SecretKey, or other long-lived credentials in a release archive.