用途:面向打包与发布流程,确保「用户实际安装的字节」与「源码树」一致,避免在 CI 全绿的情况下发布损坏或过期产物。
主要能力与要点:
- 构建脚本中的缺失输入必须是错误。只警告并 exit 0 的脚本不是门禁;若说不清缺该文件后产物是否仍可用,就应报错并以非零码退出。
- 产物大小两侧都要设界。只有上限是成本护栏,构建静默丢掉一半文件反而更小、更易通过;应同时设下限,并最好直接断言归档内的条目与入口点所需集合一致。
- 文件清单要么自动派生(从真实入口打包),要么校验清单与入口 HTML 中引用的路径在构建后确实存在于产物中;手工维护的白名单若无此校验,是未来的 bug。重复声明的依赖元数据同理,应加规范化对比测试。
- 已提交的构建产物会静默过期。应在 CI 中重建并与已提交产物 diff,漂移即失败;构建器需固定到精确版本,并确认输出字节确定(一次跨本地工具链与容器镜像验证)。重建产物应与源码改动同一提交,不要用后续「重建」提交。
- 发布脚本在非开发机上运行。避免 GNU 专有选项(如 grep -P、sed -i'' 在 macOS BSD 下的语义差异),改用解析器读取结构化元数据,例如:VERSION=$(python -c 'import tomllib;print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])') 或 VERSION=$(jq -r .version package.json),并加测试断言构建脚本提取的版本与项目清单声明一致,否则会出现 tag 为 v1.4.0 而产物报告 1.3.2 的情况。
- 先验证再发布,且在同一 job 内完成。顺序为:构建;列出产物中每个条目并断言入口点存在;在不在源码树加载路径上的目录安装或加载它,并实际调用一个真实符号或命令;最后才上传。分离的「测试」job 针对源码树,证明不了产物可运行。
适用场景:任何有构建脚本、打包或发布工作流的项目,尤其是浏览器扩展、Python 包(wheel/sdist)等。
限制:文中未提供具体项目仓库结构、支持的语言清单或工具版本要求;文内提及的 packaging-python-libraries、setting-up-python-libraries 等关联内容仅为引用,本次资料未给出其细节。