mcpField
R
releasing-macos-apps

releasing-macos-apps

github.com/jamesrochabrun云与 DevOps221203 次安装41 周前更新
代码仓库

关于 releasing-macos-apps

releasing-macos-apps 是面向 macOS 应用开发者的发布工作流技能,涵盖签名、公证、Sparkle 更新、DMG 制作和 GitHub 发布,并提供逐步验证流程。

主要功能

  1. 01版本更新、构建与归档
  2. 02代码签名与公证
  3. 03Sparkle 更新签名和 appcast
  4. 04DMG 安装包制作
  5. 05管理 GitHub 发布资源
  6. 06发布验证清单

适用场景

  1. 01准备经过签名的 macOS 应用发布
  2. 02发布 Sparkle 更新和 DMG 安装包
  3. 03排查公证或发布验证问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jamesrochabrun/skills --skill releasing-macos-apps

安装后在 Claude Code 中输入/releasing-macos-apps确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

NOTARIZATION.md
SPARKLE.md
TROUBLESHOOTING.md

详细介绍

发布 macOS 应用

使用 Sparkle 自动更新、DMG 安装器和 GitHub 发布来创建经过公证的 macOS 应用发布的完整工作流。

发布检查清单

复制此检查清单并跟踪进度:

Release Progress:
- [ ] Step 1: Check prerequisites (certificates, credentials)
- [ ] Step 2: Update version in .xcconfig file
- [ ] Step 3: Build and archive the app
- [ ] Step 4: Export with proper code signing
- [ ] Step 5: Create zip and generate Sparkle signature
- [ ] Step 6: Create DMG with Applications folder
- [ ] Step 7: Submit for notarization
- [ ] Step 8: Staple notarization ticket to DMG
- [ ] Step 9: Update appcast.xml with new signature
- [ ] Step 10: Commit and push changes
- [ ] Step 11: Update GitHub release assets
- [ ] Step 12: Verify DMG and version number

前提条件

开始发布前,请确认:

  1. 已安装且有效的 Apple Developer ID Application 证书
  2. 用于公证的 Apple ID 凭据:
    • Apple ID 邮箱
    • App 专用密码(在 appleid.apple.com 生成)
    • Team ID
  3. 用于签署更新的 Sparkle 私钥
  4. 已安装并完成身份验证的 GitHub CLI(gh)
  5. 已确定版本配置文件的位置(通常是 .xcconfig 文件)

检查证书:

security find-identity -v -p codesigning | grep "Developer ID Application"

第 1 步:更新版本

找到版本配置文件(通常是 ProjectName.xcconfig 或 project.pbxproj)。

对于 .xcconfig 文件:

# Edit the APP_VERSION line
# Example: APP_VERSION = 1.0.9

验证更新:

xcodebuild -project PROJECT.xcodeproj -showBuildSettings | grep MARKETING_VERSION

第 2 步:构建并归档

使用新版本归档应用:

xcodebuild -project PROJECT.xcodeproj \
  -scheme SCHEME_NAME \
  -configuration Release \
  -archivePath ~/Desktop/APP-VERSION.xcarchive \
  archive

确认已创建归档:

ls -la ~/Desktop/APP-VERSION.xcarchive

第 3 步:导出并进行代码签名

创建导出选项文件:

cat > /tmp/ExportOptions.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>destination</key>
	<string>export</string>
	<key>method</key>
	<string>developer-id</string>
	<key>signingStyle</key>
	<string>automatic</string>
	<key>teamID</key>
	<string>YOUR_TEAM_ID</string>
	<key>signingCertificate</key>
	<string>Developer ID Application</string>
</dict>
</plist>
EOF

将 YOUR_TEAM_ID 替换为你的实际团队 ID。

导出归档:

xcodebuild -exportArchive \
  -archivePath ~/Desktop/APP-VERSION.xcarchive \
  -exportPath ~/Desktop/APP-VERSION-Export \
  -exportOptionsPlist /tmp/ExportOptions.plist

验证导出应用的版本:

defaults read ~/Desktop/APP-VERSION-Export/APP.app/Contents/Info.plist CFBundleShortVersionString

这里应显示新的版本号。

验证代码签名:

codesign -dvvv ~/Desktop/APP-VERSION-Export/APP.app

在 Authority 行中查找 “Developer ID Application”。

第 4 步:创建 Zip 并生成 Sparkle 签名

创建用于 Sparkle 自动更新的 Zip 文件:

cd ~/Desktop/APP-VERSION-Export
ditto -c -k --keepParent APP.app APP.app.zip

生成 Sparkle EdDSA 签名(系统会提示输入私钥):

echo "YOUR_SPARKLE_PRIVATE_KEY" | \
  ~/Library/Developer/Xcode/DerivedData/PROJECT-HASH/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update \
  APP.app.zip --ed-key-file -

输出格式:

sparkle:edSignature="BASE64_SIGNATURE" length="FILE_SIZE"

保存签名和文件大小,以便更新 appcast.xml。

更多详情请参阅 SPARKLE.md。

第 5 步:创建带有 Applications 文件夹的 DMG

创建带有 Applications 文件夹符号链接的 DMG 安装器,以支持拖放安装:

