关于 release-mac-app
用于从应用仓库发布采用 Sparkle 更新的 macOS 应用的技能,提供共用的发布、appcast、验证和签名流程,同时保留各应用自己的打包脚本。
主要功能
- 01查看发布状态并生成说明
- 02创建并验证 appcast
- 03检查资源并执行发布流程
- 04处理 Sparkle 与 Developer ID 签名
- 05通过 1Password 和 Keychain 管理凭据
适用场景
- 01准备 Sparkle 应用发布
- 02检查 appcast 条目和下载构建
- 03在自动打包时执行签名
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ steipete/ agent-scripts --skill release-mac-app安装后在 Claude Code 中输入/release-mac-app确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/mac-releasemac-release-assets.test.shmac-release-canary.test.shmac-release-download.test.shmac-release-provider.test.shmac-release-publication.test.shmac-release.test.shscripts/lib/mac_release.sh详细介绍
Mac 应用发布
适用于 BlackBar、RepoBar、CodexBar、Trimmy 及其他使用 Sparkle 更新的 macOS 应用。
规则
- 在应用仓库中操作。
- 读取
.mac-release.env;这是由仓库管理的发布清单。 - 使用此技能中的
scripts/mac-release执行通用的发布、appcast 和验证工作。 - 直接执行
mac-release,使其特权 Bash shebang 忽略启动钩子;如果必须显式指定解释器,请使用/bin/bash -p,绝不要使用普通的bash mac-release。 - 除非应用特有的构建/打包/签名行为已由清单驱动,否则将其保留在仓库脚本中。
- 绝不输出私钥材料。
- 在发布前,先将应用和 dSYM 资源上传到草稿版本。失败后,保留发布版本、标签、appcast 提交和本地编辑;检查现有状态并从失败步骤继续,而不是删除或重新标记可能已发布的版本。
- 如果密钥存储在 1Password 中,无头发布签名优先使用
MAC_RELEASE_SPARKLE_OP_REF;否则优先使用 Keychain Sparkle 签名。SPARKLE_PRIVATE_KEY_FILE仅用于显式指定本地覆盖项。
命令
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release status
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release notes [version] [output.md]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release changelog-html <version> [CHANGELOG.md]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release make-appcast <zip> [feed-url]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release verify-appcast [version]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release check-assets [tag]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release release
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release codesign-run [--with-package-secrets] -- <command> [args...]
/Users/steipete/Projects/agent-scripts/skills/release-mac-app/scripts/mac-release package-run -- <command> [args...]
清单
每个仓库都自行维护 .mac-release.env。其中不得包含机密信息。
必填项:
MAC_RELEASE_APP_NAMEMAC_RELEASE_REPOMAC_RELEASE_BUNDLE_IDMAC_RELEASE_VERSION_FILEMAC_RELEASE_APPCASTMAC_RELEASE_FEED_URLMAC_RELEASE_DOWNLOAD_URL_PREFIXMAC_RELEASE_APP_ZIPMAC_RELEASE_INFO_PLIST或MAC_RELEASE_SUPUBLIC_ED_KEYMAC_RELEASE_PACKAGE_CMD
常见可选项:
MAC_RELEASE_PRECHECKMAC_RELEASE_SOURCE_FILES(展开制品名称前要 source 的应用辅助文件,以空格分隔)MAC_RELEASE_DSYM_ZIPMAC_RELEASE_REQUIRE_DSYM=0,用于仅发布应用的情况MAC_RELEASE_ARTIFACT_PREFIXMAC_RELEASE_TAG_SIGNEDMAC_RELEASE_TAG_FORCEMAC_RELEASE_RELEASE_BRANCHMAC_RELEASE_SPARKLE_ACCOUNTMAC_RELEASE_SPARKLE_CHANNELMAC_RELEASE_GENERATE_APPCAST_ARGSMAC_RELEASE_RUN_SPARKLE_UPDATE_TESTMAC_RELEASE_SPARKLE_OP_REF— Sparkle EdDSA 私钥的精确op://Vault/Item/field引用。该辅助程序会在共享的op-worktmux 会话中解析此引用,仅写入权限模式为 0600 的临时密钥文件,根据SUPublicEDKey验证其公钥,并在成功或失败后将其删除。MAC_RELEASE_SPARKLE_OP_ACCOUNT和MAC_RELEASE_SPARKLE_OP_USE_SERVICE_ACCOUNT可覆盖 Sparkle 引用的主要 1Password 账户/服务账户模式。由服务账户支持的引用应将服务账户模式设为1。MAC_RELEASE_SIGNING_KEY_FILE(仅用作本地回退路径;文件不存在时使用 Keychain)MAC_RELEASE_EXTRA_ASSET_PATTERNSMAC_RELEASE_EXTRA_ASSET_WAIT_SECONDSMAC_RELEASE_EXTRA_ASSET_WAIT_INTERVALMAC_RELEASE_OP_ENV_REFS— 以;分隔的NAME=op://Vault/Item/field条目,会在同一轮凭据读取中解析并导出,供打包命令使用(条目名称可能包含空格,因此使用;)。优先使用已导出的名称;仅当名称缺失时才会通过op read解析引用。示例:NPM_TOKEN=op://Molty/npm Registry - steipete - Release Automation/registry_token。MAC_RELEASE_OP_ITEM+MAC_RELEASE_OP_FIELDS,用于必需的打包密钥。发布辅助程序会在一个持久 tmux 会话中通过op读取一次已知条目,然后导出所请求的字段,供打包命令使用。MAC_RELEASE_OP_ACCOUNT默认为my.1password.com;MAC_RELEASE_OP_VAULT、MAC_RELEASE_OP_TMUX_SESSION、MAC_RELEASE_OP_WAIT_SECONDS为可选项。若未指定保管库,单次op读取时会取消设置服务账户令牌环境变量,由个人桌面账户处理。MAC_RELEASE_CODESIGN_IDENTITY+MAC_RELEASE_CODESIGN_OP_ITEM+MAC_RELEASE_CODESIGN_KEYCHAIN_MANAGED=1可启用非交互式 Developer ID 签名。钥匙串必须可替换,专用于发布自动化,与默认钥匙串分离、不与交互式用途共用,并且只包含一个签名私钥。该辅助程序负责管理该密钥,并可能永久规范化其分区 ACL 为apple-tool:,apple:,codesign:。预检后,同一轮 tmux 凭据读取会读取keychain_path,通常还会读取keychain_password,获取每用户发布锁,在不隐藏现有钥匙串的情况下将该钥匙串置于首位,验证 Developer ID Application canary,通过临时codesign --keychainshim 限定打包签名范围,然后恢复临时状态并释放锁。仅当使用规范的、无密码且永不锁定的发布钥匙串时,才设置MAC_RELEASE_CODESIGN_PASSWORDLESS=1;这会省略密码字段、保留钥匙串的解锁状态,并禁用超时/睡眠时锁定设置。MAC_RELEASE_CODESIGN_OP_ACCOUNT、MAC_RELEASE_CODESIGN_OP_VAULT、MAC_RELEASE_CODESIGN_OP_USE_SERVICE_ACCOUNT、MAC_RELEASE_CODESIGN_OP_PATH_FIELD和MAC_RELEASE_CODESIGN_OP_PASSWORD_FIELD可覆盖 codesign 凭据条目的默认值;否则,账户、保管库和服务账户模式会继承主要条目设置。对于个人桌面账户条目,将保管库设为空,并将服务账户模式设为0。也可以直接提供MAC_RELEASE_CODESIGN_KEYCHAIN+MAC_RELEASE_CODESIGN_KEYCHAIN_PASSWORD。- 设置
MAC_RELEASE_RUN_LOGIN_SHELL=1可让命令钩子重新使用bash -lc;默认钩子使用env -u BASH_ENV bash -c,以防 shell 启动文件覆盖已导出的发布密钥。
1Password 规则:
- 优先使用已导出的环境变量;如果
MAC_RELEASE_OP_FIELDS中的字段都已提供,则不调用op。 - 如果缺少字段,则通过一条 tmux 命令读取本次发布所需的 package 和 codesign 配置项。
- 丢弃 Provider 的标准错误输出和解析器异常;读取失败时,以固定的 Provider 读取、JSON/schema、缺少字段或解析失败诊断信息停止,不显示值或字段标签。
- 直接通过环境变量引用传递时,使用 Bash
%q在 Bash 3.2 上安全保留捕获的值;命令替换仍会去掉op read输出末尾的换行符。 - 解析
MAC_RELEASE_SPARKLE_OP_REF时,不得将私钥暴露在生成的环境文件或日志中; 只有临时文件路径会跨越辅助程序边界传递。 - 仅在明确指定 vault 或设置
MAC_RELEASE_OP_USE_SERVICE_ACCOUNT=1时使用服务账户模式。 - 不要在新的 shell 中重试
op读取;只有在用户明确指示后,才能从同一个 tmux 会话重新运行。 - 绝不允许发布流程在 Developer ID 钥匙串尚未准备就绪时进入应用打包阶段。发布期间不得出现 SecurityAgent 密码窗口;先运行签名 canary,失败时立即停止。
- 对于非应用发布脚本,使用
codesign-run,不要将钥匙串设置代码复制到仓库中。通过.mac-release.env或显式的MAC_RELEASE_CODESIGN_*环境配置提供 codesign 清单字段。默认情况下,它只加载 codesign 凭据;如果封装的发布脚本还需要同一次 1Password 读取中的已配置 package/notary 字段,则传入--with-package-secrets。它会运行有界签名 canary,通过受管理钥匙串的 shim 限定codesign的作用范围,并在返回前恢复设置并重新锁定。 - 如果不需要执行签名操作,则使用
package-run处理公证/打包凭据。它不会解析、准备或解锁 Developer ID 钥匙串,并会从子进程中移除签名和 Sparkle 权限。 - 加载发布机密前,禁用 shell xtrace 和 verbose 模式。在修改钥匙串/搜索列表前启用清理机制,恢复专用钥匙串原有的锁定策略和用户搜索列表,并在打包后重新锁定。
完成
- appcast 条目包含 URL、长度和 Sparkle 签名。
- 下载的 enclosure 已通过 Sparkle 验证。
- 解压后的应用已通过
codesign、spctl和stapler validate检查。 - GitHub 发布版本包含应用 zip;如已配置,还包含 dSYM zip,以及应用专属的额外资源。
- 发布说明与变更日志章节一致。
- 发布验证通过后,在应用仓库中将变更日志更新为下一个补丁版本的
Unreleased。
评论
支持 Markdown