☰
Presenton Mac App Store 打包实操:证书、Profile 到 MAS 构建脚本全打通
2026/10/2 16:56:49 网站建设 项目流程

Presenton Mac App Store 打包实操:证书、Profile 到 MAS 构建脚本全打通

【免费下载链接】presentonOpen-Source AI Presentation Generator and API (Gamma, Canva, Beautiful AI, Decktopus, Presentations AI Alternative)项目地址: https://gitcode.com/GitHub_Trending/pr/presenton

把 Presenton 的 Electron 客户端推进 Mac App Store 审核,最容易翻车的不是前端或后端代码,而是签名链:一个带-beta后缀的版本号、一个还躺在仓库里的占位 profile、一次钥匙串私钥授权弹窗——任何一环没接好,electron-builder都会在半路停下来报错。这篇按"Apple 侧一次性准备 → 沙盒权限 → 构建跑通 → 产物与自测"的顺序,带你把 Presenton Mac App Store 打包从证书申请做到.pkg上传,涉及的脚本、环境变量、报错对照表都落在仓库真实文件里。

三种打包目标,先认对门牌

Presenton 在 macOS 上把打包拆成三种目标,全部由环境变量PRESENTON_MAC_TARGET驱动,你在 npm 脚本里不用手动设它。选错目标,产物就装不上对应的分发渠道:

目标值分发场景对应 npm 脚本
dmg绕开 App Store 的直接下载npm run build:all:mac:signed
mas-dev已注册 Mac 上的沙盒内测npm run build:all:mas-dev
mas提交 Mac App Store 审核npm run build:all:mas

所有打包逻辑集中在 electron/build.js 里。文件开头有两个常量值得先记住:APP_ID是com.presenton.presenton,即应用标识(Bundle ID);TEAM_ID是S6W5C54KL6,会写进mac.extendInfo.ElectronTeamID字段。这两个值是后面证书与 Profile 配置的锚点,换成你自己的团队就得同步改它们。

一次性搞定 Apple 的四件套

签名链的原料分四份,前两份是证书,第三份是 App ID,第四份是两份 profile。开发链路只用到前三份里的"开发证书",提交链路则要把分发那一套备齐。

开发用:一张 Apple Development 证书

在 Xcode →Settings→Accounts→ 你的团队 →Manage Certificates→+→Apple Development生成。它只服务于mas-dev目标和本地沙盒测试。

分发用:两张证书缺一不可

同样是上面的入口,选Apple Distribution。这里有个坑:mas(分发)构建实际要匹配两张证书。electron/build.js 的resolveMasSigningIdentities会同时找——

  • 应用证书:名字匹配Apple Distribution或3rd Party Mac Developer Application
  • 安装器证书:名字匹配3rd Party Mac Developer Installer

两者缺一,构建直接抛错并列出钥匙串里现有的身份。

App ID 与 Bundle ID

Apple Developer Portal →Certificates, Identifiers & Profiles→Identifiers→App IDs,建一个与com.presenton.presenton匹配的 macOS App ID。若你用别的 ID,得回头改 electron/build.js 里的APP_ID。

两份 Profile 的落位与验证

Portal →Profiles→+里各建一个 macOS profile,下载后放进electron/build/:

用途Profile 类型关联证书落位文件名备选文件名
MAS 开发(mas-dev)macOS App DevelopmentApple Developmentbuild/AppleDevelopment.provisionprofileAppleDev.provisionprofile/AppDev.provisionprofile
MAS 分发(mas)Mac App StoreApple Distributionbuild/MacAppStore.provisionprofileAppDistri.provisionprofile

下载后立刻验证能否解码,别等构建时才发现问题:

cd electron # -D 表示 decode,检查 profile 是否为合法 DER 编码 security cms -D -i build/AppleDevelopment.provisionprofile security cms -D -i build/MacAppStore.provisionprofile

两点提醒:Profile 通常按年过期,过期要重新生成并替换本地文件;真实 profile不要提交进 git,仓库里的MacAppStore.provisionprofile.replace_me占位文件就是为此留的位。

沙盒权限清单:entitlements 开了哪些口子

MAS 强制启用 App Sandbox,Presenton 的主进程权限写在 electron/build/entitlements.mas.plist。每一项对应一个具体的运行能力:

