Automate certificate and profile management with fastlane match

When we conduct team development, the management of certificates and description files cannot be avoided. There are two conventional methods: automatic management and manual management.

1. Conventional management methods

1.1 Automatically manage signatures

Need to Targets->Signing & Capabilitiescheck . In this way, all the work including the creation of AppId, certificate, and description file (Provisioning Profile) is handled by Xcode, which is very convenient.

Automatically manage signing.png

This method is very friendly to individual developers, but has major disadvantages for team development, as follows.

1.1.1 Each development member has a separate certificate and description file, which will lead to a large number of duplicate files, which is very confusing to manage

as the picture shows:16577654793275.png

1.1.2 The creation of certificates is limited, which may prevent others from creating certificates.

Screenshot 2022-07-14 10.26.37 am.png

1.1.3 Every time a new device is added or a certificate expires, the latest set of profiles must be manually updated and downloaded

For example, after adding a new device, if the device is not checked in the description file configuration, this device cannot install our application, so every time you need to make sure that the Select All of the description file is checked.

16577663758021.png

1.2 Manually manage signatures

First, a team member is required to create certificates and configuration files for the development environment and the production environment in the Apple Developer background , and then download and install these files locally. When other people are involved in development, this person is required to export the relevant files to others.

16577730394088.png

Then you need to uncheck it on Xcode Automatically manage signing, and set the corresponding certificate and provisioning profile at the same time.

Screenshot 2022-07-14 2.16.50 pm.png

The advantage of this method is that all developers share a certificate and description file, and the disadvantage is also very obvious: every time the certificate expires or a new device is added, it needs to be updated manually, and then redistributed to others, which is very troublesome to operate. .

So, is there such a solution: access these certificates and configuration files in a public place, and automate the whole process? This is the match tool we are going to talk about today .

2. 使用 fastlane match 自动化管理证书和配置文件

matchfastlane 工具套装其中的一个工具,它是 codesigning.guide 概念的实现。 它提供了一种全新的管理证书的方式,使团队所有成员共享一份代码签名,以减免不必要的证书创建、配置文件失效等问题。

2.1 使用 match 有什么优势?

  • 所有的团队成员共享同一份证书和配置文件,减少了管理和维护成本
  • 简化请求证书,生成描述文件,注册设备等一系列繁杂工作
  • 能自动识别已过期的证书和失效的描述文件,对这些文件进行重置
  • 对新开发者极其友好,match使用git管理所有的证书和描述文件,所以只要新人拥有git的访问权限,安装了fastlane,就能快速同步现有的证书配置,远离证书配置的大坑

2.2 如何使用 match ?

下面我将详细介绍 match 的使用流程。

2.2.1 准备一个私有的 git仓库

创建一个私有git仓库来存储证书和描述文件。建议在git账号中配置好SSH Key,这样就可以省去身份校验这一步。至于如何配置SSH Key,请参考:使用 SSH 连接到 GitHub

另外,当有多个App时,建议一个git分支对应一个App,这样,我们所有App的证书都在一个仓库里面,便于管理。

2.2.2 初始化 match

在终端定位到项目目录,注意先看项目目录下是否存在fastlane目录,如果没有的话,先执行 fastlane init 命令来初始化fastlane服务(后面会用到)。然后再执行 fastlane match init 命令,首先会提示让你选择存储方式,我们选git,然后再输入git仓库地址,最后会生成一个 Matchfile 的配置文件。接下来,我们修改一下 Matchfile。

git_url("[email protected]:YourUserName/certificates.git")  # git仓库地址

storage_mode("git") # 存储方式
git_branch("app1")  # git分支名称,暂时以app名称作为分支名

# 默认的Profile类型, 可以为: appstore, adhoc, enterprise or development
type("development") 

# bundleId,可以填多个bundleId,如App内包含 extension
app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
ENV["MATCH_PASSWORD"] = "your match password" # 导出和打开 .p12文件的密码

# username("user@fastlane.tools") # Your Apple Developer Portal username

# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options

# The docs are available on https://docs.fastlane.tools/actions/match

配置完 Matchfile 后,大部分教程都是让你通过以下三条命令来同步证书和配置文件。

fastlane match development
fastlane match adhoc
fastlane match appstore

但是这种方式使用起来非常不方便,特别是用于自动化构建脚本,因为每次都要输入AppleId和密码;有的团队的做法是在Matchfile配置一个公用的AppleId,这样就不用每次输入账户和密码。

git_url("[email protected]:YourUserName/certificates.git")  # git仓库地址
# 省略其他内容...

username("APPLE_ID") # 公用的AppleId
ENV["FASTLANE_PASSWORD"] = "AppleId密码"  

但是,还会遇到另外一个问题,需要进行双重验证,要求输入6位验证码,所以我个人更推荐用 App Store Connect API 的方式,下面我将对这种方式做详细介绍。

Screenshot 2022-07-18 10.45.28 am.png

2.2.3 创建 App Store Connect API 秘钥

App Store Connect API 是官方提供的一套 REST API,可让您在 App Store Connect 中执行的操作自动化。它主要提供了以下功能(包含了证书和描述文件的管理):

16578505249608.png

为什么要使用 App Store Connect API?

因为如果按照常规的方式的话,需要先用账号密码登录,登录过程中还要做双重验证,非常的不方便。 你可能会说 fastlane 不是还有一个强大的 spaceship 工具么,但是它还是无法绕过双重验证这个流程。具体可以看下这个文章:Spaceship VS App Store Connect API,这里就不做详细介绍了。

而 App Store Connect API 是通过 JSON Web Tokens (JWT) 进行授权,无需登录开发者账号,也无需做双重验证,非常适合在脚本内做自动化操作。

fastlane 内部也集成了 App Store Connect API,它那边也是推荐使用 API key的方式进行身份验证,具体请参考文档:Using App Store Connect API

创建 App Store Connect API 密钥

账户持有人身份的AppleID登录 AppStoreConnect 后台,选择 用户和访问->秘钥,点击添加按钮来生成API秘钥。

16578593228349.png

然后下载API秘钥(一个.p8文件),保存到项目的fastlane目录。注意:私钥只能下载一次,永远不会过期,保管好,如果丢失了,去App Store Connect后台撤销密钥,否则别人拿到也可以用。

2.2.4 创建自动化脚本

为了更加方便使用,我们通过 fastlane 来配置几个常用的命令,将以下内容添加到你的 fastlane目录下的 Fastfile 文件中:

# 定义一个全局变量api_key,下面都会要用到这个 api_key
# key_id 和 issuer_id 都可以在 AppStoreConnect后台 -> 用户和访问 -> 秘钥 这里找到
api_key = app_store_connect_api_key(
    key_id: "D383SF739",
    issuer_id: "6053b7fe-68a8-4acb-89be-165aa6465141",
    key_filepath: "./AuthKey_D383SF739.p8", # 上面下载的p8文件路径
    duration: 1200, # optional (maximum 1200)
    in_house: false # optional but may be required if using match/sigh
)
  
desc "下载所有需要的证书和描述文件到本地,不会重新创建证书和描述文件(只读方式)"
lane :match_all do
    match(api_key: api_key, type: "development", readonly: true)
    match(api_key: api_key, type: "adhoc", readonly: true)
    match(api_key: api_key, type: "appstore", readonly: true)
end

desc "同步证书,如果证书过期或新增了设备,会重新创建证书和描述文件"
desc "该方法仅限管理员使用,其他开发成员只需要使用 match_all 方法即可"
  lane :force_match do
    match(api_key: api_key, type: "development", force_for_new_devices: true)
    match(api_key: api_key, type: "adhoc", force_for_new_devices: true)
    match(api_key: api_key, type: "appstore")
end

