news 2026/10/29 17:59:22

从零到发布:Screendrop 的 Go 发布工具如何自动完成公证、DMG 与 Homebrew 推送

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到发布:Screendrop 的 Go 发布工具如何自动完成公证、DMG 与 Homebrew 推送

从零到发布:Screendrop 的 Go 发布工具如何自动完成公证、DMG 与 Homebrew 推送

【免费下载链接】ScreendropA beautiful screenshot + screen recording + Loom alternative - all native, self hostable and free.项目地址: https://gitcode.com/gh_mirrors/sc/Screendrop

Screendrop 是一款免费、全原生的 macOS 截图与录屏工具,它的发版工作全部由一个 Go 编写的发布工具完成:一条命令自动跑完 Apple 公证、DMG 打包、Sparkle 签名、自动更新推送与 Homebrew cask 更新——开发者不需要再手动点一次 Xcode 的导出按钮。

为什么不用手动发版?

发布一个 macOS 应用,手动流程至少要串起 5 个环节:

  1. Xcode Archive 并以 Developer ID 导出
  2. 打包成 DMG
  3. 对 DMG 做 Sparkle 签名(供自动更新校验)
  4. 创建 Release 并更新 appcast.xml
  5. 生成并推送 Homebrew cask

每一步都可能出错,而且顺序错了就会留下"引用了不存在下载地址"的 appcast。Screendrop 的解法是把整条流水线封装进一个 Go 命令行工具 cmd/screendrop-release/main.go,约 1000 行代码覆盖了从归档到推送的全部步骤。

发布流水线全景:一条命令,五个阶段

带上-build参数运行时,工具按固定顺序执行:

阶段做什么关键命令
① 构建与公证归档 → Developer ID 导出 → 公证 → staplexcodebuild/xcrun notarytool
② 打包签名生成 DMG 并用 Sparkle 签名create-dmg/sign_update
③ 发布到仓库推代码 → 建 Release → 更新 appcastgit push/gh release
④ 推送 Homebrew重算 sha256,生成 cask 并提交 tap 仓库git push(tap 仓库)

第一步:Apple 公证自动化——归档、签名、钉上公证票据

核心逻辑在 main.go 的 runBuildPhase 中:

  • 归档:xcodebuild archive指定 Release 配置,产物落在~/Downloads/Screendrop.xcarchive
  • 导出:自动生成ExportOptions.plist(Developer ID + 自动签名),用-exportArchive导出
  • 公证:ditto压缩后用xcrun notarytool submit --wait等待 Apple 返回,直到输出包含status: Accepted才算通过
  • Staple:xcrun stapler staple把公证票据钉进应用,离线下载也能通过 Gatekeeper 校验

它还支持在归档前用-set-version和-set-build直接改写工程里的MARKETING_VERSION/CURRENT_PROJECT_VERSION(见 bumpVersion),并自动提交这次版本号变更——"升版本"这件小事也不再需要打开 Xcode。

第二步:DMG 打包与 Sparkle 签名