TEMP_DMG_DIR="/tmp/APP_dmg" && \
rm -rf "${TEMP_DMG_DIR}" && \
mkdir -p "${TEMP_DMG_DIR}" && \
cp -R ~/Desktop/APP-VERSION-Export/APP.app "${TEMP_DMG_DIR}/" && \
ln -s /Applications "${TEMP_DMG_DIR}/Applications" && \
hdiutil create -volname "APP VERSION" \
  -srcfolder "${TEMP_DMG_DIR}" \
  -ov -format UDZO ~/Desktop/APP-VERSION.dmg && \
rm -rf "${TEMP_DMG_DIR}"

确认 DMG 内容:

hdiutil attach ~/Desktop/APP-VERSION.dmg -readonly -nobrowse -mountpoint /tmp/verify_dmg && \
ls -la /tmp/verify_dmg && \
hdiutil detach /tmp/verify_dmg

你应能看到 APP.app 和 Applications(符号链接)。

第 6 步:提交公证

将 DMG 提交给 Apple 进行公证(系统会提示输入凭据):

xcrun notarytool submit ~/Desktop/APP-VERSION.dmg \
  --apple-id [email protected] \
  --team-id YOUR_TEAM_ID \
  --password YOUR_APP_SPECIFIC_PASSWORD \
  --wait

--wait 标志会让命令等待处理完成(通常需要 1-2 分钟)。

预期输出:

Processing complete
  id: [submission-id]
  status: Accepted

如果状态为 “Invalid”,请获取详细日志:

xcrun notarytool log SUBMISSION_ID \
  --apple-id [email protected] \
  --team-id YOUR_TEAM_ID \
  --password YOUR_APP_SPECIFIC_PASSWORD

公证问题排查请参阅 NOTARIZATION.md。

第 7 步:附加公证票据

将公证票据附加到 DMG:

xcrun stapler staple ~/Desktop/APP-VERSION.dmg

预期输出:

The staple and validate action worked!

验证公证:

spctl -a -vvv ~/Desktop/APP-VERSION-Export/APP.app

应显示:

accepted
source=Notarized Developer ID

第 8 步:更新 appcast.xml

使用第 4 步获取的新版本、签名和文件大小更新 Sparkle appcast 文件:

<item>
  <title>Version X.X.X</title>
  <link>https://github.com/USER/REPO</link>
  <sparkle:version>X.X.X</sparkle:version>
  <sparkle:channel>stable</sparkle:channel>
  <description><![CDATA[
    Release version X.X.X
  ]]></description>
  <pubDate>DAY, DD MMM YYYY HH:MM:SS -0700</pubDate>
  <enclosure
    url="https://github.com/USER/REPO/releases/download/vX.X.X/APP.app.zip"
    sparkle:version="X.X.X"
    sparkle:edSignature="SIGNATURE_FROM_STEP_4"
    length="FILE_SIZE_FROM_STEP_4"
    type="application/octet-stream" />
</item>

注意: gitleaks 提交前钩子可能会将 Sparkle 签名标记为潜在密钥。这是误报——EdDSA 签名是公开的,可以安全提交。如有需要,请使用 git commit --no-verify。

第 9 步:提交并推送更改

提交版本更新和 appcast 更改:

git add PROJECT.xcconfig appcast.xml
git commit --no-verify -m "Bump version to X.X.X

Update appcast.xml with new version, Sparkle signature, and file size.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>"

git push

第 10 步:更新 GitHub 发布

创建或更新 GitHub 发布并添加新资源:

对于新发布:

gh release create vX.X.X \
  --title "APP vX.X.X" \
  --notes "Release version X.X.X" \
  ~/Desktop/APP-VERSION.dmg \
  ~/Desktop/APP-VERSION-Export/APP.app.zip

对于更新现有发布:

# Upload new assets (overwrites existing with --clobber)
gh release upload vX.X.X \
  ~/Desktop/APP-VERSION.dmg \
  ~/Desktop/APP-VERSION-Export/APP.app.zip \
  --clobber

关于资源命名的说明: 上传的文件名将成为资源名称。若要使用指定名称上传:

# Copy to desired name first
cp ~/Desktop/APP-1.0.9.dmg /tmp/APP.dmg
gh release upload vX.X.X /tmp/APP.dmg

验证发布资源:

gh release view vX.X.X --json assets -q '.assets[] | "\(.name) - \(.size) bytes"'

第 11 步:最终验证

确认发布正常运行:

检查应用中的版本:

defaults read /Applications/APP.app/Contents/Info.plist CFBundleShortVersionString

应显示:X.X.X

测试 DMG:

  1. 从 GitHub 发布下载 DMG
  2. 打开 DMG
  3. 确认其中有 Applications 文件夹,可用于拖放安装
  4. 将应用拖到 Applications 并启动
  5. 应能正常打开,不出现任何“恶意软件”或安全警告

测试 Sparkle 更新:

  • 使用旧版本的用户应收到自动更新通知
  • 更新应能顺利下载并安装

常见问题

如果遇到问题,请参阅 TROUBLESHOOTING.md 查找以下问题的解决方案:

  • 重建后版本未更新
  • DMG 缺少 Applications 文件夹
  • 公证失败
  • “恶意应用”警告
  • Sparkle 签名问题
  • CI/CD 失败

快速参考

检查版本:

defaults read /path/to/APP.app/Contents/Info.plist CFBundleShortVersionString

检查代码签名:

codesign -dvvv /path/to/APP.app

检查公证:

spctl -a -vvv /path/to/APP.app

获取 Sparkle sign_update 路径:

find ~/Library/Developer/Xcode/DerivedData -name sign_update -type f

评论

支持 Markdown