desc "注册设备,并更新描述文件"
lane :sync_devices do
    # devices.txt模板:
    # http://devimages.apple.com/downloads/devices/Multiple-Upload-Samples.zip
    register_devices(api_key: api_key, devices_file: "./devices.txt")
    match(api_key: api_key, type: "development", force_for_new_devices: true)
    match(api_key: api_key, type: "adhoc", force_for_new_devices: true)
end

# 构建测试包
lane :beta do
  # 先同步adhoc证书和描述文件
  match(api_key: api_key, type: "adhoc", readonly: true)
  # 省略其他步骤...
  build_app(scheme: "MyApp",
            workspace: "Example.xcworkspace",
            include_bitcode: true)
end 

lane :release do
  # 先同步appstore证书和描述文件
  match(api_key: api_key, type: "appstore", readonly: true)
  # 省略其他步骤...
  build_app(scheme: "MyApp")
  # 上传应用到AppStore
  upload_to_app_store(
        api_key: api_key,
        force: true, # Skip HTMl report verification
        skip_screenshots: true,
        skip_metadata: true,
        submit_for_review: false,
  )
end

通过上面这个模板我定义了以下几个常用的命令:

  1. fastlane match_all:下载所有需要的证书和描述文件到本地,不会重新创建证书和描述文件(只读方式)
  2. fastlane force_match:强制同步证书和描述文件,如果证书过期或新增了设备,会重新创建证书和描述文件
  3. sync_devices:注册设备,会同步更新描述文件,需要先在 devices.txt 文件录入新增的设备UDID。
  4. fastlane beta:构建测试包,先通过 match 确保adhoc证书和描述文件都是最新且有效的
  5. fastlane release:构建且上传到AppStore,先通过 match 确保 appstore证书和描述文件都是最新且有效的。

当我们有新同事入职,或者需要在新的电脑上配置开发证书和描述文件,我们仅仅只需要一条 fastlane match_all 命令即可。

3. 其他

3.1 如何撤销所有的证书和描述文件

很少会有这种需求,如果确实需要清空所有证书和描述文件的话,可以通过 fastlane match_nuke 工具来处理:

desc "清空所有的证书和描述文件,慎用"
lane :nuke_all do
    match_nuke(api_key: api_key, type: "development")
    match_nuke(api_key: api_key, type: "adhoc")
    match_nuke(api_key: api_key, type: "appstore")
end

注意:清空完所有的证书和描述文件后,已安装的测试包是无法使用的,谨慎使用。

3.2 如何查看设备的UDID

1. 通过Xcode来查看

先通过USB在电脑上连接iOS设备,然后在Xcode中打开菜单:Window -> Device and Simulators,上面显示的 Identifier 这一项就是我们所需要的设备UDID。

2. 通过第三方工具

如果当前无法使用Xcode来查看,如其他地区的同事,可以使用第三方工具。大部分提供应用分发的平台都支持获取UDID,如 Fir获取UDID蒲公英-快速获取iOS设备的UDID

3.3 如何判断某个测试包是否能在设备上运行

原理:描述文件里面包含了所有的支持安装的设备的UDID,所以我们只需要看描述文件里面是否包含该设备的UDID就行了。在我们构建IPA包时,里面会嵌入一个叫 embedded.mobileprovision 文件(其实就是描述文件),判断我们的设备UDID是否在包含这个文件中,就能判断是否能安装(当然这只是其中的一个条件,其他的没在本文范围内,不做过多介绍)。

但是,这个文件是无法直接打开查看的,因为它经过了特殊的编码,其实质是一个plist文件,我们可以通过以下方式来查看它:

1. 通过 security 命名解码查看

security cms -D -i embedded.mobileprovision > result.plist
open result.plist

2. 使用预览插件 ProvisionQL 查看

可以通过 brew 来安装 ProvisionQL,安装命令为: brew install --cask provisionql 。 在文件扩展名为 .ipa.xcarchive.mobileprovision 上可通过空格键来快速预览。

Quick Look for ipa & provision

4. 参考资料


我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

Guess you like

Origin juejin.im/post/7121617118100979748
Recommended