macshot测试与发布流水线600无头测试、双变体构建与Sparkle自动更新【免费下载链接】macshotFeature-packed native macOS screenshot recording tool: annotate, auto-redact PII, record GIFs, OCR translate, scroll capture, beautify, and more. No Electron, no subscription.项目地址: https://gitcode.com/gh_mirrors/mac/macshotmacshot 是一款功能齐全的 macOS 原生截图与录屏工具它不仅自带 600 多个无头headless单元测试还在每次推送时执行双变体 Release 构建并通过 Sparkle 框架实现自动更新。对于普通用户来说这意味着每次自动更新背后的质量都是有保障的对于想参与贡献的新手这套测试与发布流水线也是值得学习的一套完整工程实践。600 无头测试不启动应用也能测什么很多 macOS 应用的测试都需要授予屏幕录制权限并打开窗口但 macshot 的测试方案绕开了这些限制。它的 macshotTests/ 测试目标直接编译应用源码而不是依赖一个宿主应用host app。因此️无头运行不需要屏幕录制权限不依赖窗口服务器CI 上也能跑覆盖纯逻辑坐标计算、命中检测、编解码、文件名模板、快捷键匹配以及滚动截图像素比对等确定性像素夹具共享辅助类ImageProbe保证在 Retina 屏和 CI 上生成完全一致的像素避免我这机器上是好的问题测试辅助工具集中在 macshotTests/TestSupport.swiftwithDefaults提供隔离的 UserDefaultsTestKeyEvent合成键盘事件Reflect则能一次性对比某个值类型的所有存储属性——比如当你给Annotation新增字段却忘了更新序列化代码时普查测试会直接点名报出来。想在本地跑一遍一条命令即可支持指定测试类或单个测试scripts/run-tests.sh # 全部测试 scripts/run-tests.sh AnnotationGeometryTests # 单个测试类 scripts/run-tests.sh --offline # 离线变体编译条件脚本在失败时会保留完整日志与 xcresult 结果包方便排查。详见 scripts/run-tests.sh 与 CONTRIBUTING.md。CI 流水线每次推送都跑双变体测试 Release 构建持续集成配置在 .github/workflows/tests.yml触发时机是每次 push 到 main 分支和每个 PR。它在macos-26运行器上依次完成三件事常规变体测试—— 以 Debug 配置运行完整测试套件并生成 JSON 摘要写入任务总结离线变体测试—— 附加OFFLINE编译条件重跑一遍。因为离线版是真实发布的产品上传代码被编译移除必须同样构建通过、测试通过双变体 Release 构建—— 这一步很关键Release 模式启用-Owholemodule严格并发检查能捕获 Debug 构建放行的 Swift 并发错误确保问题不会溜进打 tag 的正式版本任何一步失败CI 都会上传测试结果与完整日志作为制品保留 7 天并生成人类可读的失败摘要。双变体构建同一个 tag两份产品macshot 提供两个发布变体从同一个 tag构建而来维度常规版离线版产品名macshotmacshot OfflineBundle IDcom.sw33tlie.macshot.macshotcom.sw33tlie.macshot.offlineSparkle 更新源appcast.xmlappcast-offline.xml发布资产MacShot.dmgMacShot-Offline.dmg云上传功能✅ 完整❌ 被编译移除离线版通过OFFLINESwift 编译条件区分上传界面、上传快捷键、设置项乃至上传器实现都被#if !OFFLINE从二进制中剔除——不是隐藏按钮而是代码根本不存在。运行时变体检查统一走 macshot/Services/BuildVariant.swift详见 CLAUDE.md 的 Build Variants 章节。一个容易踩的坑两个变体的更新源严格隔离。CI 会修补离线版的SUFeedURL指向appcast-offline.xml绝不让离线用户升级成常规版反之亦然。Sparkle 自动更新appcast 是这样运作的macshot 使用 Sparkle 框架做自动更新更新源就是仓库根目录下的两个 XML 文件appcast.xml 和 appcast-offline.xml。里面藏着两个巧妙设计 用 CI run number 当版本号sparkle:versionSparkle 用来比较新旧的字段不是3.8.0这样的语义化版本而是每次 CI 构建单调递增的整数用户看到的sparkle:shortVersionString才是 tag 上的人类可读版本号。这彻底避开了 beta / rc / pre-release 这类语义化版本比较时的各种边界问题。 beta 频道隔离beta 条目带sparkle:channelbeta/sparkle:channel标签普通用户完全看不见只有在偏好设置中开启检查 beta 更新的用户才会收到。beta 版本还会被标记为 pre-release并跳过 Homebrew 与官网的版本更新。发布流程推一个 tag剩下的交给 CI对普通用户安装与更新都很省心brew install --cask macshot而对维护者整个发布过程就两步——在 CHANGELOG.md 写好版本说明然后推一个 tag类型操作CI 自动完成稳定版git tag v4.4.0构建、签名、公证、打包 DMG、更新 appcast、创建 Release、更新 Homebrew cask 与官网版本号beta 版git tag v4.4.0-beta.3同上但 appcast 条目加 beta 频道、Release 标记 pre-release、跳过 Homebrewappcast 在提交前会先用 Python 的 XML 解析器校验损坏的 XML 永远不会到达用户端——这是一道很朴素的护栏。发布细节含手动触发 CI 的兜底方式和 tag 节流注意事项都记录在 CLAUDE.md 的 Releasing 章节。新手参与指南从跑测试开始如果你想给 macshot 提第一个 PR门槛比想象中低打开 macshot.xcodeproj 即可运行——项目使用 Xcode 同步文件组新建.swift文件会自动被识别本地跑scripts/run-tests.sh确认全绿再为新逻辑补上测试遵循 CONTRIBUTING.md 的 PR 清单无警告构建、测试通过、手动验证、不夹带无关改动历史与数据恢复相关的改动建议先读 docs/history-recovery.md一句话总结600 无头测试守逻辑双变体 CI 守构建Sparkle appcast 守更新——三层护栏让每次推给用户的 tag 都经过了同一条严格流水线。【免费下载链接】macshotFeature-packed native macOS screenshot recording tool: annotate, auto-redact PII, record GIFs, OCR translate, scroll capture, beautify, and more. No Electron, no subscription.项目地址: https://gitcode.com/gh_mirrors/mac/macshot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考