77 lines
5.2 KiB
Markdown
77 lines
5.2 KiB
Markdown
# 发布打包门禁修复报告
|
||
|
||
日期:2026-08-11(Asia/Shanghai)
|
||
范围:仅 PyInstaller spec、打包/构建/入口检查脚本、发布说明、环境示例与打包专属测试;未修改 UI、core 或 repository,未执行完整 PyInstaller。
|
||
|
||
## 结论
|
||
|
||
`release_packaging_audit.md` 中除 Git 工作树/提交状态和 macOS Git executable mode 本身之外的 QtMultimedia 发布门禁已经落到代码与合同测试中:
|
||
|
||
- spec 显式列出 `PySide6.QtMultimedia`、`PySide6.QtMultimediaWidgets`,从而强制触发 PyInstaller 官方 PySide6 hooks,收集对应 Python 扩展、`Qt6Multimedia`/`Qt6MultimediaWidgets` DLL、dylib/framework、`plugins/multimedia` 以及平台媒体后端。
|
||
- 新增 PyInstaller runtime hook:冻结程序收到 `--media-smoke-test` 时,在进入正常应用入口前真实导入两个媒体模块,实例化 `QMediaPlayer`、`QAudioOutput`、`QVideoWidget`,连接音视频输出,确认媒体 backend 可用且至少暴露一种解码格式,并在 `offscreen` Qt 事件循环中退出。任一导入、链接、backend 或事件循环失败均返回非零(固定失败码 70)。
|
||
- Windows 构建在成功前要求 `QtMultimedia.pyd`、`QtMultimediaWidgets.pyd`、`Qt6Multimedia.dll`、`Qt6MultimediaWidgets.dll`、`plugins/multimedia/ffmpegmediaplugin.dll` 和 `windowsmediaplugin.dll`,随后依次运行冻结媒体门禁与原应用 `--smoke-test`。
|
||
- macOS 构建在成功前要求两个 Python 扩展、两个对应 framework/dylib、`plugins/multimedia` 与至少一个 `*mediaplugin*` backend,随后依次运行相同两项冻结门禁。
|
||
- 两个平台的一键 package 入口仍先调用 build;只有 build 的文件门禁和两项冻结 smoke gate 全部通过后才归档 ZIP/生成 SHA-256。
|
||
- `.env.example` 和 README 已明确:环境示例不会进入发布包,生产配置应由受控启动器/设备管理/进程环境注入,发布包不得包含密码、token、UserSig、TRTC SecretKey 等凭据。
|
||
|
||
## 主要文件
|
||
|
||
- `packaging/doctor_workstation.spec`
|
||
- `packaging/runtime_media_smoke.py`
|
||
- `scripts/build_windows.ps1`
|
||
- `scripts/package_windows.ps1`
|
||
- `scripts/build_macos.sh`
|
||
- `scripts/package_macos.sh`
|
||
- `scripts/check_macos_entrypoints.sh`
|
||
- `packaging/README.md`
|
||
- `README.md`
|
||
- `.env.example`
|
||
- `tests/test_packaging_media_gate.py`
|
||
|
||
## macOS executable mode:必须由根代理完成
|
||
|
||
本任务遵守约束,没有执行 `git add`、`git update-index` 或 `git commit`。当前 Git index 仍把下列 9 个入口记为 `100644`;根代理必须把每个文件的 index mode 精确改为 `100755`,并把 mode 变化纳入最终发布提交:
|
||
|
||
1. `run_macos.command` → `100755`
|
||
2. `package_macos.command` → `100755`
|
||
3. `一键运行.command` → `100755`
|
||
4. `一键打包.command` → `100755`
|
||
5. `scripts/build_macos.sh` → `100755`
|
||
6. `scripts/package_macos.sh` → `100755`
|
||
7. `scripts/run_macos.sh` → `100755`
|
||
8. `scripts/macos_helpers.sh` → `100755`
|
||
9. `scripts/check_macos_entrypoints.sh` → `100755`
|
||
|
||
根代理可从项目根目录执行以下精确操作(本代理未执行):
|
||
|
||
```powershell
|
||
git update-index --chmod=+x -- run_macos.command package_macos.command `
|
||
"一键运行.command" "一键打包.command" `
|
||
scripts/build_macos.sh scripts/package_macos.sh scripts/run_macos.sh `
|
||
scripts/macos_helpers.sh scripts/check_macos_entrypoints.sh
|
||
git ls-files --stage -- '*.command' 'scripts/*.sh'
|
||
```
|
||
|
||
第二条命令对上述 9 个文件必须全部显示 `100755`。`scripts/check_macos_entrypoints.sh` 现在同时检查实际 `-x` 与 Git index mode,因此 Windows/Git Bash 将文件视为可执行也不能再掩盖 `100644`。
|
||
|
||
## 已执行的轻量验证
|
||
|
||
- 源环境媒体门禁(`QT_QPA_PLATFORM=offscreen`):PASS;实际播放器、音频输出、VideoWidget 和 decoder backend 均成功创建。
|
||
- 缺少 site-packages 的隔离进程:PASS;`--media-smoke-test` 返回 70,证明缺组件不会误报成功。
|
||
- PowerShell parser:`build_windows.ps1`、`package_windows.ps1`、`run_windows.ps1` PASS。
|
||
- Git Bash `bash -n`:所有 macOS build/package/run/check/helper 与四个 `.command` PASS。
|
||
- 打包合同测试:`tests/test_packaging_media_gate.py`、`tests/test_one_click_entrypoints.py`、`tests/test_entrypoint.py`,10 passed。
|
||
- Ruff:新增 runtime hook 与打包测试 PASS。
|
||
- `git diff --check`:PASS。
|
||
|
||
## 仍需原生构建机完成的发布验收
|
||
|
||
按任务约束,本次没有运行完整 PyInstaller。最终发布仍必须:
|
||
|
||
- 在 Windows x64 原生构建机运行一键打包,确认新 onedir/ZIP 的文件门禁和冻结 `--media-smoke-test` 均通过,替换旧 `dist` 证据;
|
||
- 在目标架构 macOS 原生构建机运行一键打包,确认 `.app` framework/plugin 布局、codesign、摄像头/麦克风权限、notarization/stapling;
|
||
- 使用批准分发的 MP4(产品需要时再加 HLS)完成实际解码、画面渲染和音频输出验收;媒体 smoke gate 是 backend 准入,不替代真实播放;
|
||
- 由发布负责人审阅工作树,只从确定的 commit/tag 构建。Git 输入/提交状态属于本任务明确排除项。
|
||
|
||
补充:仓库指令引用的 `.trellis/workflow.md` 与 `.trellis/spec/` 在当前工作区不存在,因此本次无法执行 Trellis 规范审查;这不影响上述脚本合同结果。
|