通俗来讲,fastlane 是用于 App 自动化测试、打包、发布的工具,向上一层的抽象概念是我们常听到的持续集成 CI (Continuous Integration) /CD (Continuous Delivery) . 当前市场上,App 端实现 CI/CD 比较成熟的两种方式是 Jenkins 和 fastlane. 两者都是跨平台使用,既可以用在 Android ,也可以使用 fastlane 。 Jenkins 基于 java 语言编写,具有一定的可视化界面。fastlane 基于 Ruby 语言,全部为命令行操作。个人认为命令行的方式,更能彰显程序猿的身份,所以选择了 fastlane 来实现 iOS 端的 CI/CD.
fastlane 的官方文档 https://docs.fastlane.tools/ 中,详细介绍了 fastlane 的安装、配置和使用,但是由于英文文档的语言差异,阅读过后在实践中,有一些小细节需要特别注意,下面就自己在实际操作中遇到的困难,详细记录一下使用方式。
1 初始化
fastlane 安装后,需要 cd 到工程所在的目录,执行 fastlane init
命令,然后输入 4 选择 Manual setup
,然后 2 次回车。如果安装成功,能在工程目录的同一级下,看到新生成的 fastlane 文件夹和 Gemfile 文件:
各个文件的用途:
Gemfile -----显示本工程 fastlane 安装的插件和依赖包;
Gemfile.lock --- 记录 gem 的版本和仓库信息;
Appfile ---- 配置 App 的 bundle ID 、version、profile 文件等,以及 AppleID 账号相关等信息;
Fastfile ---- 配置 fastlane 的各种 Action , 本工程使用的 fastlane 命令都在此处配置;
Gemfile 和 Gemfile.lock 两个文件的理解,可以参照 cocoapods 的设置,Gemfile 类别 podfile , 定义了 gem 需要依赖的库文件;Gemfile.lock 类比 podfile.lock, 定义了 pod 的版本。当本地工程的 fastlane 依赖其他插件时,修改 Gemfile 文件,然后运行 bundle update
命令,即可更新本地 fastlane 。
2 文件含义
fastlane 运行的命令都在 Fastfile 文件中定义, 比如对工程 testFastlane 定义如下命令:
default_platform(:ios)
platform :ios do
desc "Use test"
lane :test do
scan(
scheme: testFastlane
output_directory: "fastlane/tests",
clean: true
)
end
end
然后在本地目录下,运行命令 fastlane test
, 就能对 scheme -> testFastlane 进行测试。注:工程中的 scheme 需要设置为 shared
3 工具 dotenv
使用 gem 工具 dotenv ,可以为 fastlane 指定环境变量。
打开 Gemfile 文件,能够看到 fastlane 默认的 gem 源为 https://rubygems.org
, 该网站在国内访问不太稳定,通常需要更改为国内的镜像网站 https://gems.ruby-china.com/
。保存后,使用命令 gem install dotenv
命令安装。
本工程安装了 dotenv 后,默认会自动加载 fastlane 目录下的 .env 或者 .env.defalut 文件。在 fastlane 目录下,输入命令touch .env
新建文件,在文件中添加如下内容:
XCODE_SCHEME = testFastlane
XCODE_CLEAN = true
EXPORT_OUTPUT_DIRECTORY = fastlane/tests
在 fastfile 文件中就可以使用,以上定义的环境变量。比如,对上面的 lane :test 进行改造:
default_platform(:ios)
platform :ios do
desc "Use test"
lane :test do
scan(
scheme: ENV['XCODE_SCHEME'],
output_directory: ENV['EXPORT_OUTPUT_DIRECTORY'],
clean: ENV['XCODE_CLEAN']
)
end
end
切换到 fastlane 文件夹所在的上层目录,使用命令 fastlane test
,运行结果通过。在 iOS 打不同包时,如果想要新建多个环境,可以在 fastlane 目录下,新建多个名称为 .env.xxx
的环境文件。然后通过为 fastlane 命令加参数的方式 fastlane lane命令 --env xxx
就能切换到需要的环境。
4 插件
fastlane 功能十分完善,其实现方式采用了元命令+插件的方式。其中 build 、test、build_ios_app 等都属于元命令。其他命令,比如自动增加版本号、增加 build 值等,通过插件来添加。fastlane 可以使用的插件,参考https://docs.fastlane.tools/plugins/available-plugins。安装后, 会在工程的 Gemfile 文件中记录。通过 bundle update
可以更新安装的插件。
以上是我在 fastlane 使用中遇到的坑,尤其是运行命令时,需要注意所在的路径。现在想来,和 pod 使用时一样,只有在 podfile 所在的目录下,才可以执行 install 命令,而 pod 和 fastlane 都是基于 ruby 的工具。所以,如果其他基于 ruby 的工具,应该都需要注意路径的问题。
最后附上自己工程对 fastlane 的配置文件:
fastlane_version "2.126.0"
default_platform(:ios)
platform :ios do
lane :lint do
swiftlint(
reporter: "html",
output_file: "fastlane/swiftlint.html",
ignore_exit_status: true
)
end
lane :test do
scan(
scheme: ENV['XCODE_SCHEME'],
output_directory: "fastlane/tests",
clean: true
)
end
lane :build do
# cocoapods(
# clean: true,
# podfile: "Podfile"
# )
# incerment the build number
increment_build_number(
build_number: ENV['CI_JOBENV_ID'],
xcodeproj: ENV['XCODE_PROJECT']
)
# BUILD
gym(
scheme: ENV['XCODE_SCHEME'],
configuration: ENV['DEVELOP_CONFIGURATION'],
export_method: ENV['DEVELOP_EXPORT_METHOD'],
output_directory: "fastlane/build",
#export_xargs: ENV['DEVELOP_XARGS'],
silent: true,
clean: true,
#codesigning_identity: "iPhone Developer: Miao Wang (7298FM259A)",
# export_options: {
# method: ENV['EXPORT_METHOD'],
# # provisioningProfiles: {
# # "com.jujinyufu.test" => "com.jujinyufu.test"
# # }
# }
)
end
desc "Archive iOS app" # use with --env for env setting
# desc "****3) #{ENV['EXPORT_METHOD']}"
lane :archive_app do
#increment_build_number_in_plist
build_ios_app(
workspace: ENV['XCODE_WORKSPACE'],
configuration: ENV['DEVELOP_CONFIGURATION'],
scheme: ENV['XCODE_SCHEME'],
silent: ENV['XCODE_SILENT'],
clean: ENV['XCODE_CLEAN'],
output_directory: ENV['EXPORT_OUTPUT_DIRECTORY'], # Destination directory. Defaults to current directory.
output_name: ENV['EXPORT_OUTPUT_NAME'], # specify the name of the .ipa file to generate (including file extension)
export_options: {
method: ENV['EXPORT_METHOD'],
# method: "enterprise",
# provisioningProfiles: {
# "com.example.bundleid" => "Provisioning Profile Name",
# "com.example.bundleid2" => "Provisioning Profile Name 2"
# }
}
)
end
lane :increment_number do
increment_build_number_in_plist(
xcodeproj: ENV['XCODE_PROJECT'],
scheme: ENV['XCODE_SCHEME'],
build_configuration_name: ENV['DEVELOP_CONFIGURATION'],
)
end
lane :deployFirim do
firim(firim_api_token: "your firim token")
end
desc "Notification" # use with --env for env setting
lane :notificationMac do |options|
notification(
subtitle: "Finished Building",
message: options[:message],
)
end
end
还有 env.default 的环境变量:
XCODE_WORKSPACE = testFastlane.xcworkspace
XCODE_PROJECT = testFastlane.xcodeproj
XCODE_SCHEME = testFastlane
XCODE_CLEAN = true
XCODE_SILENT = true
DEVELOP_CONFIGURATION = Release
DEVELOP_EXPORT_METHOD = development
EXPORT_METHOD = enterprise
EXPORT_ARCHIEVE_PATH = fastlane/archieve
EXPORT_BUILD_PATH = fastlane/build
EXPORT_OUTPUT_DIRECTORY = fastlane/ipa
EXPORT_OUTPUT_NAME = testFastlane
配合托管代码的 gitlab 配置,fastlane 还能够顺利实现,在提交分支后,自动打包。这部分知识,我打算另开一篇。就酱~