macOS应用发布技能Skill releasing-macos-apps

此技能用于创建已公证的macOS应用发布工作流,包括Sparkle自动更新、DMG安装程序和GitHub发布。涉及版本管理、代码签名、公证提交和分发自动化,适用于macOS应用开发者进行高效、安全的软件发布。关键词:macOS应用发布,Sparkle自动更新,DMG安装程序,代码签名,公证流程,GitHub发布,自动化工作流,应用分发。

DevOps 0 次安装 0 次浏览 更新于 3/17/2026

名称: 发布macOS应用 描述: 创建带有Sparkle自动更新、DMG安装程序和GitHub发布的已公证macOS应用发布。适用于发布macOS应用、创建DMG文件、公证应用或设置Sparkle更新。处理版本更新、代码签名、公证和分发。

发布macOS应用

创建带有Sparkle自动更新、DMG安装程序和GitHub发布的已公证macOS应用发布的完整工作流。

发布检查列表

复制此检查列表并跟踪进度:

发布进度:
- [ ] 步骤1:检查先决条件(证书、凭证)
- [ ] 步骤2:在.xcconfig文件中更新版本
- [ ] 步骤3:构建和归档应用
- [ ] 步骤4:使用适当代码签名导出
- [ ] 步骤5:创建zip并生成Sparkle签名
- [ ] 步骤6:创建带有Applications文件夹的DMG
- [ ] 步骤7:提交公证
- [ ] 步骤8:将公证凭证附加到DMG
- [ ] 步骤9:更新appcast.xml文件中的新签名
- [ ] 步骤10:提交和推送更改
- [ ] 步骤11:更新GitHub发布资源
- [ ] 步骤12:验证DMG和版本号

先决条件

开始发布前,验证:

  1. Apple Developer ID应用证书 已安装且有效
  2. Apple ID凭证 用于公证:
    • Apple ID邮箱
    • 应用特定密码(在appleid.apple.com生成)
    • 团队ID
  3. Sparkle私钥 用于签名更新
  4. GitHub CLI (gh) 已安装且认证
  5. 版本配置位置 已识别(通常是.xcconfig文件)

检查证书:

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

步骤1:更新版本

定位您的版本配置文件(常见如ProjectName.xcconfigproject.pbxproj)。

对于.xcconfig文件:

# 编辑APP_VERSION行
# 示例: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.appApplications(符号链接)。

步骤6:提交公证

将DMG提交给Apple进行公证(将提示凭证):

xcrun notarytool submit ~/Desktop/APP-VERSION.dmg \
  --apple-id YOUR_APPLE_ID@gmail.com \
  --team-id YOUR_TEAM_ID \
  --password YOUR_APP_SPECIFIC_PASSWORD \
  --wait

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

预期输出:

处理完成
  id: [submission-id]
  状态: 已接受

如果状态为“无效”,获取详细日志:

xcrun notarytool log SUBMISSION_ID \
  --apple-id YOUR_APPLE_ID@gmail.com \
  --team-id YOUR_TEAM_ID \
  --password YOUR_APP_SPECIFIC_PASSWORD

公证问题排查,请见NOTARIZATION.md

步骤7:附加公证凭证

将公证凭证附加到DMG:

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

预期输出:

附加和验证操作成功!

验证公证:

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

应该显示:

已接受
来源=已公证开发者ID

步骤8:更新appcast.xml

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

<item>
  <title>版本 X.X.X</title>
  <link>https://github.com/USER/REPO</link>
  <sparkle:version>X.X.X</sparkle:version>
  <sparkle:channel>稳定</sparkle:channel>
  <description><![CDATA[
    发布版本 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="步骤4中的签名"
    length="步骤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 "版本提升至 X.X.X

更新appcast.xml文件中的新版本、Sparkle签名和文件大小。

🤖 由[Claude Code](https://claude.com/claude-code)生成

合著者: Claude <noreply@anthropic.com>"

git push

步骤10:更新GitHub发布

使用新资源创建或更新GitHub发布:

对于新发布:

gh release create vX.X.X \
  --title "APP vX.X.X" \
  --notes "发布版本 X.X.X" \
  ~/Desktop/APP-VERSION.dmg \
  ~/Desktop/APP-VERSION-Export/APP.app.zip

对于更新现有发布:

# 上传新资源(使用--clobber覆盖现有)
gh release upload vX.X.X \
  ~/Desktop/APP-VERSION.dmg \
  ~/Desktop/APP-VERSION-Export/APP.app.zip \
  --clobber

资源命名注意: 上传的文件名成为资源名称。要上传特定名称:

# 先复制到所需名称
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