使用 GitHub Actions 全自动发布 Safari 扩展

使用 GitHub Actions 全自动发布 Safari 扩展

💡 原文中文,约7200字,阅读约需18分钟。
📝

内容提要

本文介绍如何利用GitHub Actions实现Safari扩展的全自动发布流程。通过两个工具(wxt-module-safari-xcode和safari-webext-publish-action),将构建、签名、上传和提交审核等步骤自动化。用户只需修改package.json中的版本号并推送代码,即可触发发布。文章详细说明了配置WXT、准备证书、Provisioning Profiles和API密钥等前置条件,并解释了workflow中build和submit两个job的分工。

🔎

延伸解读

自动化流程的适用边界

文章明确指出,如果只有一两个 Safari 扩展,手动流程可能更划算,因为自动化需要一次性配置大量 secrets。但若扩展数量多或发版频繁,自动化能显著降低每次发版的心智负担。读者应评估自身扩展数量和发版频率,再决定是否投入配置成本。

secrets 的复用与专属

证书和 API 密钥是账户级的,配置一次可跨项目复用;而 Provisioning Profiles 是按扩展生成的,每个新扩展都需要单独创建。理解这一区别有助于规划多扩展的配置策略,避免重复劳动或遗漏。

构建与提交分离的设计

workflow 拆分为 build 和 submit 两个 job,前者在 macOS runner 上完成签名上传,后者在便宜的 ubuntu runner 上调用 API 提交审核。这种设计既满足了构建环境需求,又降低了运行成本,同时通过 release-notes 参数自动填充更新说明,省去手动填写步骤。

Q&A

如何使用 GitHub Actions 自动发布 Safari 扩展?

通过配置 GitHub Actions workflow,使用 wxt-module-safari-xcode 将扩展转换为 Xcode 项目,并使用 safari-webext-publish-action 自动完成构建、签名、上传和提交审核。只需修改 package.json 中的版本号并推送代码,即可触发发布。

wxt-module-safari-xcode 的作用是什么?

wxt-module-safari-xcode 是一个 WXT 模块,在构建时自动将扩展转换为配置好的 Xcode 项目,并注入版本号、App 分类、开发团队等配置,省去手动使用 xcrun safari-web-extension-converter 的繁琐步骤。

safari-webext-publish-action 的 build 和 submit 模式有什么区别?

build 模式在 macOS runner 上运行,负责导入证书、构建签名、打包并上传 bundle 到 App Store Connect;submit 模式在 ubuntu runner 上运行,调用 App Store Connect API 创建新版本、关联 bundle、填写 release notes 并提交审核。

配置 Safari 扩展自动发布需要哪些 secrets?

需要三类 secrets:证书相关(APPLE_CERTIFICATE_BASE64 和 APPLE_CERTIFICATE_PASSWORD)、Provisioning Profiles(4 个 base64 编码的 profile)、App Store Connect API 密钥(APPLE_API_KEY、APPLE_API_KEY_ID、APPLE_API_ISSUER)。

如何获取 Apple 分发证书并导出为 .p12 文件?

在 Apple Developer 的 Certificates 页面创建三张分发证书:Mac App Distribution、Mac Installer Distribution 和 Apple Distribution(注意命名陷阱)。下载后双击导入钥匙串,然后在「钥匙串访问」中同时选中这三张证书(确认有私钥),右键导出为单个 .p12 文件,并设置导出密码。

为什么 Safari 扩展发布需要专门的工具?

因为 Safari 扩展本质上是一个 App,发布走 App Store,需要处理 Xcode 项目、证书、签名、公证、provisioning profile 等 Apple 分发体系,而 Chrome/Firefox/Edge 的发布 WXT 已经做得很好,一条命令即可。

如何配置 WXT 以生成 Safari Xcode 项目?

在 wxt.config.ts 中添加 wxt-module-safari-xcode 模块,并配置 safariXcode 选项,包括 projectName、appCategory、bundleIdentifier 和 developmentTeam。然后运行 pnpm wxt build -b safari,即可生成 Xcode 项目到 .output/<projectName>。

Provisioning Profiles 需要为每个扩展单独创建吗?

是的,Provisioning Profiles 是按扩展算的,每新增一个 Safari 扩展都需要为它的 App 和 Extension 两个 target 分别创建 macOS 和 iOS 的 profile,共 4 个。这是唯一不能跨项目复用的 secrets。

如何获取 App Store Connect API 密钥?

在 App Store Connect 的 Integrations 页面创建团队 API 密钥,角色选择 App Manager(最小权限)。创建后下载 .p8 私钥文件(只能下载一次),将 base64 编码存入 APPLE_API_KEY,Key ID 存入 APPLE_API_KEY_ID,Issuer ID 存入 APPLE_API_ISSUER。

这套自动化流程适合什么情况?

如果只有一两个 Safari 扩展,手动流程可以忍受;但如果有三个以上或发版频繁,自动化能显著降低发版成本。一次性配置 secrets 后,每次发版只需修改版本号并推送代码。

🏷️

标签

➡️

继续阅读