1 问题
在Jenkins中搭建iOS的持续集成环境时,遇到的一个问题就是证书和配置文件的管理问题。
一般的解决方法是,通过 Keychains and Provisioning Profiles Management 插件来进行配置。如下图所示:
但由于我们的项目中存在多个应用,且由于增加调试设备等,需要比较频繁地更新Provisioning File 配置文件。在这种情况下,每次有证书更新,都需要手动去Jenkins进行更新,操作不便。于是就想到,是否能用脚本的方式来安装证书和配置文件,且在每次编译时,都去指定路径取最新的证书和配置文件,达到减少维护成本和出错的目的。
2 解决方法
2.1 Certificate 证书的安装
证书可通过 security import
命令来进行安装
security unlock-keychain -p <my keychain password>
security import Certificate.p12 -k ~/Library/Keychains/login.keychain -P <certficate password> -T /usr/bin/codesign
security unlock-keychain
命令是为了先解锁 keychain,避免安装证书时遇到没有权限的问题。
2.2 Provisioning File 的安装
Provisioning File 没有安装的命令,不过通过观察可知,当我们双击安装Provisioning File时,其实做了两件事:
1)将文件重新命名为其 UUID。其 UUID 可通过文本编辑器打开后搜索得到,如下图:
2)将文件移动到下面文件夹下:
~/Library/MobileDevice/Provisioning Profiles
故想要实现Provisioning File 的安装,只需要通过脚本的方式来实现这两步即可。
3 脚本实现
我是通过Python 脚本的方式来实现的上述功能。具体代码如下:
3.1 certificate 的安装
def install_certificate(file_path):
cmd_str = "security unlock-keychain -p {2} {1};security import {0} -k {1} -P {3} -T /usr/bin/codesign".format(file_path, g_keychain_path, g_mac_root_password_keychain, g_certificate_password)
print(cmd_str)
status, output = commands.getstatusoutput(cmd_str)
if status == 0:
return True
print(output)
return False
3.2 Provisioning File 的安装
def get_uuid_for_profile(file_path):
get_uuid_cmd = "grep UUID -A1 -a %s | grep -io \"[-A-F0-9]\\{36\\}\"" % file_path
status, uuid = commands.getstatusoutput(get_uuid_cmd)
if status != 0:
return None
return uuid
def install_provisioning_file(file_path):
uuid = get_uuid_for_profile(file_path)
ext_str = os.path.splitext(file_path)[1]
dst_file_name = uuid + "." + ext_str
dst_path = os.path.join(g_profile_folder_path, dst_file_name)
shutil.copy(file_path, dst_path)
return True
4 总结
在 Jenkins中执行操作时,很多时候会遇到权限的问题,这里的两个脚本实现不会有类似的问题,可以直接在 Jenkins 中配置执行。
使用脚本来进行证书和配置文件的管理,赋予我们更大的灵活性,可以根据自己的需要来实现不同的功能。
我当前的实现是,根据产品名称来去获取到最新的证书和配置文件并安装,然后通过脚本自动更新工程配置和ExportOption.plist 文件中相应的值,达到每次编译时自动使用最新证书和配置文件的功能。
希望对大家有所帮助。
参考:
How to install developer certificate/private key and provisioning profile for iOS development via command line?
Can an Xcode .mobileprovision file be 'installed' from the command line?