jenkins+fastlane+ios自动化打包实战
当项目达到一定规模后,为了便于管理,我们都会引入自动化构建。本篇主要是讲述如果通过jenkins和fastlane实现iOS的打包。
关于jenkins的搭建就不多说了,大家可以按照网上的文章去配置,基本都是傻瓜式一键安装。
本文将要解决的问题是如何在jenkins搭建iOS的自动编译job。
构建iOS的包只能在Mac机器上进行,如果Jenkins搭建在Linux或者非Mac机器上,需要在Jenkins中配置slave节点连接到Mac电脑。
1. 准备工作
Q:为何是通过fastlane来构建iOS,而不是通过Jenkins的Xcode插件来构建呢? A:Xcode插件方式不仅配置麻烦,而且配置完成后还需要大量的调试工作才能正确编译。而fastlane只需要配置一次,简单方便。
既然是通过fastlane来构建,那么我们首先得需要配置好fastlane相关的东西。
1.1 安装fastlane
在Mac编译机上需要配置好fastlane
打包iOS我们需要保证xcode命令行已经正确安装
xcode-select --install //命令行输入,如果未安装会弹出对话框提示安装,否则会提示已经安装
可以通过两种方式来安装fastlane 方式一:
[sudo] gem install fastlane -NV
方式二:
brew cask install fastlane
1.2 项目中配置fastlane
给我们需要自动化编译的iOS工程配置fastlane
假如我们现在有一个BlocklySample
的工程,我们需要在项目根目录下执行命令行
fastlane init
会有如下图这样的提示,需要我们选择哪种任务,这里我们可以选2
或者3
。选择这两个选择后会提示让你输入iOS开发者的账号密码,这样会自动给你生成团队信息、bid和基本编译脚本等等。
执行完成后在项目根目录下会自动新建一个fastlane的目录
修改fastlane目录下的Fastfile文件
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
desc "Push a new release build to the App Store"
lane :release_appstore do
increment_build_number(xcodeproj: "xxx.xcodeproj")
update_project_provisioning(
# 之前有sigh下载的描述文件存储路径
profile:"fastlane/provision/xxx.mobileprovision",
# 打包配置,Debug,Release
build_configuration:"Release"
)
automatic_code_signing(
# 工程文件所在路径
path:"xxx.xcodeproj",
# 是否使用自动签名,这里如果是打包的话应该一般都为false吧,默认也是false
use_automatic_signing:false,
# 这个就不用说了,需要修改的targets
targets:"xxx",
# 用哪种方式打包“iPhone Develop”还是“iPhone Distribution”
code_sign_identity:"iPhone Distribution",
# 描述文件名称, 也就是使用哪个描述文件打包
profile_name:"xxx"
)
scheme_name = 'xxx'
configuration = 'AppStore'
version = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleShortVersionString")
build = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleVersion")
output_directory = File.expand_path("..", Dir.pwd) + File::Separator + 'build'
output_name = "#{scheme_name}_#{configuration}_#{version}_#{build}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
build_app(workspace: "xxx.xcworkspace", scheme: "xxx", export_method: "app-store", output_directory: output_directory,
output_name: output_name)
upload_to_app_store
end
desc "Push a new release build to the Testflight"
lane :release_testflight do
update_project_provisioning(
# 之前有sigh下载的描述文件存储路径
profile:"fastlane/provision/xxx.mobileprovision",
# 打包配置,Debug,Release
build_configuration:"Release"
)
automatic_code_signing(
# 工程文件所在路径
path:"xxx.xcodeproj",
# 是否使用自动签名,这里如果是打包的话应该一般都为false吧,默认也是false
use_automatic_signing:false,
# 这个就不用说了,需要修改的targets
targets:"xxx",
# 用哪种方式打包“iPhone Develop”还是“iPhone Distribution”
code_sign_identity:"iPhone Distribution",
# 描述文件名称, 也就是使用哪个描述文件打包
profile_name:"xxx"
)
scheme_name = 'xxx'
configuration = 'AppStore'
version = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleShortVersionString")
build = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleVersion")
output_directory = File.expand_path("..", Dir.pwd) + File::Separator + 'build'
output_name = "#{scheme_name}_#{configuration}_#{version}_#{build}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
build_app(workspace: "xxx.xcworkspace", scheme: "xxx", export_method: "app-store", output_directory: output_directory,
output_name: output_name)
upload_to_testflight
end
desc "Push a new release build to the Ad Hoc"
lane :release_adhoc do |option|
# cocoapods
#根据传入参数version设置app的版本号
# increment_version_number(version_number: option[:version])
#自动增加build号
#increment_build_number
update_project_provisioning(
# 之前有sigh下载的描述文件存储路径
profile:"fastlane/provision/xxx.mobileprovision",
# 打包配置,Debug,Release
build_configuration:"Release"
)
automatic_code_signing(
# 工程文件所在路径
path:"xxx.xcodeproj",
# 是否使用自动签名,这里如果是打包的话应该一般都为false吧,默认也是false
use_automatic_signing:false,
# 打包的team ID, 也就是打包使用的证书中的team ID,这个如果不知道是什么的话可以在xCode中设置好签名用的描述文件后到xcodeproj下的pbxproj文件中搜索“DEVELOPMENT_TEAM”,它的值就是了
team_id:"RRRRR5555",
# 这个就不用说了,需要修改的targets
targets:"xxx",
# 用哪种方式打包“iPhone Develop”还是“iPhone Distribution”
code_sign_identity:"iPhone Distribution",
# 描述文件名称, 也就是使用哪个描述文件打包
profile_name:"xxx"
)
#证书签名
# sigh
#编译打包
scheme_name = 'xxx'
configuration = 'Release'
version = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleShortVersionString")
build = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleVersion")
output_directory = File.expand_path("..", Dir.pwd) + File::Separator + 'build'
output_name = "#{scheme_name}_#{configuration}_#{version}_#{build}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
gym(
scheme: scheme_name,
clean: true,
silent:true,
export_method:'ad-hoc',
export_options: {
provisioningProfiles: {
#前面的是bundle id,后面的是对应用到的mobileprovision,只需要名字,不需要后缀
"me.ithome.xxx" => "xxx"
}},
configuration: configuration,
output_directory: output_directory,
output_name: output_name,
# 签名证书的名称,去钥匙串-登录-证书里面复制
codesigning_identity:'iPhone Distribution: xxx (Rxxx47)',
export_xcargs: '-allowProvisioningUpdates')
# 上传到蒲公英,需要安装pgyer插件
#pgyer(api_key: "aaaa", user_key: "bbbb")
end
end
- 上述脚本中有部分xxx之类的东西,需要自行替换成自己项目的。
- 所有脚本中用到的xxx.mobileprovision都需要双击安装一次,否者会提示找不到。
- 需要安装好p12证书文件。
修改完成后我们就有了三个命令,用来分别打包上传到appstore、testflight和蒲公英。
fastlane release_appstore
fastlane release_testflight
fastlane release_adhoc
我们可以运行fastlane release_adhoc
来打个adhoc包测试下是否全部配置成功。
如果一些都配置无误,运行后应该会提示
ipa文件已经打包出来了。
此时环境配置已经完成。接下来我们来配置如何通过Jenkins来实现自动化打包。
2. 新建一个自由风格的软件项目
因为需要分别打包appstore、testflight和adhoc,所以我们需要构建参数
也许还需要配置下git代码分支
如果是通过slave连接的Mac,还需要配置下(jenkins架设在Mac上的请无视)
配置源码地址
顺便配置个job名吧
配置构建命令
最后,文件归档
如果上传到了蒲公英,还能做一些获取二维码的操作,请自行研究。
好了,配置完成后的构建界面如下:
收工。
也许你会遇到执行fastlane打包命令发现打包失败的问题,请仔细阅读失败的错误提示,一般都能找出问题所在。