fastlane 环境搭建
- 终端执行下面命令进行安装:
sudo gem install fastlane -NV
使用上面命令安装时可以切换gem源为ruby-china.com ,点此链接去切换
或者
brew install fastlane
- iOS相关设置
Xcode command line tools (macOS) 如果没安装则需要安装,如下命令:
xcode-select --install
- 在工程目录下创建Gemfile文件,写入如下内容:
source "https://gems.ruby-china.com/"
gem "fastlane"
gem "cocoapods"
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
上面的 source 改成 gems.ruby-china.com 会快一点
- 终端cd到工程目录下,使用下面初始化fastlane:
fastlane init
上面会弹出4个选项,我们选择第4项手动配置,下面第6步会进行配置
fastlane add_plugin fir_cli
从fir.im获取API Token,https://www.betaqr.com/apps
编辑工程目录下fastlane/Fastfile文件:
7.1 打包ipa如下设置:
default_platform(:ios)
platform :ios do
desc "上传到fir"
lane :gofir do
cocoapods # 执行 pod install
build_app( # 构建app,archive操作
workspace: "**.xcworkspace", # 指定工程文件
scheme: "**", # 指定scheme
configuration: "Adhoc", # 打包模式
export_method: "ad-hoc", # 导出方式
silent: true, # 隐藏构建app时输出的不必要的信息
)
# 上传到fir,
# api_token 参数为上面从fir.im 获取的API Token,
# changelog 参数为变更日志,fir.im上的变更日志
# 多个参数 可以使用逗号(, )分离
answer = fir_cli api_token: "***", changelog: "**",need_release_id:true
# 返回下载地址,此项为fir上面的下载地址
download_url = "***?release_id=#{answer[:release_id]}"
# 通知,此为macOS的系统通知,点击通知会在浏览器中打开上传到fir的链接,复制这个链接就可以发送给测试人员了
notification(title: "发布成功!", message: "已成功上传到fir平台, 赶快联系测试人员开始测试吧!", open: download_url)
end
desc "上传到app_store"
lane :release do
cocoapods
build_app(
workspace: "**.xcworkspace",
scheme: "**",
configuration: "Release",
silent: true,
)
upload_to_app_store( # 上传到app store
force: true, # 跳过HTML预览文件的验证
skip_metadata: true, # 不要上传元数据(例如标题,描述)。这仍然会上传屏幕截图
skip_screenshots: true, # 不要上传屏幕截图
)
end
end
lane 后面是定义一个Action,Action可以做一些操作,上面定义了两个Action,分别可以上传到fir和app store,其他具体使用文档可以看下官方文档,http://docs.fastlane.tools/getting-started/ios/beta-deployment/。
上面的通知可以改成 企业微信的群聊机器人,但是现在公司内群聊机器人未开通,暂时不做处理
7.2 自动打包静态库或者动态库,并且合并armv7 i386 x86_64 arm64,如下设置:
动态库和静态库区别:https://juejin.cn/post/6844904031937101838
platform :ios do
desc "静态库或者动态库打包"
lane :dy do
#build for iphonesimulator
xcodebuild(
target: "ACSCategroies", #打包的Target 需要设置
configuration: "Release",#打包的模式 需要设置
silent: false,
clean: true, #打包前清理
build: true,
sdk:"iphonesimulator", #打包环境
xcargs: "-UseModernBuildSystem=0"
)
#build for iphone
xcodebuild(
target: "ACSCategroies", #打包的Target 需要设置
configuration: "Release", #打包的模式 需要设置
silent: false,
clean: true, #打包前清理
build: true, #打包环境
xcargs: "-UseModernBuildSystem=0",
)
# 上面参数文档http://docs.fastlane.tools/actions/gym/#parameters
# 合并模拟器和真机SDK
# 获取当前路径
code_path = File.expand_path("..", File.dirname(__FILE__)).to_s
target = "ACSCategroies"
# SDK路径
iphonesimulator_path = "#{code_path}/build/Release-iphonesimulator/#{target}.framework/#{target}"
iphoneos_path = "#{code_path}/build/Release-iphoneos/#{target}.framework/#{target}"
# 定义输出的framework路径
out_path = "#{code_path}/build/framework/#{target}.framework"
# 下面合并库会遇到一个have the same architectures (arm64) and can't be in the same fat output file的错误
# 因为Xcode12模拟器架构下的静态库有arm64,真机架构下的静态库也有arm64,有相同的架构导致不能合并。
# 先将模拟器库的arm64架构移除,然后再合并
# 合并后的路径在工程路径下build/framework/
# Two libraries are combined into one, support x86_64, armv7 ,arm64
command = "lipo #{iphonesimulator_path} -remove arm64 -output #{iphonesimulator_path} &&
mkdir #{code_path}/build/framework &&
lipo -create #{iphoneos_path} #{iphonesimulator_path} -output #{out_path}"
result = `#{command}`
end
end
合并库会遇到一个have the same architectures (arm64) and can't be in the same fat output file的错误
因为Xcode12模拟器架构下的静态库有arm64,真机架构下的静态库也有arm64,有相同的架构导致不能合并。
先将模拟器库的arm64架构移除,然后再合并
合并后的路径在工程路径下build/framework/
如果用下面的打包成xcframework就不会出现上面的情况
6.3 自动打包xcframework,推荐使用,如下设置:
platform :ios do
desc "静态库或者动态库打包"
lane :xc do
#build for iphonesimulator
xcodebuild(
target: "ACSCategroies", #打包的Target 需要设置
configuration: "Release",#打包的模式 需要设置
silent: false,
clean: true, #打包前清理
build: true,
sdk:"iphonesimulator", #打包环境
xcargs: "-UseModernBuildSystem=0"
)
#build for iphone
xcodebuild(
target: "ACSCategroies", #打包的Target 需要设置
configuration: "Release", #打包的模式 需要设置
silent: false,
clean: true, #打包前清理
build: true, #打包环境
xcargs: "-UseModernBuildSystem=0",
)
# 上面参数文档http://docs.fastlane.tools/actions/gym/#parameters
# 获取当前路径
code_path = File.expand_path("..", File.dirname(__FILE__)).to_s
target = "ACSCategroies"
# SDK路径
iphonesimulator_path = "#{code_path}/build/Release-iphonesimulator/#{target}.framework"
iphoneos_path = "#{code_path}/build/Release-iphoneos/#{target}.framework"
# 定义输出的xcframework路径
out_path = "#{code_path}/build/xcframework/#{target}.xcframework"
# 合并成xcframework
# 文档http://docs.fastlane.tools/actions/create_xcframework/
create_xcframework(
frameworks:[iphonesimulator_path,iphoneos_path], # 两个Framework
output:out_path # 输出路径
)
end
end
- 终端执行如下代码上传到 fir
fastlane gofir
执行如下代码上传到app store
fastlane release
上传到app store 需要配置fastlane/Appfile文件,文档http://docs.fastlane.tools/advanced/Appfile/,如果不配置,则需要在终端输入账户名称、密码和两步验证码
执行如下代码打包静态库或者动态库
fastlane dy
执行如下代码打包xcframework
fastlane xc
- git自动commit和push 参考文档:http://docs.fastlane.tools/actions/#source-control
至此上面fastlane + Fir 自动打包上传Fir完成了!
Jenkins
如果需要提交代码后自动打包,或者选择分支进行打包,需要用到Jenkins
- 安装Jenkins,安装文档:https://www.jenkins.io/zh/doc/book/installing/
brew install jenkins
解锁 Jenkins,浏览http://localhost:8080 ,安装推荐插件
设置gitlab的凭据,访问gitlab或者github创建一个访问令牌,进入http://localhost:8080/credentials/store/system/domain/_/newCredentials 添加gitlab或者github上的账户和访问令牌
创建任务
源码管理:添加工程的源码地址,gitlab或者github的地址,Credentials选择上面创建的凭据。
触发构建器:此项是为自动构建的条件
下面拿几项说明下
定时构建为设置一段时间自动构建
Build when a change is pushed to GitLab. GitLab webhook URL: 此项为推送代码到仓库时自动构建,此项需要去gitlab设置webhook为构建app的地址,因此机器和gitlab机器不是同一网络,所以此项不通
轮询SCM,是设置一段时间自动去查看仓库有没有commit,有commit自动去构建
构建:此项选择执行shell 脚本
#!/bin/bash -ilex
cd ./**/ # cd到工程目录
fastlane gofir
# fastlane release 或者执行这个上传到app store
构建后操作:此项为构建完成后的操作,我们可以做发送通知的操作,鉴于上面的fastlane已经做了构建完成后的通知了,我们可以不做操作
5.另外加个选择分支手动构建
Jenkins在管理中选插件,安装Git Parameter插件
安装完成之后项目配置中多个如下选择:
勾选它,选择git Parameter
添加如下参数
构建shell修改如下:
#!/bin/bash -ilex
cd ./**/ # cd到工程目录下
if [ "${fastlane_type}" = "fir" ];then
bundle exec fastlane gofir
elif [ "${fastlane_type}" = "app_store" ];then
bundle exec fastlane release
fi
然后我们就可以选择指定分支进行构建了: