Skip to content

feat(packaging): frozen Qt product staging and manifest (#35) - #329

Merged
JavaZeroo merged 1 commit into
mainfrom
agent/artifact-manifest-prep-291e68b43ed7
Nov 8, 2026
Merged

JavaZeroo merged 1 commit into
mainfrom
agent/artifact-manifest-prep-291e68b43ed7

Conversation

@JavaZeroo-Bot

@JavaZeroo-Bot JavaZeroo-Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

问题与最终行为

#35 已明确允许提前开展的独立范围:为正式 C++/Qt/随包固定 ConPTY 产品(termforge_qt_shell)提供可核对的构建产物清单与可重复准备入口。基线 8506c6c;不发布 release/tag、不关闭 #35/#7、不宣称 R2 包最终验收、不触发 Codex review;#27/#28/#29/#30/#38 仍未闭合,本次不进入最终工作流验收。#324/#327 未合并,本 PR 不含其代码也未运行其失败路径。

本 PR 新增一个只接受冻结来源的工程 staging 入口,并把正式 Qt 依赖/许可/部署集合变成可机读、可复发失败的契约:

  • 新增 tools/stage_qt_product.py + tools/test_stage_qt_product.py(18 项离线契约测试)
    • stage:只接收 packaging/qt-product/manifest.json 冻结的文件集合;要求 tools.prepare_qt_build 摘要与当前仓库固定清单一致、Qt SDK 树哈希一致、ConPTY/CRT/字体按 pin 校验、构建目录每个文件与固定依赖或源码逐字节相同。
    • 缺文件、测试夹具、额外文件、来源不符、摘要过期、dirty source 都明确失败;输出目录已存在时绝不覆盖;生成的 product-manifest.json 路径无关,含 source commit/tree、构建参数、入口、逐文件 SHA-256、许可文件映射和未闭合项。
    • verify:对已生成 staging 重新核对文件集合/哈希/入口/PE 架构/许可证据。
  • 新增 packaging/qt-product/manifest.json:冻结入口、Qt 库/插件集合、OS 提供项、被排除的系统重分发文件与许可证据;新增 assets/fonts/manifest.json(字体/许可 pin 与上游固定提交)。
  • third_party/qt:记录源码归档身份(50,509,856 B,SHA-256 383dc907…,仅用于提取许可),随附从该归档提取的 LICENSES/LGPL-3.0-only.txt(7,651 B,SHA-256 da7eabb7…),并在 .gitattributes 固定其 LF 字节身份。
  • windeployqt 显式 --no-system-d3d-compiler --no-system-dxc-compiler:避免从开发机 Windows SDK/System32 借用未固定的 D3D/DXC 文件;icuuc.dll 由 Windows 11 System32 提供,构建目录中 windeployqt 复制的副本经字节比对后排除,不随包分发。
  • .github/workflows/qt-cpp.yml:构建后运行 staging + verify,并只上传路径无关的摘要、product-manifest.json 与许可索引(不上传二进制)。
  • 文档:src/qt/README.md、third_party/qt/README.md、assets/fonts/README.md、docs/FEATURES.md 更新入口与仍未完成的验收边界。

验证

本地 Windows 11 x64、独立 worktree、VS 2022 C++ toolset 14.42.34433、CMake 3.31.0、Python 3.15.2、Release x64:

  • 依赖准备:python -m tools.prepare_qt_build --cache local/qt-downloads --out local/qt-build-deps2 --summary local/qt-build-preparation2.json --offline → passed;Qt 6.10.3 SDK 树 a35ab6fe76b62e4d9bd6d3c6b0d476c63583070cea5c9118ef5bb02042ffe266(4,358 files),ConPTY 包 6d6f8b00…,CRT 包 84306899…。
  • 构建:cmake --build build/qt-cpp --config Release --target termforge_qt_shell --parallel 4 → 成功;windeployqt 产出不再包含 D3Dcompiler_47/dxcompiler/dxil。
  • staging:36 个产品文件 + product-manifest.json(共 37 文件),manifest_sha256=7128be5f09daa87aa5a2ba74a5699d50f6f09ba25c154b5e8a23a722ee978dd7,tree_sha256=641a7666b0c4890b5c27a5f46f33a58575e0a652b2c316ed2ad4388ce7cda538;入口 termforge_qt_shell.exe 284,672 B、SHA-256 d068b7bb06d44c2b06488c802428e25b3038c2ea5ffb0627ea8d28f3ba5e27f1。本次为 dirty worktree + --allow-dirty-development,manifest 记录 development_override: true;干净提交由 PR CI 重新生成。
  • python -m tools.stage_qt_product verify --staging local/qt-product-staging-final → passed(文件集合、逐文件哈希、入口/PE 架构、许可证据一致)。
  • 失败路径实测:复制 staging 后修改 Qt6Core.dll,verify 返回 file_identity:Qt6Core.dll 且 exit 1。
  • 既有部署检查:python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-bin/Release --executable termforge_qt_shell.exe → passed,34 files。
  • 工具契约测试:python -m unittest tools.test_prepare_qt_build tools.test_prepare_msvc_runtime tools.test_msvc_runtime tools.test_stage_qt_product → 45/45 passed,其中 18 项覆盖缺失/额外/测试夹具、Qt/CRT/ConPTY/字体篡改、OS 组件来源不符、依赖摘要绑定、dirty source、输出不覆盖与 CLI 失败路径。
  • PR CI(pull_request run 42459313684,qt-cpp-windows 4m3s success):Verify preparation failure contracts、Prepare manifest-pinned …、Build Qt product and independent smoke、Stage the frozen Qt product and verify every file identity 全部 success。干净 checkout 产生的 staging 身份:source commit 30608e8d…、tree b3ff34d7…、dirty=false;manifest_sha256=80ab1dbf5c96c4bd5f66af7cbe98767c6058a1704659610bfc297f4627a66558,tree_sha256=41f338599996ed9ea41491bb7e1be6c1fc9ee682babb2bb5ae311bab2dba2ff3(37 files);入口 termforge_qt_shell.exe 292,352 B、SHA-256 501f5d296f91411c6b3c28befb1d244412b97b9416c8d123f9bac9677d1f9f49。CI 只保留路径无关的 product-manifest.json、摘要与许可索引 artifact,不上传二进制。

性能影响(如适用)

无性能结论;本 PR 不改变运行时路径,不做性能测量,也不使用未确认的数值容差。新增 CI 只做离线工具测试、staging 与校验。

来源与限制

- Add tools/stage_qt_product.py: stage only the frozen Qt/ConPTY/CRT/font
  product set from a build whose files are byte-identical to the prepared
  pinned dependencies, add license evidence and emit a path-free
  product-manifest.json with per-file SHA-256. Missing, extra or test-fixture
  files, stale dependency summaries, unpinned sources and dirty trees fail
  closed; an existing output directory is never overlaid.
- Freeze the staging contract in packaging/qt-product/manifest.json, add a
  machine-readable font resource manifest, and bundle the LGPL-3.0-only text
  extracted from the pinned qtbase source archive.
- Skip unpinned system D3D/DXC redistributables in windeployqt and verify then
  exclude the OS-provided icuuc.dll instead of redistributing it.
- Wire staging and bounded re-verification into the Qt C++ CI workflow and
  document the entry plus the still-open R2 acceptance items.
- Add offline contract tests (18 cases) for staging, verification, failure
  codes, OS component identity and dependency binding.

Co-authored-by: JavaZeroo <71128095+JavaZeroo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants