一个 Linux 源码版本对应的完整一方依赖组合由两部分构成:
- 源码 pin 走 gitlink。 engine、helpcode 两个 submodule 的提交由 git 本身固定,在 PR diff 里可评审,
scripts/bootstrap_ci_dependencies.sh按 gitlink 逐个还原,全程不执行git submodule update --remote。这些提交不再抄一份进锁文件——那只会给同一个 pin 造出第二处会漂移的副本,还会挡住engine-bump-triage.yml对 dependabot 引擎升级的自动合并。 - 词库的源码提交也在锁里,不走 gitlink。 dict 曾经是第三个 submodule,而那个 pin 记的是错的:没有任何东西会让它跟着
dictionary.tag一起动,于是 manifest 声称词库来自55bd649,包里的字节却是0c7368c构建出来的。release tag 解析到的提交才是唯一产出这批数据的提交,refresh在评审数据的那一刻把它解析出来记进dictionary.source_commit。 - 数据 pin 走
product-lock.json。 词库是 git 唯一钉不住的输入:它是 release 资产,tag 可以被上游重新指向。锁文件记录 release tag 和每个文件的 SHA256,构建按这些已提交的摘要校验,而不是按 release 里随数据一起发布的SHA256SUMS.txt——后者和数据一样可变,把数据和校验文件一起替换掉并不能让构建通过,因为校验文件本身也在锁里。
这与 Windows 的差别是刻意的:MSIME-Windows 的 Server / 页面 / 安装器 / 辅助码都不是它的 submodule,只能在锁文件里显式钉住;Linux 这边它们本来就是 submodule。
python3 scripts/product_lock.py refresh --dictionary-tag dict-v1.0.0
python3 scripts/product_lock.py validaterefresh 是唯一会访问上游的命令。它下载该 release 的全部资产、算出摘要、并与 release 自带的 SHA256SUMS.txt 交叉核对——只有这一刻信任上游校验文件是合适的,因为这正是有人专门审视这批数据的时刻,而它产出的摘要就是此后每次构建的判据。改动落在 product-lock.json 的 diff 里,评审后提交。
scripts/fetch_dictionary.py 不再接受 --tag:换 release 必须经过上面这条评审路径,不能在流水线里临时指定。
fetch_dictionary.py 先把资产下载到一个暂存目录,校验锁里的摘要,再跑 SQLite 完整性与候选探针(ni'hao、yyds、aaaa、xiaolian、haixiu、hello),全部通过后才覆盖 vendor/MetasequoiaImeDict/out/。下载失败或数据被替换时,上一份可用的词库原样保留,不会被替换掉一半。
发布流水线用 product_lock.py manifest 生成 product-manifest.json,内容是被发布的源码提交、两个 gitlink 的实际提交、锁定的词库 tag / 源码提交 / 摘要,以及锁文件自身的 SHA256。它同时随包安装到 <prefix>/share/metasequoiaime/product-manifest.json 并作为 release 资产附加,打包步骤会比对两者一致后才继续。
本地构建默认不生成也不安装该文件:一份过期的清单比没有清单更糟。需要复现打包时显式传入:
python3 scripts/product_lock.py manifest --source-commit "$(git rev-parse HEAD)" --output product-manifest.json
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DMETASEQUOIA_IME_PRODUCT_MANIFEST="$PWD/product-manifest.json"签名、工具链与 runner 更新仍可能改变二进制字节;此机制保证产品源码与数据组合确定,不承诺安装包逐字节一致。
python3 -m unittest discover -s tests -p 'test_product_lock.py'
python3 scripts/product_lock.py validate
python3 scripts/product_lock.py verify-dictionaries vendor/MetasequoiaImeDict/out