权限 key打开的能力
com.apple.security.app-sandbox启用 App Sandbox,MAS 硬性要求
com.apple.security.application-groups值为S6W5C54KL6.com.presenton.presenton,让应用与组件共享容器
com.apple.security.cs.allow-jit允许 JIT 编译,Electron 渲染进程依赖此项
com.apple.security.network.client发起出站网络连接
com.apple.security.network.server监听本地端口,支撑内置 Next.js / FastAPI 本地服务
com.apple.security.files.user-selected.read-write读写用户主动选定的文件(导入文档、导出 PPTX)
com.apple.security.files.downloads.read-write读写下载目录

辅助进程与内置二进制走 electron/build/entitlements.mas.inherit.plist,只声明沙盒加com.apple.security.inherit,表示继承主进程的能力边界,不额外开洞。

一条命令跑通构建

所有命令都在electron/目录下执行。第一次用先跑初始化脚本,它会串起npm install、FastAPI 的uv sync、Next.js 依赖安装,以及导出运行时和 ImageMagick 的准备:

# 首次初始化,完成前后端依赖与运行时准备 npm run setup:env

完整构建(推荐)

会重建 Next.js、FastAPI、导出运行时再打包,适合从零开始或改动较大时:

# MAS 开发:只能在开发 profile 注册的 Mac 上运行 PRESENTON_MAS_DEV_IDENTITY="Apple Development: Your Name (TEAMID)" \ npm run build:all:mas-dev # MAS 分发:用于上传 App Store Connect PRESENTON_MAS_DISTRIBUTION_IDENTITY="Apple Distribution: Your Org (TEAMID)" \ PRESENTON_APP_STORE_VERSION=1.0.0 \ npm run build:all:mas

只重打包(资源已构建好)

跑过build:all后只想再走一遍 electron-builder 打包阶段,用dist:*系列:

PRESENTON_MAS_DEV_IDENTITY="Apple Development: Your Name (TEAMID)" \ npm run dist:mac:mas-dev PRESENTON_MAS_DISTRIBUTION_IDENTITY="Apple Distribution: Your Org (TEAMID)" \ PRESENTON_APP_STORE_VERSION=1.0.0 \ npm run dist:mac:mas

注意:dist:*脚本依赖 electron/build.js 的资源就绪校验。它会逐一检查 FastAPI 二进制、LLM 模型元数据、Next.js standalone server、导出任务 runner、export-core 包以及导出用的 sharp 运行时,任何一项缺失都会在打包前报错,避免打出"启动不了内置服务"的坏包。

不走 App Store 的 DMG

只想要一份签名并公证(notarize)的 macOS 磁盘映像、跳过 App Store 审核时:

# 走 Developer ID Application 证书,需要 Apple 公证凭据 npm run build:all:mac:signed

这条路径用的不是 MAS 证书,而是 Developer ID 证书,完整的证书准备与 notarytool 凭据存储见 macOS 直接分发指南。

版本号:为什么-beta后缀会让 mas 直接报错

当前 electron/package.json 的版本形如0.9.11-beta(带-beta后缀)。mas目标要求 App Store 版本号严格是三段点分整数,于是 electron/build.js 的getAppStoreBundleShortVersion做了两级回退:

  • 优先读PRESENTON_APP_STORE_VERSION,必须匹配/^\d+\.\d+\.\d+$/;
  • 没设时尝试从 package 版本里截x.y.z前缀;截不出来(比如版本根本不是语义化)就抛Cannot derive an App Store version from package version。

build 号由getAppStoreBundleVersion读PRESENTON_APP_STORE_BUILD,匹配/^\d+(\.\d+){0,2}$/(1~3 段,如42或1.0.1),没设则回退到短版本号。所以带 beta 后缀的包,构建mas时这两个变量基本是必填:

# 版本号必须是三段整数;build 号可省略(默认取短版本号) export PRESENTON_APP_STORE_VERSION=1.0.0 export PRESENTON_APP_STORE_BUILD=42

其余环境变量集中在这里,配命令时对着查:

变量生效目标含义
PRESENTON_MAC_TARGET脚本注入mas-dev/mas,配合上述脚本时别手动设
PRESENTON_MAS_DEV_IDENTITYmas-dev开发签名身份,如Apple Development: 名字 (TEAMID)
PRESENTON_MAS_DISTRIBUTION_IDENTITYmas分发身份,如Apple Distribution: 组织 (TEAMID)
PRESENTON_MAS_IDENTITYmas上一项的别名
CSC_NAME两者上面专属变量都没设时的回退
PRESENTON_APP_STORE_VERSIONmas商店版本号x.y.z;package 版本带后缀时必填
PRESENTON_APP_STORE_BUILDmas商店 build 号,默认取短版本号
PRESENTON_CODESIGN_TIMESTAMPmas设1恢复 codesign 时间戳,默认走--timestamp=none
PRESENTON_CODESIGN_TIMESTAMP_RETRIESmas时间戳失败重试次数,默认 4

