iOS使⽤fastlane实现持续集成的⽅法教程
前⾔
最近公司有打渠道包的需求,领导说使⽤fastlane来做持续集成,发了点时间研究了下,所有有了这篇⽂章
本⽂主要涉及到以下⼏个主题:
fastlane是什么和为什么使⽤fastlane
fastlane安装和设置
在项⽬中集成fastlane
是什么和为什么
fastlane是⼀款使⽤ruby实现的跨平台的持续集成⼯具,⽀持安卓和iOS平台项⽬的持续集成实践,fastlane处理提供基本的但是很强⼤的包含了:初始设置、屏幕截图、打包、上传到测试平台、部署等功能。此外还有⼤量的第三⽅插件可以使⽤,⽐如fir插件⽀持上传beta版本到fir测试平台,appicon插件⽀持⾃定义某个⼦版本的应⽤图标,还有很多不胜枚举。
因为项⽬的配置、打包、上传等⼀系列操作是耗时且没有技术含量的⼯作,所以有了fastlane可以为我们节省⼤量的没有什么价值的时间花费,以提⾼我们的⼯作效率。
fastlane安装和设置
安装
⽀持三种⽅式安装
使⽤brew安装
brew cask install fastlane
使⽤gem安装
sudo gem install fastlane -NV
下载安装包安装
,下载完了之后打开install脚本即可安装
安装完成之后命令⾏输⼊fastlane -v,可以看到fastlane的版本信息说明安装成功了,接下来可以继续设置步骤
➜ PlushGame fastlane -v
fastlane installation at path:
/Users/aron/.rvm/gems/ruby-2.3.0@global/gems/fastlane-2.62.0/bin/fastlane
-----------------------------
fastlane 2.62.0
设置
进⼊到项⽬⽬录执⾏fastlane init命令,会有⼀系列的设置,包含了登录apple账号,确认fastlane检测到的项⽬信息确认,登录iTunesConnect 和从iTunesConnect拉取项⽬已存在的信息
➜ PlushGame fastlane init
[20:37:45]: Get started using a Gemfile for fastlane ls/getting-started/ios/setup/
#use-a-gemfile
[20:37:48]: Detected iOS/Mac project in
...
# 根据提⽰输⼊项⽬的Apple ID和对应的密码,会⾃动登录到苹果开发者后台,拉取开发者账号对应的信息完成设置
[20:37:52]: Your Apple ID (e.g. fastlane@krausefx): XXXXXX@126
[20:37:55]: Verifying that app is available on the Apple Developer Portal and
[20:37:55]: Starting login with user 'XXXXXX@126'
-------------------------------------------------------------------------------------
Please provide your Apple Developer Program account credentials
The login information you enter will be stored in your macOS Keychain
You can also pass the password using the `FASTLANE_PASSWORD` environment variable
More information about it on GitHub: github/fastlane/fastlane/tree/master/credentials_manager
-------------------------------------------------------------------------------------
# 输⼊Apple ID 对应的密码
Password (for XXXXXX@126): **************
+----------------+------------------------------------------------------+
|      Detected Values      |
+----------------+------------------------------------------------------+
| Apple ID  | XXXXXX@126        |
| App Name  | PlushGame          |
| App Identifier |         |
| Workspace  | /Users/aron/PuTaoWorkSpace/project/PlushGame/PlushG |
|    | workspace          |
+----------------+------------------------------------------------------+
# 检测到的项⽬信息要求确认,按y即可
[20:38:50]: Please confirm the above values (y/n)
y
[20:39:03]: Created new file './fastlane/Appfile'. Edit it to manage your preferred app metadata information.
[20:39:03]: Loading up 'deliver', this might take a few seconds
[20:39:03]: Login to iTunes Connect (XXXXXXX@126)
[20:39:16]: Login successful
+--------------------------------------+------------------------+
|    deliver 2.62.0 Summary      |
+--------------------------------------+------------------------+
| run_precheck_before_submit  | false    |
| screenshots_path      | ./fastlane/screenshots |
| metadata_path      | ./fastlane/metadata |
| username        | XXXXXX@126 |
| app_identifier      | |
| edit_live      | false    |
| platform        | ios    |
| skip_binary_upload    | false    |
| skip_screenshots      | false    |
| skip_metadata      | false    |
| skip_app_version_update    | false    |
| force        | false    |
| submit_for_review    | false    |
| automatic_release    | false    |
| dev_portal_team_id    | JN55YSQ744    |
| overwrite_screenshots    | false    |
| precheck_default_rule_level  | warn    |
| ignore_language_directory_validation | false    |
+--------------------------------------+------------------------+
# 从ituneconnect拉取已存在的元数据,这⾥只有截屏的信息
[20:39:34]: Downloading all
[20:39:37]: Downloading existing screenshot '1_iphone58_1.X1_1.jpg' for language 'zh-Hans'
[20:39:42]: Downloading existing screenshot '2_iphone58_2.X2_1.jpg' for language 'zh-Hans'
[20:40:22]: Downloading existing screenshot '3_iphone58_3.X3_1.jpg' for language 'zh-Hans'
[20:40:49]: Downloading existing screenshot '4_iphone58_4.X5_1.jpg' for language 'zh-Hans'
....
初始化设置之后再项⽬⽂件夹下多出了⼀个fastlane⽂件夹,主要有以下的⼀些的信息
➜ fastlane tree
.
├── Appfile
├── Deliverfile
├── Fastfile
├── metadata
│├── app_icon.jpg
│├──
│└── zh-Hans
│├──
│├──
│├──
│├──
│├──
│├──
│├──
│├──
│└──
└── screenshots
├──
└── zh-Hans
├── 1_iphone58_1.X1_1.jpg
├── 1_iphone6Plus_1.1.png
├── 2_iphone58_2.X2_1.jpg
├── 2_iphone6Plus_2.2.png
├── 3_iphone58_3.X3_1.jpg
├── 3_iphone6Plus_3.3.png
├── 4_iphone58_4.X5_1.jpg
├── 4_iphone6Plus_4.4.png
└── 5_iphone6Plus_5.5.png
8 directories, 62 files
最重要的是Appfile⽂件、Fastfile⽂件和Deliverfile⽂件
Appfile⽂件保存了项⽬信息,包含项⽬使⽤的apple账号信息、项⽬的team_id信息、项⽬identifier信息app_identifier "" # The bundle identifier of your app
apple_id "XXXXXX@126" # Your Apple email address
team_id "XXXXXSQ744" # Developer Portal Team ID
Fastfile⽂件保存了apple账号信息和teamid信息,该⽂件的信息⽤于上传appStore使⽤
app_identifier "com.sanshuai.FunCatch" # The bundle identifier of your app
username "sanshuai2017@126" # your Apple ID user
Fastfile⽂件定义了⼀些列的action,包含了项⽬打包设置、项⽬打包、项⽬截图、项⽬上传测试平台、项⽬发布、项⽬打包完成后期的⼀些操作
初始的Fastfile⼤致如下,可以看到 lane :release 包含了
snapshot action⽤于截屏
gym action⽤于打包
deliver action⽤于上传到App Store
frameit action⽤于给截屏添加边框
after_all 块中的slack action 则是负责打包成功之后发送信息到slack
fastlane_version "2.62.0"
default_platform :ios
platform :ios do
desc "Deploy a new version to the App Store"
lane :release do
# match(type: "appstore")
# snapshot
gym(scheme: "PlushGame") # Build your app - more options available
deliver(force: true)
# frameit
end
# You can define as many lanes as you want
after_all do |lane|
# This block is called, only if the executed lane was successful
# slack(
# message: "Successfully deployed new App Update."
# )
end
end
接下来是为我们⾃⼰的项⽬编写符合业务需求的Fastfile了
fastlane项⽬集成
fastlane 详细介绍
该部分会详细的介绍fastlane中的块操作和lane的⽤途,以及fastlane中预定义的常⽤的action
fastlane 中的块和lane
fastlane 包含了预定义块有:
before_all 块⽤于项⽬打包之前的操作,⽐如可以使⽤cocopods命令更新pod库(如果使⽤的是pod项⽬)
after_all 块⽤于项⽬打包完成之后的操作,⽐如通知⽤户打包完成
error 块⽤于项⽬打包失败之后的操作,⽐如通知⽤户打包失败
lane 定义⼀个打包操作的具体流程,预设的有 lane :release定义了打包并且发布到App Store,lane :beta 打包并且发布到testflight测试平台。fastlane 常⽤的action以及参数
fastlane中最主要的操作就是调⽤action,fastlane预定义了很多很有⽤的action,如果不够还可以使⽤第三发提供的插件调⽤第三发的action。下⾯介绍⼏个fastlane中预定的action
gym 是打包action,是 build_ios_app action的别名,他有以下常⽤的参数:
key描述
workspace如果项⽬是⼀个workspace,则是该项⽬的workspace路径
project项⽬的project路径
scheme项⽬的scheme,注意指定的scheme需要被指定为shared,/->Manage Schemes->Shared复选框需要打钩
output_directory打包保存路径
output_name打包保存的⽂件名
export_method相当于配置 Archives->Export->mehtod 可选:[app-store, ad-hoc, package, enterprise, development(默认), developer-id] configuration相当于配置Scheme->Build Configuration:[Release, Debug],Release会⽣成dsym⽂件,⽽Debug不会
key描述
set_info_plist_value是设置修改info.plist⽂件的 action,⼀次调⽤该action只能设置⼀个值,可以多次调⽤该命令来设置多个值,他有以下常⽤的参数:
key描述
path info.plist⽂件路径
key info.plist⽂件中的key
value key对应的值
pilot 是上传到TestFlight的 action,是 upload_to_testflight action的别名,没有特殊需求可以不指定参数
deliver 是上传到App Store的 action,是 upload_to_app_store action的别名,没有特殊需求可以不指定参数,会从Deliverfile⽂件读取账号信息登录到ITunesConnect从./fastlane/metadata ./fastlane/screenshots ⽂件夹中读取配置的App信息元数据然后上传
fastlane其他操作
fastlane是⼀个ruby的脚本,可以在⾥⾯执⾏⾃定义的脚本⽂件,⽐如添加 sh "your_script.sh" 语句可以执⾏⾃定义的脚本命令,也可以添加
'pwd' (这⾥使⽤的是反引号)执⾏⼀个shell命令或者添加 exec("pwd") 执⾏⼀个shell命令
Fastfile⽂件基本的编写
下⾯以⼀个真实的业务场景为例,该业务场景要求多渠道打包,并且不同渠道对应的配置有差异(info.plist⽂件配置不同和图标不同),打包
⽀持上传到fir测试平台,不同渠道打包的命名⽅式是【时间+渠道+名称.ipa】格式,最后还需要把对应的dsym⽂件和ipa⽂件压缩归档为⼀个zip包⽂件。
# Customise this file, documentation can be found here:
# ls/actions/
# All available actions: ls/actions
# can also be listed using the `fastlane actions` command
# Change the syntax highlighting to Ruby
# All lines starting with a # are ignored when running `fastlane`
# If you want to automatically update fastlane if a new version is available:
# update_fastlane
# This is the minimum version number required.
# Update this, if you use features of a newer version
fastlane_version "2.62.0"
default_platform :ios
platform :ios do
before_all do
# ENV["SLACK_URL"] = "hooks.slack/services/..."
# cocoapods
# carthage
end
desc "Runs all the tests"
lane :test do
scan
endapp开发者需要更新此app以在此ios上正常使用
# 定义全局参数:项⽬名称
projName = "Plush"
# 定义全局参数:Assets路径
projAssetsPath = "../#{projName}/assets"
# 定义全局参数:Info.plist路径
plistPath = "./#{projName}/Resources/Info.plist"
# 定义全局参数:包名(接收之后压缩使⽤)
pkgName = ""
# 定义全局参数:基本包名
basePkgName = "Plush"
# 定义全局参数:输出⽬录,对应output_directory配置
outputBaseDir = "output"
desc "⾃定义的渠道打包"
desc "使⽤⽅式:苹果助⼿:`bundle exec fastlane customChannelBeta ch:pgzs shouldUp:0`"
desc "使⽤⽅式:91助⼿:`bundle exec fastlane customChannelBeta ch:91zs shouldUp:0`"
desc "op ⽀持参数: ch:渠道类型[pgzs, 91zs, AppStore(默认)]"
desc "op ⽀持参数: shouldUp:是否需要上传[0, 1]"
desc "op ⽀持参数: up:上传类型[testflight, fir]"
desc "op ⽀持参数: exportMethod: export_method 配置[app-store, ad-hoc, package, enterprise, development(默认), developer-id] ** up为testflight需要制定为app-store **" desc "op ⽀持参数: version:版本(可选)"
desc "op ⽀持参数: build:构建版本(可选,testflight和appstore这个参数需要制定⼀个不重复的)"
lane :customChannelBeta do |op|
# 渠道
channel = op[:ch]
if channel.nil? || pty?
channel = "AppStore"
end
# 打包名字
time = w
dateTimeStr = "#{ar}-#{h}-#{time.day}_#{time.hour}-#{time.min}"
pkgName = "#{dateTimeStr}_#{channel}_#{basePkgName}.ipa"
# match(type: "appstore") # more information: codesigning.guide
#设置plist,此处传⼊plist路径,可以⽤来做环境配置
set_info_plist_value(path: plistPath, key: "pt_channel", value: channel)
# # 设置AppIcon
# iconPath = op[:iconPath]
# if iconPath.nil? || pty?
# iconPath = "channel_config/#{channel}/icon1024.png"
# iconPath = "channel_config/91zs/icon1024.png"
# end
# puts "iconPath = #{iconPath}"
# appicon(appicon_image_file: iconPath,
# appicon_devices: [:ipad, :iphone, :ios_marketing, :watch, :watch_marketing])
# 拷贝AppIcon.appiconset替换图标
iconAssetPath = op[:iconPath]
if iconAssetPath.nil? || pty?
iconAssetPath = "../channel_config/#{channel}/AppIcon.appiconset"
end
cpCmd = "cp -fRv #{iconAssetPath} #{projAssetsPath}"
`#{cpCmd}`
puts "cpCmd = #{cpCmd}"
# 设置显⽰版本和构建版本
version = op[:version]
build = op[:build]
if version.nil? || pty?
else
increment_version_number(version_number: version)
end
if build.nil? || pty?
else
increment_build_number(build_number: build)
end
exportMethod = op[:exportMethod]
if exportMethod.nil? || pty?
exportMethod = "development"
end
puts "exportMethod = #{exportMethod} pkgName = #{pkgName} outputBaseDir = #{outputBaseDir}"
# build_ios_app 参数配置
gym(
export_method: exportMethod, # 相当于配置 Archives->Export->mehtod:[app-store, ad-hoc, package, enterprise, development(默认), developer-id]  output_name: pkgName,
configuration: "Release", # 相当于配置Scheme->Build Configuration:[Release, Debug],Release会⽣成dsym⽂件,⽽Debug不会
output_directory: outputBaseDir,
scheme: "Plush",
)
# 是否需要上传配置,默认不上传
shouldUp = op[:shouldUp]
if shouldUp == "1"
# 上传测试包到测试平台类型,默认上传到fir,可以⽀持多种测试平台使⽤逗号分隔
# testflight, fir
upType = op[:up]
if upType.nil? || pty?
upType = "fir"
end
if upType.include? "testflight"
pilot # 上传到testflight
elsif upType.include? "fir"
firim(firim_api_token: "xxxxxxxx")#上传fir,如果是新项⽬,fir会⾃动创建
end
end
end
desc "上传到 App Store"
lane :release do
# match(type: "appstore")
# snapshot
gym(
export_method: "app-store", # 相当于配置 Archives->Export->mehtod:[app-store, ad-hoc, package, enterprise, development, developer-id]
output_name: pkgName,
configuration: "Release", # 相当于配置Scheme->Build Configuration:[Release, Debug],Release会⽣成dsym⽂件,⽽Debug不会
output_directory: outputBaseDir,
scheme: "Plush",

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。