news 2026/9/10 9:53:30

fastlane 之 sigh(get_provisioning_profile):一行命令创建、续期、下载与修复 iOS 预置描述文件实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
fastlane 之 sigh(get_provisioning_profile):一行命令创建、续期、下载与修复 iOS 预置描述文件实战指南

fastlane 之 sigh(get_provisioning_profile):一行命令创建、续期、下载与修复 iOS 预置描述文件实战指南

【免费下载链接】fastlane🚀 The easiest way to automate building and releasing your iOS and Android apps项目地址: https://gitcode.com/GitHub_Trending/fa/fastlane

本文以 fastlane 内置动作文档 get_provisioning_profile 为主体,结合仓库中 sigh 工具的真实源码(动作封装、sigh 核心实现 等)深度展开。你将掌握sigh用于 App Store / Ad Hoc / Development / Enterprise 描述文件的生成与维护方法、与certmatch的分工关系,以及它在 fastlane 签名流程中的完整调用链与底层原理。

fastlane sigh是 fastlane 家族中处理Provisioning Profile(预置描述文件)的专用命令,对应 fastlane 动作名为get_provisioning_profile(别名sigh)。它能够在一条命令内完成描述文件的创建(Create)、续期(Renew)、下载(Download)与修复(Repair),支持 App Store、Ad Hoc、Development 与 Enterprise 四种类型,并自动把全部测试设备加入 Ad Hoc / Development 描述文件。读完本文,你可以用它替代在开发者后台手动维护.mobileprovision的繁琐流程,并将其嵌入 Jenkins 等 CI 服务器或自己的Fastfile流水线。

提示:根据 fastlane 官方建议(见文档与代码内注释),一般签名场景优先使用match来生成和维护描述文件(详见仓库内 fastlane/docs/Codesigning/GettingStarted.md 与 match 主页);只有当你希望完全掌控签名细节、熟悉代码签名机制时才直接使用sigh

功能总览

根据 动作文档,sigh提供如下能力:

  • Download:为你的应用下载最新的预置描述文件;
  • Renew:描述文件过期时自动续期;
  • Repair:描述文件损坏或失效时自动修复;
  • Create:当描述文件尚不存在时自动新建;
  • 支持App StoreAd HocDevelopment三种主流类型,并额外支持Enterprise(企业 In-House)描述文件
  • 支持多个 Apple 账号多个 Team,账号凭据安全地存放在系统 Keychain 中;
  • 支持 macOS / Catalyst / tvOS 等平台目标(见下文--platform参数)。

若你需要自动化的是iOS 推送证书(Push Profile),可以改用同一仓库中的pem工具。

为什么不让 Xcode 来生成?

文档给出的理由非常实际:

  • sigh可以轻松集成进CI 服务器(例如 Jenkins、Bamboo、Circle 等,参见 fastlane/docs/Jenkins.md);
  • Xcode 有时会使本机全部现存描述文件失效(SignErrors.png 展示的就是这类签名报错),让人措手不及;
  • 你可以完全掌控每个环节发生了什么、何时发生;
  • 生成的签名文件会保留下来,可以直接供构建脚本使用,或提交到 git 仓库统一管理。

基本用法:一条命令搞定

最简单的用法就是直接运行:

fastlane sigh

没错,这就是全部命令。默认情况下,sigh会为当前工程处理App Store 类型描述文件,完成「存在则下载、不存在则创建、过期/损坏则修复」这一整套逻辑。

传入 App 的 Bundle Identifier 与开发者账号(Apple ID):

fastlane sigh -a com.krausefx.app -u username