后两个时间戳开关解释一下:本地 MAS 打包默认加--timestamp=none,是为了不依赖 Apple 时间戳服务(无网或受限网络下不挂起);真要时间戳就把PRESENTON_CODESIGN_TIMESTAMP设为1,重试次数用PRESENTON_CODESIGN_TIMESTAMP_RETRIES调。

产物落点与上传入口

所有产物统一输出到electron/dist/,具体子目录随架构(arm64/x64)变化,典型布局:

electron/dist/ mas-dev-arm64/ # mas-dev:未签名或开发签名的 .app mas-arm64/ # mas:分发签名的 .app Presenton-<version>.pkg # 用于上传 App Store Connect 的 MAS 安装包 Presenton-<version>.dmg # 签名并公证的直接分发 DMG

把mas构建产出的.pkg传进 App Store Connect,就进入审核与发布流程。

build.js 在打包前替你拦下的三个坑

这几处是 electron/build.js 里最有工程价值的部分,理解它们能少踩很多隐性错误:

资源就绪校验。collectMissingBundleResources把上面dist:*提到的五项资源列成清单,打包前后各查一遍(afterPack阶段还会再确认一次装进.app的副本),缺项就列出路径并停手。

签名身份解析。mas-dev的身份直接取PRESENTON_MAS_DEV_IDENTITY,没设回退CSC_NAME。mas更复杂:resolveMasSigningIdentities会跑security find-identity -v读全钥匙串身份,身份限定词依次从PRESENTON_MAS_DISTRIBUTION_IDENTITY、PRESENTON_MAS_IDENTITY、CSC_NAME取,最后自动发现匹配的证书对。它还会拒绝把 Apple Development 这类开发身份用于分发构建,防止你拿错证书打分发包。

codesign 预检与平台限制。分发构建启动前,assertCodesignCanUseIdentity会拿一个临时文件用选中的分发身份实际签一次,超时(通常是 macOS 在等钥匙串/私钥授权)就给出"解锁登录钥匙串并允许 codesign 访问私钥"的明确提示。另外resolveProvisioningProfile在非 darwin 平台会直接抛MAS builds must be run on macOS——Apple 签名工具只在 macOS 上可用,这条没有绕过办法。

图标与 .icns

默认 macOS 图标来自electron/resources/ui/assets/images/presenton_short_filled.png。想给 App Store 打包换正式.icns,把它放到electron/build/icon.icns,并同步改 electron/build.js 里mac配置下的icon字段(当前指向build/icon.icns)。生成图标集用的源 PNG 在electron/build/icon.iconset/目录里。

内测沙盒的四条红线

  • MAS 签名应用必须用 MAS 目标构建(mas或mas-dev),普通 DMG 构建的沙盒兼容性并不等价;
  • mas-dev构建只能跑在开发 profile 注册的 Mac 上,适合做 TestFlight 式的内测;
  • mas(分发)构建通常本地起不来,它是给 App Store Connect 处理和发布用的;
  • mas-dev签名用--timestamp=none,本地签名不依赖网络时间戳服务器,无网也不会挂起。

报错对照表

报错原因与解法
Missing MAS development/distribution provisioning profile把对应目标的.provisionprofile放进electron/build/,脚本会按候选文件名逐一匹配
macOS 提示 profile 无法解码(could not decode)从 Developer Portal 重新下载替换;真实 profile 不要提交 git
Cannot derive an App Store version from package version设PRESENTON_APP_STORE_VERSION为三段整数,如1.0.0
MAS builds must be run on macOS在装了 Xcode 命令行工具的 Mac 上构建(xcode-select --install)
.app 内 FastAPI / 导出二进制不可执行afterPack钩子已对 FastAPI 二进制chmod 755并剪掉与目标架构不符的 prebuild 目录;签名仍失败时检查 entitlements 是否放行Contents/Resources/app/resources/下的辅助程序

参考

  • macOS 开发 README:全部 macOS 构建目标的快速参考
  • macOS 直接分发指南:Developer ID 证书、公证与 DMG 验证流程

【免费下载链接】presentonOpen-Source AI Presentation Generator and API (Gamma, Canva, Beautiful AI, Decktopus, Presentations AI Alternative)项目地址: https://gitcode.com/GitHub_Trending/pr/presenton

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询