关于 macos-release
macos-release 是帮助开发者在 Mac App Store 之外发布原生 macOS 应用的技能,涵盖 GitHub Releases 分发和 Sparkle 自动更新。它还附带 Go CLI,可交互地完成 DMG 制作、签名、appcast 更新及发布。
主要功能
- 01指导版本号更新与归档
- 02处理公证和应用导出
- 03创建并签名 DMG
- 04更新 Sparkle appcast.xml
- 05推送 appcast 并创建 GitHub Release
- 06通过交互式 Go CLI 自动化发布
适用场景
- 01向 Mac App Store 之外分发应用
- 02为应用版本生成签名 DMG
- 03发布 Sparkle 自动更新信息
- 04从终端执行完整发布流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fayazara/ macos-app-skills --skill macos-release安装后在 Claude Code 中输入/macos-release确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
cli/main_test.gomain.gorelease.example.json详细介绍
发布 macOS App
此技能涵盖通过 GitHub Releases 在 Mac App Store 之外分发原生 macOS App 的完整发布流程,并支持 Sparkle 自动更新。
发布流程概览
Bump version → Archive → Notarize → Export → Create DMG → Sign DMG → Update appcast.xml → Git push → GitHub Release
前提条件
用户需要安装以下工具:
| 工具 | 安装方式 | 用途 |
|---|---|---|
create-dmg | brew install create-dmg | 创建 DMG 安装程序 |
gh | brew install gh | 创建 GitHub 发布 |
git | 内置 | 推送 appcast 更改 |
Sparkle sign_update | 使用 Sparkle 构建项目时自动构建 | 使用 EdDSA 对 DMG 签名 |
在 Xcode 中构建项目后,sign_update 二进制文件位于 DerivedData 中:
find ~/Library/Developer/Xcode/DerivedData -name "sign_update" -type f 2>/dev/null | head -1
分步发布指南
1. 更新版本号
在 Xcode 中,更新:
MARKETING_VERSION(例如,1.2)——面向用户的版本号CURRENT_PROJECT_VERSION(例如,5)——构建号(每次发布必须唯一)
或者通过命令行更新:
# Check current values
grep -E "MARKETING_VERSION|CURRENT_PROJECT_VERSION" YourApp.xcodeproj/project.pbxproj | head -4
2. 在 Xcode 中归档
选择 Product > Archive。此操作会创建带有正确签名身份的发布构建。
3. 公证并导出
在 Archives 管理器中:
- 选择归档 > Distribute App
- 选择“Direct Distribution”(或选择“Developer ID”进行公证)
- 等待公证完成
- 导出到
~/Downloads/YourApp.app
4. 创建 DMG
create-dmg \
--volname "YourApp" \
--window-pos 200 120 \
--window-size 660 400 \
--icon-size 160 \
--icon "YourApp.app" 180 170 \
--app-drop-link 480 170 \
--hide-extension "YourApp.app" \
~/Downloads/YourApp.dmg \
~/Downloads/YourApp.app
5. 使用 Sparkle 对 DMG 签名
/path/to/sign_update ~/Downloads/YourApp.dmg
此操作会输出 EdDSA 签名和文件长度:
sparkle:edSignature="BASE64..." length="12345"
保存这两个值,以供 appcast 使用。
6. 更新 appcast.xml
在 appcast.xml 的 <channel> 顶部添加新的 <item>:
<item>
<title>Version 1.2 (Build 5)</title>
<pubDate>Mon, 26 May 2026 12:00:00 +0000</pubDate>
<sparkle:version>5</sparkle:version>
<sparkle:shortVersionString>1.2</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
<description><![CDATA[<ul><li>Feature one</li><li>Bug fix two</li></ul>]]></description>
<enclosure url="https://github.com/OWNER/REPO/releases/download/v1.2/YourApp.dmg"
type="application/octet-stream"
sparkle:edSignature="THE_SIGNATURE_FROM_STEP_5"
length="THE_LENGTH_FROM_STEP_5" />
</item>
pubDate 应采用 RFC 2822 格式。生成方式如下:
date -R
7. 提交并推送 Appcast
git add appcast.xml
git commit -m "Release v1.2 appcast"
git push origin main
8. 创建 GitHub 发布
gh release create v1.2 \
~/Downloads/YourApp.dmg \
--title "v1.2" \
--notes "- Feature one
- Bug fix two"
自动化发布流程
如果需要频繁发布,可构建一个 CLI 工具来自动执行第 4 至第 8 步。请参阅 references/release-pipeline.md,其中提供了 Go CLI 模板,可通过一条命令处理 DMG 创建、签名、appcast 更新和 GitHub 发布创建。
该 CLI 应:
- 在 DerivedData 中自动查找
sign_update - 通过
plutil从导出 App 的 Info.plist 中读取版本号和构建号 - 解析并更新 appcast.xml(保留现有条目)
- 交互式收集发布说明
- 显示摘要,并在继续前请求确认
- 创建附带 DMG 的 GitHub 发布
发布 CLI 工具
此仓库包含一个 Go CLI,可通过一条命令自动执行第 4 至第 8 步(从创建 DMG 到创建 GitHub 发布)。它会从项目根目录中的 release.json 文件读取配置。
设置
- 在项目根目录中创建
release.json(参见cli/release.example.json):
{
"app_name": "MyApp",
"github_repo": "owner/myapp"
}
只有 app_name 和 github_repo 是必填项。其他配置均有合理的默认值:
| 字段 | 默认值 | 描述 |
|---|---|---|
bundle_name | {app_name}.app | .app Bundle 文件名 |
dmg_name | {app_name}.dmg | 输出的 DMG 文件名 |
git_branch | main | 用于推送 appcast 的分支 |
min_system_version | 14.0 | Sparkle 最低 macOS 版本 |
appcast_file | appcast.xml | 仓库根目录中的 Appcast 文件名 |
derived_data_prefixes | ["{app_name}-"] | 搜索 sign_update 时使用的 DerivedData 前缀 |
- 在项目目录中运行 CLI:
go run github.com/fayazara/macos-app-skills/release/cli@latest
或者克隆此仓库并在本地运行:
go run ./release/cli
此 CLI 采用交互式操作——它会提示输入发布说明,并在继续前请求确认。必须在用户可交互的终端中运行。
CLI 的功能
- 从当前目录开始向上查找
release.json - 检查
create-dmg、gh、git和 Sparkle 的sign_update是否可用 - 验证
~/Downloads/中导出的应用(从 Info.plist 读取版本、构建号和 Sparkle 密钥) - 如果构建号已存在于 appcast 中,则发出警告
- 交互式收集发行说明(每行一条项目,空行结束)
- 显示发行摘要并请求确认
- 通过
create-dmg创建 DMG - 使用 Sparkle 的
sign_update(EdDSA)对 DMG 签名 - 使用新的发行条目更新
appcast.xml - 提交并推送 appcast
- 创建附带 DMG 的 GitHub 发行版
常见问题
| 问题 | 解决方案 |
|---|---|
找不到 sign_update | 先在 Xcode 中构建项目,以便 DerivedData 中包含 Sparkle 构建产物 |
gh 身份验证失败 | 运行 gh auth login |
| appcast 中存在重复构建号 | 归档前增加 CURRENT_PROJECT_VERSION |
| 公证失败 | 检查签名身份、权利文件和强化运行时设置 |
| DMG 过大 | 检查导出内容中是否包含调试符号或不必要的框架 |
| 应用不会更新 | 确认 SUFeedURL 指向 appcast 的原始 URL,而不是 GitHub 页面 URL |
Appcast 托管
最简单的托管方式:将 appcast.xml 提交到你的 GitHub 仓库,并使用原始 URL:
https://raw.githubusercontent.com/OWNER/REPO/main/appcast.xml
此 URL 必须与应用 Info.plist 中的 SUFeedURL 一致。