Skip to content

14 · 测试、CI 与发布

对维护工具而言,测试的第一条要求不是覆盖率,而是测试运行本身绝不能触发真实 sudo、AppleScript 或系统服务修改。

测试规模与分层

固定提交中可统计到 72 个 tests/ 文件、约 1289 个 Bats @test,Go 侧约 306 个 Test* 与 1 个 benchmark。数量不是质量证明,但显示安全边界并非只靠人工约定。

scripts/test.sh 同时运行 Shell 单元/集成测试与 Go 测试。Bats 文件可并行执行,CI 默认 6 workers,并生成 JUnit 报告列出最慢文件。性能断言通过环境变量给出预算,降低不同 CI 机器上的随机失败。

测试宿主机隔离

运行器设置 MOLE_TEST_NO_AUTH=1,并把 stub sudoosascriptlaunchctl 放到 PATH 最前。真实授权请求必然失败,launchctl 只记录调用。每个测试使用独立 HOME,遗留超过 60 分钟的临时目录才被清理,避免与仍在运行的长测试竞争。

Go TUI helper 预先构建到临时目录供 CLI 测试使用;即使构建失败,测试也能按能力降级。NO_COLOR 在测试中清除,使 ANSI 输出断言不受开发者环境影响。

静态质量门

scripts/check.sh 覆盖 shfmt、goimports/gofmt、golangci-lint(不可用时 go vet)、ShellCheck 与全量 Bash 语法。Check workflow 把格式和质量拆成依赖 job;format job只检查 diff,避免 CI 自动改文件。

Security job 额外:

  • 搜索未通过安全 wrapper 或明确注释的 rm -rf
  • 运行关键应用保护 smoke test;
  • 使用 gitleaks 扫描秘密;
  • 保留完整 git history 供安全扫描。

兼容矩阵运行 macOS 14 与 15,并对 core safe functions、timeout、regression、CLI 做子集验证。

Release 的可追溯产物

标签 V* 触发 release。amd64 与 arm64 都在 macOS runner 上以纯 Go 构建,随后检查最低 macOS 版本。发布 job 合并二进制与 Homebrew tarball,按确定顺序生成 SHA256SUMS,再使用 GitHub artifact attestation 生成 provenance。

release asset、checksum 与 provenance 是安装器校验链的生产端。之后 workflow 自动准备 Homebrew Core 更新,URL 与源码 SHA-256 从 tag 计算,避免手工复制错误。

仍然存在的测试边界

大量 Bats 测试可以验证字符串、路径与 stubbed 系统命令,但无法完全模拟 APFS、TCC 隐私拒绝、外置卷 Trash、真实 Spotlight 索引和不同企业 EDR。因此代码仍选择保守失败,并保留 macOS 实机矩阵;这不是测试不足的借口,而是对不可模拟边界的明确承认。

关键源码索引

下一章抽离具体命令,总结哪些架构模式可以迁移,哪些复杂度是 Mole 特定风险换来的。

独立源码研究笔记 · 非 Mole 官方文档