Repository navigation
Conversation
| raise _DownloadError("资源增量基线已失效,必须重新下载全量包") | ||
| complete = stage_tmp / "complete" | ||
| shutil.copytree(_STAGE_DIR / "resource", complete) | ||
| merge_package_tree(root, complete) | ||
| root = complete | ||
| expected = len(resource_tree_hashes(root)) | ||
| else: | ||
| expected = count_zip_entries(zip_path, prefix=prefix) | ||
| file_hashes = resource_tree_hashes(root) | ||
| _MANIFEST_FILE.unlink(missing_ok=True) | ||
| if _STAGE_DIR.exists(): |
There was a problem hiding this comment.
Bug: Discrepancy in counting .gitignore files during incremental stage validation causes _DownloadError and forces unexpected fallbacks to full downloads.
Severity: MEDIUM
Suggested Fix
Align file counting between expected and actual. Either ignore .gitignore files when calculating actual via rglob, or exclude .gitignore during copytree when building the incremental stage tree.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: app/task/MAA/tools/resource_update.py#L484-L500
Potential issue: In `_build_stage`, the expected file count for incremental packages is
calculated via `len(resource_tree_hashes(root))`, which ignores `.gitignore` files.
However, `actual` is calculated by counting all files in `_STAGE_DIR / 'resource'`,
including `.gitignore` files copied from the baseline tree during `copytree`. If
`.gitignore` files exist in the baseline directory, `actual` exceeds `expected`, raising
`_DownloadError` and causing incremental updates to fail and fall back to full package
downloads every time.
Did we get this right? 👍 / 👎 to inform future reviews.
| ) -> Path: | ||
| """本体更新共享缓存目录:按系统、架构、通道隔离,互不覆盖。""" | ||
| return Path.cwd() / "data" / "maa_update" / "software" / os_name / arch / channel | ||
| root = Path.cwd() / "data" / "maa_update" / "software" / os_name / arch / channel | ||
| return ( | ||
| root / ("base-" + hashlib.sha256(base_version.encode()).hexdigest()[:16]) | ||
| if base_version | ||
| else root | ||
| ) | ||
|
|
||
|
|
||
| def load_cache_manifest(cache_dir: Path) -> dict[str, str] | None: |
There was a problem hiding this comment.
Bug: Versioned base-* cache directories for incremental software updates are never cleaned up, resulting in unbounded disk usage.
Severity: LOW
Suggested Fix
Implement a cleanup routine to remove obsolete base-* directories within {channel} when a new software package is cached or after an update completes successfully.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: app/task/MAA/tools/software_package.py#L76-L91
Potential issue: `software_cache_dir` creates versioned cache directories prefixed with
`base-<hash>` when a base version is specified. Because there is no pruning mechanism or
cleanup routine for old `base-*` directories, each incremental update leaves past
package caches behind, causing cumulative unbounded disk space consumption over multiple
updates.
Also affects:
app/task/MAA/tools/software_update.py:466~491app/task/MAA/tools/software_package.py:287~298
Did we get this right? 👍 / 👎 to inform future reviews.
总体结论:修改后合并AUTO-MAS-Project/AUTO-MAS #1949 宝宝,这次没有另起一套安装器,MAA 继续交给官方更新入口,MFW 家族也沿用了现有的新版本构建与登记流程,这个边界保留得好喵。不过增量路径还漏了两处:一处把合法资源缓存误判成损坏,另一处没接到真正需要回退全量的异常,先补好再合啦。 配置和前端负责保存全量/增量偏好;MAA 软件模块准备更新包,资源模块先拼出完整缓存再分发;MaaFW 更新模块则在临时目录构建、校验新版本,通过后才登记并切换。下面两项都是静态源码推演,未执行更新或复现。 MAA 资源更新[逻辑 · P2] 基线含
|
总体结论:可以合并宝宝,上一轮两处问题都补好了喵:资源增量复制已统一排除 新增缓存清理也核对过了:与取包、复制共用通道锁,保留近期和当前缓存,不会顺手删掉安装目录里的待更新包。合入 dev 后的配置衔接未发现新的必须修改项,这次可以放行啦。 dot酱只做了静态复核,未执行测试或真实安装更新。 —— 把增量回退这条线检查完的 dot酱敬上 🐾 |
release 分支没有 dev 上「差量构建失败回退全量」的通用回退(#1949),这里只针对 DeltaNativeRelocationError 补一次:新版本尚未登记、当前版本未动,按全量包重新更新。
## 摘要 - 用户报障:MAA_bbb 发行包同时带 `maafw/`(5.14.3)和 `runtimes/win-x64/` 两份原生库,导入时只留了 `maafw/`。v1.13.20 只升级了 `runtimes/win-x64/`(5.16.0),Mirror 酱差量包里只有改过的十几个 DLL。runner 按版本取高换到 `runtimes/win-x64`,opencv、onnxruntime 等没改过的依赖都不在,每次运行都报 `Could not find module ...\runtimes\win-x64\MaaFramework.dll (or one of its dependencies)`。 - 差量包套用完后,如果 runner 要用的原生库目录换到了旧版本里没有的地方,就抛 `DeltaNativeRelocationError`(原因链上是 `UpdateApplyError`),在登记前由 #1949 的回退改要全量包。 - 预检在独立子进程里按 runner 的方式加载一次新版本的 `MaaFramework.dll`。确定加载不了就放弃这次更新、继续用当前版本;检查本身出问题(起不来、超时、非 Windows)一律放行。 ## 测试与验证 - 自动化测试:`.venv\Scripts\python.exe -m pytest tests -q`:2087 passed、1 skipped(跑完后只给错误单独定义了类型、去掉报错末尾的句号,之后 MaaFW 相关测试重跑通过)。改动文件 `ruff format` / `ruff check` 通过。 - 测试提交:没有随 PR 提交测试。本地回归用例按问题包实际布局造了一个只有 `maafw/` 的当前版本和只带 `runtimes/win-x64` 改动文件的差量包:去掉修复时只下差量包、新版本缺依赖(红),修复后先下差量、再下全量,新版本原生库目录完整(绿)。预检的加载检查另有一条 Windows 专属用例。 - 环境与提交:`15fffce99`,Windows 11,Python 3.12(项目锁定环境)。 - 未覆盖范围:没有在真实 MAS 上走一遍 MAA_bbb v1.13.18 → v1.13.20 的 Mirror 酱差量更新。 - 作者本机真实流程:预检加载检查用 MAA_bbb 自带的真实 MaaFramework 5.14.3 原生库试过:完整目录放行;只留 `MaaFramework.dll` + `MaaToolkit.dll` 时被拒,报错与用户日志一致。
## 摘要 - MaaEnd 增量更新优先复用 MFW 的 HTTP Range 读取器,直接从官方全量 ZIP 重建原始 ZIP;复用的是读取器,不是 MFW 文件树安装流程。公共重建工具没有宿主依赖,本次不为其他专项开启该能力。 - GitHub 路径不限起始版本,以实际读取量 40%、变化条目 3000 和网络条件决定是否回退;失败后尝试 [数据仓库 #4](AUTO-MAS-Project/AUTO-MAS-Copilot-Data#4) 的 Action 增量,最后沿用全量下载。默认仍为全量,停止操作不会触发备用下载。 - Action 备用包覆盖目标之前最多三个正式版;beta 必须有同号正式基准。客户端保留最近安装 ZIP 和最近正式基准,避免 beta 更新覆盖后续备用包需要的基准;两路都必须通过独立 GitHub 官方整包大小和 SHA256,之后才交给原有事务安装器。 - 说明见 [MaaEnd 双路径增量更新](https://github.com/youngslin/AUTO-MAS/blob/feat/maaend-multi-base-delta/docs/maaend-incremental-update.md),包含范围、限制、缓存、重复/删除/回退文件及发布边界。保存与执行复用现有遥测结果入口,不新增逐区间事件。 ## 路径与限制 | 路径 | 允许的起点 | 失败后的处理 | | --- | --- | --- | | GitHub Range | 任意跨度的可信旧缓存 ZIP,包括跨多个 beta;不需要版本范围索引 | 再试 Action 自建站包 | | Action 正式版 | 如 `3.0.0 / 2.9.0 / 2.8.0 → 3.1.0`;更早版本不使用本站增量 | 全量 | | Action beta | `3.1.0` 正式版或 `3.1.0b1…b7 → b8`,实际重建使用缓存的 `3.1.0` 原始 ZIP | 缺同号正式版、缺可信正式缓存、站点未发布或不匹配时全量 | GitHub 只接受范围正确且完整的 206;返回 200 不读取整包响应体。实际读取预算包含头、中央目录和对齐开销,超过整包 40% 即退出;变化条目超过 3000 也退出。单次网络超时 30 秒。CDK 提供完整包备用源时,复用 MFW 网速保护,以 40% 读取上界保守估算 120 秒预算、180 秒实际网络耗时上限;没有较快备用源时不以这两项阈值打断持续传输的直连。 ZIP 是完整目标快照,不在当前安装上逐版叠补丁。重复数据复用,删除、改名和内容回退以目标快照为准;用户配置仍由现有安装器保护。CRC/大小只挑选复用候选,不能替代最终整包 SHA256;压缩字节不同导致 SHA256 不一致时丢弃重建结果。缓存最多两份原始 ZIP,约占两个整包大小;无缓存时允许先全量一次,不额外下载正式基准来伪装节省流量。 ## 验证 - Windows,锁定 Python 环境;实现提交 `57651c30569e247731b9aa762c7480dfe7e6ee24`,基于上游 `70376570f`。 - 真实官方 x64 `v3.1.0-beta.4 → beta.5`:官方完整 ZIP **316,003,772** 字节,Range 实际读取 **38,917,565** 字节(约节省 **87.7%**),复用 **3035** 个条目、取回 **11** 个变化条目。重建 SHA256 与官方完全一致:`05b516305872c8b8a41fa0235d5ecfedef0157d1822dbe7147cc3112c00477a4`。原型耗时 73.9 秒;生产读取路径再次复现同一结果。 - 同一真实包由数据仓库新生成器产生 **11,172,784** 字节 v2 包,再由主程序实际 v2 解码器重建,亦通过上述官方 SHA256。此项是跨仓库字节协议验证,未绕过正式发布规则去声称没有同号正式基准也能使用 Action。 - Range 重建包通过真实 `apply_update` 入口安装到独立临时目录,目标版本、安装回执和用户配置保留通过;不启动游戏、不更改用户实际安装。 - 相关回归 **107 passed**:真实更新入口覆盖跨 beta/旧正式版的 Range、文件删除/回退/复用、200 响应后自建站接续、正式基准跨 beta 保留、损坏与错误基线回退、取消,以及既有 MFW 核心与预取回归。 - `ruff format --check .`、相关文件 Ruff、`uv lock --check`、diff 和更新日志检查通过。完整后端回归 `uv run --no-sync python -m pytest tests -q -p no:cacheprovider --tb=short`:**2097 passed、1 skipped、1 failed,17 subtests passed**。唯一失败仍是此前已在未修改上游复现的 `tests/utils/test_fluxdown_detect_managed_priority.py::test_incomplete_managed_fluxdown_falls_back`,由本机已有完整 `res/fluxdown-cli` 优先于测试夹具外部目录触发;本 PR 未修改该实现或测试,没有新增失败。 ## 发布边界 没有合并或触发站点生产发布;arm64 实包未验证。Action 仍需四个独立文件 ID 和授权密钥,旧 v1 发布包在新客户端上全量回退,旧客户端不识别 v2 也全量回退。 本次属于 #1949 同一 beta 未发布功能的补充,按仓库规则使用 `skip-changelog`,不重复增加碎片,不修改版本号或 CHANGELOG。
摘要
审查修复
.gitignore时,重建增量缓存采用与分发相同的忽略规则;保留未改文件及摘要校验,不再误触发全量。UpdateApplyError → PayloadError → MaaFWProjectUpdateError链;登记前仅回退一次全量。真实坏指纹、取消、两种磁盘错误、登记后回调失败及全量请求仍返回坏增量均有回归;旧载荷内容全程保持不变。只隔离 HTTP 和磁盘故障,不替换构建、校验或登记逻辑。测试与验证
c62ecffd557f5c3597eb5e53d7e79fc93fafa39f,已合并上游dev的5dc79aebd并解决三种语言与统计覆盖文档冲突。uv run --no-sync python -m pytest tests/task/test_maa_fluxdown_update.py tests/task/test_maafw_update_fallback.py -k 'delta_fallback_uses_real or resource_delta_rebuilds or prunes_old_baselines' -q -p no:cacheprovider --tb=short:9 passed。corepack yarn test --run:358 passed;corepack yarn typecheck、lint、format:check通过,lint 仅有原有 QueueDeleteButton 属性默认值警告。ruff format --check .、相关文件 Ruff 检查、uv lock --check、更新日志碎片与 diff 检查通过。check_reverts仅提示增量接口签名与夹具的对应调整;同日新版突破旧额度限制的原回归仍保留并通过。corepack yarn e2e --grep 'package mode persists':2 passed,隔离配置、不填写 CDK,覆盖 MAA/MaaEnd 禁用状态、选择增量、保存、风险提示、刷新保留。产出截图、HTML 报告和 trace;corepack yarn e2e:check通过。05b516305872c8b8a41fa0235d5ecfedef0157d1822dbe7147cc3112c00477a4。apply_update入口安装到独立临时目录,安装回执、目标版本/架构及用户配置保留均通过;没有启动 MaaEnd 或游戏,没有修改用户实际安装。已知验证边界
c62ecffd5,Windows):uv run --no-sync python -m pytest tests -q -p no:cacheprovider --tb=short:2076 passed、1 skipped、1 failed,17 subtests passed。唯一失败仍为tests/utils/test_fluxdown_detect_managed_priority.py::test_incomplete_managed_fluxdown_falls_back:本机完整res/fluxdown-cli优先于夹具的外部目录。此前未修改上游5aa609284独立工作树在相同工作目录已复现同一失败;该检测实现及测试从5aa609284到本次合并的5dc79aebd均无变化,本 PR 也未修改。没有新增测试失败。选项名称已统一为“全量更新 / 增量更新”,默认仍为全量;文案调整后类型检查、格式检查与两个更新设置组件测试通过。