其中-a对应app_identifier-u对应username。值得说明的是:从 sigh 的选项定义源码 看,app_identifier的默认值会自动读取Appfile中的配置(CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)),username同样会回退到Appfile中的apple_id/apple_dev_portal_id(sigh/lib/sigh/options.rb#L84-L91),因此只要你在 Appfile 中配置妥当,通常连-a/-u都可以省略。

选择描述文件类型

生成Ad Hoc描述文件(而非默认的 App Store 类型):

fastlane sigh --adhoc

生成Development描述文件:

fastlane sigh --development

生成Developer ID描述文件(macOS 分发用):

fastlane sigh --developer_id

以上三种开关在源码中彼此互斥:adhoc:development:developer_id两两设置了conflicting_options,同时开启会直接报错「You can't enable both :x and :y」(sigh/lib/sigh/options.rb#L16-L42)。此外,Enterprise(In-House)描述文件属于企业开发者账号场景,会依据账号类型自动判定,无需显式开关。

指定输出目录

默认描述文件输出在当前目录,若要存到指定文件夹:

fastlane sigh -o "~/Certificates/"

-o/output_path的默认值为.(当前目录),若设置了自定义目录,会先自动创建目录,再移动生成结果(参见 sigh/lib/sigh/manager.rb#L18-L24)。

批量下载全部描述文件

需要把账号下所有描述文件都拉下来做备份或迁移时:

fastlane sigh download_all

可选的--download_xcode_profiles标志用于把 Xcode 托管(Xcode managed)的描述文件也一并下载:

fastlane sigh download_all --download_xcode_profiles

不过注意:在仓库源码 download_all.rb 中,--download_xcode_profiles已被标注为 deprecated——因为App Store Connect API 本身不支持查询 Xcode 托管的描述文件,仅当使用 Apple ID 账号密码方式登录时才可能拿到相关数据。该命令内部会按平台枚举 App Store / InHouse / AdHoc / Development 等全部类型并逐个拉取,跳过其中已过期或无效(invalid)的描述文件(sigh/lib/sigh/download_all.rb#L29-L88)。

查看全部参数

运行下述命令即可查看完整参数、环境变量与示例:

fastlane action sigh

它相当于「本地文档查阅器」,会把动作的available_options(最终来自 sigh/lib/sigh/options.rb)以及 Fastfile 示例一次性打印出来。

进阶用法详解

文档中的「Advanced」部分给出几个高频进阶开关,下面逐一说明(含源码中的默认值与作用):

跳过本地安装

默认情况下,sigh下载描述文件后会自动安装到本机(写入 Xcode 的描述文件目录,便于后续真机调试/归档直接使用)。如果你只想拿到文件而不安装:

fastlane sigh --skip_install

对应配置项:skip_install(默认false,环境变量SIGH_SKIP_INSTALL),安装这一步由Manager.install_profile调用FastlaneCore::ProvisioningProfile.install完成(sigh/lib/sigh/manager.rb#L26-L45)。

自定义保存文件名

-q指定输出文件名(必须以.mobileprovision结尾,源码中有校验):

fastlane sigh -a com.krausefx.app -u username -q "myProfile.mobileprovision"

若未指定,文件名会由Manager.start依据生成路径自动推导(sigh/lib/sigh/manager.rb#L12-L19)。

跳过证书校验

默认sigh在挑选/复用描述文件时,会校验其中的签名证书是否已安装到本机(使用FastlaneCore::CertChecker.installed?,见 runner.rb 中的校验循环)。如果某些场景下不想要这层校验(例如在非本机生成后统一分发):

fastlane sigh --skip_certificate_verification

一个细节:在 options.rb 中:skip_certificate_verification的默认值是!FastlaneCore::Helper.mac?,即非 macOS 环境默认自动跳过证书校验(因为证书是否在本机通常只在 Mac 上才有意义)。

强制续期以获取最长生命周期

--force会让sigh无视描述文件当前状态,一律重建,从而拿到最大生命周期的新描述文件;对于 Ad Hoc 类型,--force还会自动把账号下所有可用测试设备加进新描述文件:

fastlane sigh --force

源码中force的含义正是「Renew provisioning profiles regardless of its state - to automatically add all devices for ad hoc profiles」(sigh/lib/sigh/options.rb#L48-L53)。在 runner.rb 中,--force会先profile.delete!删除旧文件再调用create_profile!重建。

指定使用哪个签名证书

默认策略是:Development 描述文件包含全部可用证书,其余类型只使用「第一个」证书。需要指定证书时,既可以设环境变量SIGH_CERTIFICATE,也可以通过-c直接传证书的拥有者名称或证书(过期日期):

fastlane sigh -c "SunApps GmbH"

对应配置项:cert_owner_name(环境变量SIGH_CERTIFICATE)。此外还有更精确的-i/:cert_id(环境变量SIGH_CERTIFICATE_ID),传的是证书在开发者后台的 ID(形如78ADL6LVAA)。在 certificates_to_use 方法 中,这两个过滤条件会同时作用于证书列表,若多个证书都命中且非 Development 类型,则打印提示并选用第一个;若一个都匹配不到,会建议你先用matchcert生成证书(代码会输出提示并报错)。

其他实用的隐藏开关(来自选项源码)

下表按 sigh/lib/sigh/options.rb 整理了完整选项与环境变量的对应关系,供你在 CI 中直接以环境变量方式注入:

参数(key)短选项环境变量默认值说明
adhocSIGH_AD_HOCfalse生成 AdHoc 描述文件(与 development/developer_id 互斥)
developmentSIGH_DEVELOPMENTfalse生成 Development 描述文件
developer_idSIGH_DEVELOPER_IDfalse生成 Developer ID 描述文件
skip_installSIGH_SKIP_INSTALLfalse下载后不自动安装到本机
force-fSIGH_FORCEfalse无论状态一律重建(获取最大生命周期、自动包含全部设备)
app_identifier-aSIGH_APP_IDENTIFIER取 AppfileApp 的 Bundle Identifier
username-uSIGH_USERNAME取 AppfileApple ID 账号
team_id-bSIGH_TEAM_ID取 Appfile多 Team 时指定 Developer Portal Team ID
team_name-lSIGH_TEAM_NAME取 Appfile多 Team 时指定 Team 名称
provisioning_name-nSIGH_PROVISIONING_PROFILE_NAME开发者后台使用的描述文件名称
ignore_profiles_with_different_nameSIGH_IGNORE_PROFILES_WITH_DIFFERENT_NAMEfalse-n组合,仅下载完全同名描述文件
output_path-oSIGH_OUTPUT_PATH.描述文件保存目录
cert_id-iSIGH_CERTIFICATE_ID使用的签名证书 ID
cert_owner_name-cSIGH_CERTIFICATE使用的签名证书名称
filename-qSIGH_PROFILE_FILE_NAME输出文件名(必须 .mobileprovision 结尾)
skip_fetch_profiles-wSIGH_SKIP_FETCH_PROFILESfalse跳过既有描述文件的校验查找(账号下描述文件极多时提速)
include_all_certificatesSIGH_INCLUDE_ALL_CERTIFICATESfalse描述文件包含所有匹配证书(仅对 development 生效)
skip_certificate_verification-zSIGH_SKIP_CERTIFICATE_VERIFICATION非 Mac 为 true跳过证书本机安装校验
platform-pSIGH_PLATFORMios平台:ios/tvos/macos/catalyst
readonlySIGH_READONLYfalse只拉取既有描述文件、绝不新建(与 force 互斥)
fail_on_name_takenSIGH_FAIL_ON_NAME_TAKENfalse当待创建名称在后台已存在时报错退出
api_key_pathSIGH_API_KEY_PATHApp Store Connect API Key 的 JSON 文件路径
api_keySIGH_API_KEYApp Store Connect API Key 的 Hash 配置(敏感)

需要特别强调的是平台维度:虽然动作get_provisioning_profile声明支持[:ios, :mac](get_provisioning_profile.rb#L88-L90),但底层sighplatform选项实际覆盖iostvosmacoscatalyst四种。以 macOS 为例,development会生成 Mac App Development、developer_id会生成MAC_APP_DIRECT(Developer ID),而 InHouse 在 API Key 方式下不可用(详见 module.rb 的 profile_type_for_config)。

与 fastlane(Fastfile)配合:cert + sigh 黄金组合

sigh的威力在于嵌进Fastfile与其他动作联动。文档给出的经典 beta 分发场景是先用cert保证本机装有正确的签名证书,再用sigh强制重建描述文件:

lane :beta do cert sigh(force: true) end

force: true保证每次运行都重新生成描述文件,这样sigh拿到的始终是「与本机已安装证书精确匹配」的那一个——cert负责生成/安装证书,sigh负责绑定该证书生成描述文件,二者天然衔接。从 get_provisioning_profile.rb 的实现 可以看到动作实际做了这些事:

  1. 若传了api_key_path之外的 API Key(会从 lane 上下文APP_STORE_CONNECT_API_KEY继承),优先使用 API Key 认证(#L17-L20);
  2. 把当前已完成配置的对象赋给Sigh.config,调用Sigh::Manager.start(#L22-L24);
  3. 将结果的绝对路径写进 lane 上下文SIGH_PROFILE_PATH、追加到SIGH_PROFILE_PATHS列表(#L26-L28);
  4. 读取环境变量SIGH_UUID/SIGH_NAME同步到 lane 上下文(#L30-L33);
  5. 依据开关计算并输出描述文件类型app-store/ad-hoc/development/developer-id/enterprise,存入SIGH_PROFILE_TYPE(#L40-L50);
  6. 最终返回该描述文件的 UUID(String)。

因此后续动作(比如build_app/gym)可以读取这些输出值。动作对外公布的输出汇总如下(源码 output 数组):

Lane 上下文键说明
SIGH_PROFILE_PATH本次导出描述文件的绝对路径
SIGH_PROFILE_PATHS多次调用累计的描述文件路径列表
SIGH_UUID本次获取/生成描述文件的 UUID
SIGH_NAME描述文件的名称
SIGH_PROFILE_TYPE描述文件类型(app-store/ad-hoc/development/enterprise/developer-id),可作为build_appexport_method默认值

Fastfile 中的等效写法(注意sighget_provisioning_profile的动作别名,源码 example_code 给出了三种等价形式):

lane :beta do cert get_provisioning_profile(adhoc: true, force: true) # 或 sigh( adhoc: true, force: true, filename: "myFile.mobileprovision" ) end

一键修复:repair

repair子命令会自动扫描并修复你全部「已过期或无效」的既有描述文件

fastlane sigh repair

其入口在 commands_generator.rb 的 repair 子命令,实际逻辑由 sigh/lib/sigh/repair.rb 中的Sigh::Repair.new.repair_all完成。适合定期在 CI 或发版前跑一遍,保证签名物料始终可用。

重新签名:resign

当你手上已经有一个.ipa,却想换成另一套签名(比如换证书、换描述文件后再分发),用sigh resign

fastlane sigh resign

如果.ipa文件和.mobileprovision文件恰好都在当前目录,sigh自动帮你找到它们(分别按修改时间取最新的*.ipa*.mobileprovision,见 resign.rb#L111-L121)。也可以显式传入全部参数:

fastlane sigh resign ./path/app.ipa --signing_identity "iPhone Distribution: Felix Krause" -p "my.mobileprovision"

resign子命令的完整 CLI 参数(commands_generator.rb 的 resign 定义)包括:

参数说明
-i/--signing_identity使用的签名身份(须与描述文件中定义匹配,支持名称或自动映射到 SHA-1)
-p/--provisioning_profile描述文件路径;可重复传入多次,若 App 含扩展/嵌套 App,可用BUNDLE_ID=PATH前缀指定各自使用的描述文件
-d/--display_name修改 App 显示名称
-e/--entitlements指定使用的 entitlements 文件路径
-x/--version_number强制二进制及所有嵌套二进制使用该版本号(同时改CFBundleShortVersionStringCFBundleVersion
--short_version仅强制CFBundleShortVersionString
--bundle_version仅强制CFBundleVersion
--use_app_entitlements抽取 App bundle 自身签名 entitlements,并与新描述文件中的 entitlements 合并
-g/--new_bundle_id修改应用 Bundle ID(CFBundleIdentifier
--keychain_path指定codesign使用的钥匙串路径
--page_size设置codesign --pagesize(2 的幂)

需要留意一个易混淆点:在resign上下文中-n/provisioning_name不适用,此时请改用-p指定描述文件路径(resign.rb 会打印相应提醒,见 resign.rb#L104-L106)。从实现看,整个重签过程最终会拼装命令调用仓库内置的 sigh/lib/assets/resign.sh 脚本(resign.rb#L58-L88),底层依赖/usr/bin/codesign,并会先通过security find-identity -v -p codesigning枚举本机可用签名身份。

本地描述文件管理:manage

manage子命令用于盘点本机已安装的预置描述文件,并支持清理:

列出本机全部已安装描述文件:

fastlane sigh manage

输出会按Valid(有效)/ Expiring within 30 days(30 天内到期,黄色)/ Expired(已过期,红色)三档分组,并给出汇总统计(local_manage.rb#L51-L92)。

删除所有已过期的描述文件:

fastlane sigh manage -e

用正则表达式批量删除(例如清除 Xcode 自动生成的iOS Team Provisioning Profile系列,注意反斜杠转义空格):

fastlane sigh manage -p "iOS\ ?Team Provisioning Profile:"

删除前会逐条列出命中项并请求确认;在 CI 服务器上必须附加-f--force)跳过确认交互,否则会直接报错(local_manage.rb#L102-L127)。manage读取的是 fastlane_core 认定的 Xcode 描述文件安装目录下的*.mobileprovision,逐个用security cms -D -i解出 plist 后按名称排序(local_manage.rb#L129-L145)。

认证与原理:它背后是怎么工作的?

sigh的工作本质是通过 spaceship 访问 Apple 开发者后台 / App Store Connect API,去下载、续期或生成.mobileprovision文件。这一设计在仓库内完整可见:

  • API 层:所有对 Apple 服务的通信都由仓库中的 spaceship 完成;
  • 认证方式:支持两套——① App Store ConnectAPI Keyapi_key/api_key_path,生成 JWT token);② 传统Apple ID 账号密码username,登录 Developer Portal)。Runner 启动时会先尝试 API Key,否则强制询问用户名并调用Spaceship::ConnectAPI.login(runner.rb#L20-L35);
  • 主流程(sigh/lib/sigh/runner.rb#L16-L66):
    1. 按平台与配置(adhoc/development/developer_id/企业账号 in_house)解析出目标描述文件类型(映射逻辑见 module.rb 的 profile_type_for_config);
    2. 拉取并过滤候选描述文件:要求bundle_id匹配、profile 有效(或开启force)、证书已安装本机(除非跳过校验)等(fetch_profiles);
    3. 若没有可用描述文件且未开readonly,先确认 App Identifier 存在(ensure_app_exists!,不存在时会提示你改用produce创建 App ID),再按需自动选择/创建证书与新描述文件(create_profile!);
    4. 下载得到 profile 内容(Base64 解码后写入临时目录),随后由Manager移动到output_path并按需安装(download_profile + manager.rb)。

一个值得注意的行为约束:Development 类型描述文件可包含多个证书,而其他类型只取「第一个」匹配证书(runner.rb 末尾的certificates_to_use逻辑,runner.rb#L300-L301);Development/AdHoc 类型才会拉取设备列表并写入设备(devices_to_use)。

密码与凭据存在哪?

sigh使用 fastlane 的CredentialsManager来管理 Apple ID 凭据——它会将账号密码安全地写入macOS 系统钥匙串(Keychain),并在后续运行中自动复用,不会在命令行或脚本里明文留存。详见仓库中的 credentials_manager 模块。

使用建议与常见问题

优先推荐match管理签名物料

尽管sigh功能完整,文档和源码注释都明确建议:常规情况下用match配合 codesigning.guide 的推荐流程来集中生成与维护签名材料(把证书与描述文件加密后存入 git 仓库、团队共享),仅在需要完全掌控细节时才直接使用sigh。相关入门材料见 fastlane/docs/Codesigning/GettingStarted.md 与 match 工具主页。

用 ProvisionQL 在 Finder 中预览描述文件

安装 ProvisionQL 插件后,.mobileprovision文件可以直接在 Finder 的 Quick Look 中查看其包含的 App ID、设备、证书、过期时间等关键信息,对排查「装错描述文件」类问题非常高效。你可将描述文件拖到该目录手工管理,而sigh生成的文件默认已自动安装到系统描述文件目录。

提示「App Identifier couldn't be found」

当开发者后台尚不存在对应的 App Identifier 时,sigh会打印类似下面这样的建议,指引你先创建 App ID(源码 ensure_app_exists! / print_produce_command):

fastlane produce -u <username> -a <bundle_identifier> --skip_itc

produce正是同一仓库中负责在 Developer Portal(以及可选地 App Store Connect)上创建 App 的工具,详见 produce 主页。

会不会动我 Xcode 托管的描述文件?

不会。sigh从不触碰 Xcode 自动创建/托管的描述文件,它只管理自己生成的那一套(默认还会主动避开 Xcode 管理的命名空间)。这意味着你完全可以放心地让 Xcode 与sigh/match两套体系并存。基于此前提,若你的工程使用了 Xcode 的自动签名而手动生成的描述文件又恰好同名,需要留意 Xcode 版本可能对描述文件目录的读取策略存在差异——这正是文档建议「同一套体系用到底」的原因。

小结

sighget_provisioning_profile)把描述文件的「查、建、续、修、批量下载、本地盘点、重签 ipa」全部收敛为一条命令,是 fastlane 签名流水线中承上启下的关键一环:向下通过 spaceship 直连 Apple 服务,向上与cert(提供证书)、match(统一托管)、produce(创建 App ID)、gym(打包,可读取SIGH_PROFILE_TYPE作为导出方式默认值)无缝衔接。若你准备摆脱在开发者后台手动维护.mobileprovision的重复劳动,把描述文件管理纳入自动化,本文覆盖的命令行参数、环境变量映射与源码级行为说明即可作为直接可用的参考手册。

相关阅读:动作文档原文见 fastlane/lib/fastlane/actions/docs/get_provisioning_profile.md,动作封装见 fastlane/lib/fastlane/actions/get_provisioning_profile.rb,sigh全部实现位于 sigh/lib/sigh,对应测试位于 sigh/spec(含 resign_spec.rb、manager_spec.rb 等,可进一步佐证上述行为)。

【免费下载链接】fastlane🚀 The easiest way to automate building and releasing your iOS and Android apps项目地址: https://gitcode.com/GitHub_Trending/fa/fastlane

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 9:50:47

数字员工与SaaW落地全解:从概念到商业价值的实践指南

最近朋友圈里最热闹的To B话题&#xff0c;绕不开“数字员工”和“SaaW”这两个词。我拿到了一份《全球真实数字员工与 SaaW 商业全景报告 2026-1》&#xff0c;翻了几遍之后又对照自己过去在几家制造、零售企业里落地数字员工项目的经验&#xff0c;发现很多内容不能只看结论&…

作者头像 李华