DMG 由create-dmg生成,工具内置了窗口尺寸、图标位置与应用拖拽链接的坐标(main.go#L231-L255),保证每次装出的 DMG 观感一致。

紧接着是关键一步:用 Sparkle 的sign_update对 DMG 签名。这个二进制工具藏在 Xcode DerivedData 里,findSignUpdate 会自动按前缀扫描找到它,签名后从输出中解析出edSignature与文件长度(parseSparkleSignature,有单测覆盖),供后面写入 appcast。

第三步:顺序很重要——先建 Release,再动 appcast

发布顺序是这个工具最值得学习的设计(main.go#L274-L364):

  1. 先推送本地提交——保证 Release 的 tag 包含已发布的源码
  2. 创建 GitHub Release 并上传 DMG——此时下载 URL 已真实存在
  3. 最后才更新并推送 appcast——appcast 指向第 2 步生成的 URL

顺序反了的话,一旦中途失败,appcast 就会指向一个不存在的下载地址,客户端全部更新失败。此外两个健壮性细节也很实用:

  • 幂等重跑:Release 已存在时改为重新上传 DMG,而不是报错退出
  • 网络重试:所有易抖动的git push/gh调用都走 runCmdRetry,按 2s、4s 间隔退避重试 3 次

第四步:Homebrew cask 一键推送

cask 更新逻辑在 updateHomebrewCask:先对 DMG 计算 sha256,再由 renderCask 模板化生成Casks/screendrop.rb,最后提交并推送到 tap 仓库。

注意它的"非致命"设计:tap 仓库未配置或推送失败时,只打一条 WARN,绝不让 Homebrew 环节阻塞主发布流程。

自动更新闭环:appcast.xml 是另一半

工具负责"生产"更新,客户端的 UpdaterManager.swift 负责"消费":它基于 Sparkle 的SPUStandardUpdaterController轮询仓库中的 appcast.xml。

工具更新 appcast 时的细节值得留意(writeAppcast):

  • 新条目置顶,并按 build 号去重——同一构建重跑是"替换"而不是"重复"
  • 描述字段写成<![CDATA[...]]>包裹的 HTML,客户端弹窗里能渲染出标题和列表
  • 每次生成都会把sparkle:edSignature和length写进 enclosure,与第二步的签名一一对应

以当前仓库中的 appcast.xml 第 29-54 行 为例,就能直接看到一条由该工具生成的完整 v0.34.0 更新记录。

上手指南:从交互模式到无人值守

在仓库根目录(或任意包含appcast.xml的目录下)运行:

# 完整流水线:构建 → 公证 → DMG → 发布 → Homebrew go run ./cmd/screendrop-release -build

不带-build时,工具假设你已把Screendrop.app导出到~/Downloads,只执行打包与发布。

常用参数作用
-build包含归档、Developer ID 导出、公证与 staple 阶段
-set-version 0.35.0归档前自动升版本号并提交
-notary-profile <name>指定 notarytool 钥匙串配置
-notes "..."/-notes-file <path>非交互方式提供发布说明(一行一条)
-yes跳过所有确认提示,适合 CI / 代理调用

配合环境变量可覆盖默认路径:SCREENDROP_REPO指定仓库目录,SCREENDROP_TAP_DIR指定 tap 仓库的本地克隆(findRepoDir、resolveTapDir)。

工具启动时会先用 requireCommand 检查create-dmg、gh、git等依赖,缺什么直接给出brew install提示,新手也不会卡在"神秘失败"上。

💡 仓库为只读镜像;如需自行实验,可克隆:git clone https://gitcode.com/gh_mirrors/sc/Screendrop,模块定义见 go.mod。

写在最后

Screendrop 的发布工具给出了一个小团队做 macOS 发布的务实范式:🎯顺序正确(先有下载 URL,再更新 appcast)、可重跑(幂等 + 重试)、故障隔离(Homebrew 失败不阻塞主流程)、零手工(版本号、签名、哈希全部自动生成)。它不是复杂的 CI 编排,而是一个约千行的 Go 程序——这恰恰说明:发布自动化不一定要引入重工具链,把步骤、顺序和兜底写清楚就够了。

【免费下载链接】ScreendropA beautiful screenshot + screen recording + Loom alternative - all native, self hostable and free.项目地址: https://gitcode.com/gh_mirrors/sc/Screendrop

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 3:07:09

储能一体机如何成为企业能源管理升级的核心抓手

不做铺垫&#xff0c;直接进入正题。一个做机械加工的客户&#xff0c;上个月把近一年的电费单拍在我桌上。尖峰时段电费占了总电费的四成多&#xff0c;基本电费按变压器容量缴满&#xff0c;实际最大需量却只用了六成。聊了十分钟&#xff0c;我就把储能一体机作为第一个方案…

作者头像 李华
网站建设 2026/10/24 12:20:43

进阶练习:目标检测与图像分割的结合应用

&#x1f4da; 本章学习目标&#xff1a;深入理解目标检测与图像分割的结合应用的核心概念与实践方法&#xff0c;掌握关键技术要点&#xff0c;了解实际应用场景与最佳实践。本文属于《计算机视觉教程》传统目标检测篇&#xff08;第四阶段&#xff09;。在上一章&#xff0c;…

作者头像 李华
网站建设 2026/10/16 5:51:40

C1002数组

一.数据结构1.数据结构&#xff1a; 一种可以存储多个数据的结构 线性结构 树状结构 网状结构 组合结构2.主要作用&#xff1a; 帮我们更方便的保存数据 、查找数据、分析数据、数据处理(删除 替换 排序...)二.单位换算1.bit-二进制位 byte-字节整数型&#xff1a; int&#…

作者头像 李华
网站建设 2026/10/15 6:50:09

⭐STM32与OpenMV视觉垃圾分类回收/道路垃圾清理机器人系统设计

摘要本项目设计并实现了一款基于 STM32 与 OpenMV 视觉模块的智能垃圾回收机器人&#xff1a;三路灰度传感器实现自主循迹&#xff0c;OpenMV 摄像头实时识别可回收、厨余、其他三类垃圾&#xff0c;三自由度机械臂完成抓取与分类归位投放&#xff0c;红外传感器实现到位停车与…

作者头像 李华
网站建设 2026/10/29 8:21:46

用户口碑佳的AI论文工具势力榜(2026 最新版)

基于综合性能、学术适配度、用户口碑和功能完整性&#xff0c;以下是当前主流AI论文写作工具的权威排名&#xff0c;按综合推荐指数从高到低排列&#xff0c;并标注核心优势与适用场景。&#x1f3c6; 第一梯队&#xff1a;全流程学术解决方案&#xff08;★★★★★&#xff0…

作者头像 李华
网站建设 2026/10/29 15:05:24

PRD与SOP的本质区别、应用场景及落地实践

产品核心术语科普&#xff1a;PRD与SOP的本质区别、应用场景及落地实践 在互联网、ToB企业服务、政企数字化项目中&#xff0c;PRD和SOP是出现频率最高、但最容易被混淆的两类专业文档。 很多新人产品、业务运营、研发人员都会有一个误区&#xff1a;把操作步骤当成需求&#x…

作者头像 李华