关于fastlane自动化-你了解么?

背景

我们都知道将开发好的APP发布到AppStore的流程大概是:编译->打包IPA上传->填写应用更新数据->等待iTunesConnect编译->选择版本发布,整个过程大概需要30分钟左右(前提是公司网络还要好,说多了都是泪啊~), 悲催的是如果某一次Build Version忘记增加了,那这个流程还得再来一遍,对于经常不断迭代的产品,这更是痛啊~~

还有一种情况,发布一个Pod远程私有库或者是Pod公开库的流程大概是:
增加Podspec中的版本号->pod install -> Git Commit代码->打标签Tag->推送Tag到Origin->执行pod lib lint命令进行库验证->执行pod repo push命令发布库到私有仓库或者pod trunk push到CocoaPod公开库中,整个过程虽然没有任何技术含量,但是整个过程下来半个小时没了,如果中间标签打错了,或者是标签忘记推送到远端了,,整个过程还得再来一遍!!!

那么有没有什么工具或者好的轮子可以解决上述问题呢?肯定是有的,下面我们就来聊聊今天的主角:Fastlane

fastlane 简介

Fastlane 是一个完全开源的项目,是一款为 iOSAndroid 开发者提供的自动化构建工具,它可以帮助开发者将 App 打包、签名、测试、发布、信息整理、提交 App Store 等工作完整的连接起来,实现完全自动化的工作流,如果使用得当,可以显著的提高开发者的开发效率。
下面是fastlane的GitHub的链接和官方地址;

GitHub链接

官方文档

fastlane 的使用

安装前请确保你已经安装了最新的 Xcode command line tools,通过在终端中执行下面的命令你可以进行检查。

xcode-select --install

安装 fastlane

sudo gem install -n /usr/local/bin fastlane

查看版本


1

为项目配置fastlane

$ cd 项目根目录

$ fastlane init

如果期间报错 Connection reset by peer - SSL_Connect,就需要执行:

$ brew update && brew install ruby
// 重装
$ sudo gem install -n /usr/local/bin fastlane

然后重新执行

$ fastlane init

在这期间会让你输入 Apple ID 账号密码,这个信息会存储在钥匙串中,后续使用无需再输入密码
会检测当前的 app identifier 是否在 Apple Dev Center
会检测当前 app 是否在 iTunes Connect
如果已经在 ADCITC 中创建相应的信息,那么过程会很顺利,如下图:

执行完成之后会在项目目录中生成如下文件结构:


上面这些文件中,最重要的两个文件就是AppfileFastfile
Appfile里面存放了App的基本信息包括App_IdentifierAppIDTeam_ID。如果在init的时候你输入了正确的AppID账号和密码会在这里生成正确的team_id信息。如果没有team,这里就不会显示。
Fastfile是最重要的一个文件,在这个文件里面可以编写和定制我们打包脚本的一个文件,所有自定义的功能都写在这里。

但是如果我们没有在iTunes Connect中创建APP,那么就不会创建上述metadatascreenshots两个文件夹;当然我们也可以后续创建,执行如下操作即可:

$ fastlane produce init

FastFile文件

接下来我们分析下这个文件:

#指定当前fastlane使用的最小版本。
fastlane_version "2.50.0"

#指定当前平台,可以选择iOS,Android,Mac。
default_platform :ios

platform :ios do

#这个指的是在执行每一个lane之前都先执行这个功能。
  before_all do
    cocoapods
    
  end

#一个lane的描述,一般说明lane的用途。  
desc "Runs all the tests"
  lane :test do
    scan
  end


  desc "Submit a new Beta Build to Apple TestFlight"
  desc "This will also make sure the profile is up to date"
  lane :beta do
    # match(type: "appstore") # more information: https://codesigning.guide
    gym(scheme: "kdzs") # Build your app - more options available
    pilot

    # sh "your_script.sh"
    # You can also use other beta testing services here (run `fastlane actions`)
  end

  desc "Deploy a new version to the App Store"
  lane :release do
    # match(type: "appstore")
    # snapshot
    gym(scheme: "kdzs") # Build your app - more options available
    deliver(force: true)
    # frameit
  end

  # You can define as many lanes as you want
#在每个lane执行之后都执行这个功能。
  after_all do |lane|
    # This block is called, only if the executed lane was successful

    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end

#在每个lane执行出错的时候都执行这个功能。
  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end
end

上传 ipa 到蒲公英或者Fir.im上

上传到蒲公英上

上传 ipa 的命令如下:

$ ipa distribute:pgyer -f path/to/ipa -u USER_KEY -a APP_KEY

其中USER_KEYAPP_KEY 可以在蒲公英上查到。

上传到Fir.im上

利用 fir-cli 将打好的包,通过命令,上传到Fir.im平台上
FIR.im CLI 使用 ruby 构建,只要安装相应 ruby gem 即可:

$ gem install fir-cli —verbose

上传 ipa 的命令如下:

$ fir publish path/to/ipa -T YOUR_FIR_TOKEN

其中 YOUR_FIR_TOKEN 可以在 Fir.im 上查到。

完整 Fastfile 代码

fastlane_version "2.28.7"

default_platform :ios

def archive(path, name, scheme, method)

gym(
    export_method: method,
    scheme: scheme,
    clean: true,
    output_directory: path,
    output_name: name,
    configuration: 'Release',
    include_symbols: false,
    include_bitcode: true,
)

end

platform :ios do

desc "打包 type 1: 正式, 0: 测试"

lane :archive do |options|

time = Time.new.strftime("%Y-%m-%d-%H:%M:%S")

path = "./fastlane/" + time

type = options[:type]


# 使用证书创建私钥及签名
cert

# 不带adhoc参数,sigh会自动生成App Store证书(公司或个人帐户)
 sigh(
    adhoc: true,
    force: true,
)

if type == '1'
    name = '正式'
    archive(path, name, 'yourTargetName', 'app-store')
elsif type == '0'
    name = '测试'
    archive(path, name, 'yourTargetName', 'ad-hoc')
# 上传至蒲公英
    system 'ipa distribute:pgyer -f ./' + time + '/' + name + '.ipa -u your_user_key -a your_app_key'
# 上传至fir
    system 'fir publish ./' + time + '/' + name + '.ipa -T your_token'
else
    puts "type错误, type == '0' : 测试, type== '1' : 正式"
end

end

end

CD 项目根目录,就可以通过 fastlane archive type:0 来调用打包脚本了,登录Fir.im和蒲公英平台上我们就可以看到刚刚发布上去的APP了:

Sigh

如果你不确定证书目前是否可用,可以用Sigh自动生成获取证书。Sigh会自动根据Appfile里设置的app_identifierADC(苹果开发者中心)生成证书,并下载到项目根目录下(不是fastlane目录),下载后自动安装。你可以通过指定output_path指定证书下载位置。

PS:建议不要把这个文件夹同步到项目的git中(Fastlane提供了match专门管理所有证书)。可以在.gitignore中忽略这个文件夹。

sigh 的具体用法可以参考GitHub 或者官方文档
而且上面的两个链接我都是帮你们搜好了的,直接点击就可以到达你们想要的位置,不用谢我哈~~

Gym

Gym 是 Fastlane家族的自动化编译工具,和其他工具配合的非常默契,它可以用来编译,打包iOS app,生成签名的ipa文件.下面是GitHub上的描述,我感觉更加贴切些

gym is part of fastlane: The easiest way to automate beta deployments and releases for your iOS and Android apps.
gym builds and packages iOS apps for you. It takes care of all the heavy lifting and makes it super easy to generate a signed ipa or app file 💪

gym is a replacement for shenzhen.

具体用法参考GitHub 或者官方文档

Deliver

我们可以使用deliver命令将屏幕截图、元数据和 IPA 文件上传到iTunes Connect中,

其实上传 ITC 最主要的文件是 Deliverfile,配置好Deliverfile 后,可以删除 metadata文件夹中的文本配置.因为Deliverfile的优先级比metadata要高:

Values provided in the Deliverfile or Fastfile will be take priority over values from these files.

metadata中的所有文件删除以后,将1024*1024的icon图标放入到该目录下,然后创建一个分级的json文件,这里假如叫做:rating.json,具体内容如下:

{
    //#0: None              无
    //#1: Infrequent/Mild   偶尔/轻微的
    //#2: Frequent/Intense  频繁的/强烈的
    //#卡通或幻想暴力
    "CARTOON_FANTASY_VIOLENCE": 0,
    //#现实暴力
    "REALISTIC_VIOLENCE": 0,
    //#大量露骨或残暴的现实暴力
    "PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
    //#低俗笑话
    "PROFANITY_CRUDE_HUMOR": 0,
    //#成人/性暗示题材
    "MATURE_SUGGESTIVE": 0,
    //#恐怖/惊悚题材
    "HORROR": 0,
    //#医学/医疗信息
    "MEDICAL_TREATMENT_INFO": 0,
    //#使用或提及烟、酒或毒品
    "ALCOHOL_TOBACCO_DRUGS": 0,
    //#模拟赌博
    "GAMBLING": 0,
    //#色情或裸露内容
    "SEXUAL_CONTENT_NUDITY": 0,
    //#色情及裸体画面
    "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
    //#无限制的网站访问
    "UNRESTRICTED_WEB_ACCESS": 0,
    //#赌博和竞赛
    "GAMBLING_CONTESTS": 0
}

具体配置参加官方文档

222-w218

Deliverfile的具体配置可以参考:Deliverfile文档

发布到App Store

先看下lane

desc "发布到AppStore"
# 任务名称
lane :Release do

# 创建 ITC 中的 App 信息
produce(
#通常这两项是通过AppFile加载,因此这里不需要手动指定;
    #username: "admin@sutongwang.cn",
    #app_identifier: "gzp.fastlane.test",
    app_name: "fastlane测试",
    language: "zh-Hans",
    app_version: "1.0",
    sku: "gzp.fstlane.test"
)
# 使用证书创建私钥及签名
    cert
# 每次运行时创建新的配置文件
    sigh(force: true)

# 指定输出目录
gym(
    output_directory: './build',
    configuration: 'Release',
    include_symbols: false,
    include_bitcode: true,
)
# 上传所有信息到App Store
deliver(
    force: true,
    #自动发布,false:手动发布
    #submit_for_review: true
)
end

配置完之后执行: fastlane Release

发布成功以后fastlane会给我一个🎉 祝贺一下,哈哈 ,同时会告诉我们帮我们节省了多长时间,如下图:

发布到CocoaPods公开库或者是私有库

desc "编译\上传CocoaPods库"
lane :PushPodsLib do |options|
    targetName = options[:targetName]  #项目名称
    commitMsg = options[:commitMsg] #commit 日志信息
    tagName = options[:tagName]     #标签名称
    path    = "#{targetName}.podspec"

# 根据我们制定的自动化流程去写对应的action

# pod install
cocoapods(
    podfile: "./Example/Podfile"
)

# git add .
    git_add(path: ".")

# git commit -m "xxx"
    git_commit(path: ".", message: commitMsg)


# git push origin master
    push_to_git_remote

# 判断标签是否已经存在
# 如果存在, 应该删除标签(本地标签, 远程标签)
if git_tag_exists(tag: tagName)
UI.message("已经发现存在#{tagName}这个标签, 此处, 删除该标签对应的本地和远程标签")
remove_tag(tagName: tagName)

end

# git tag -a '#{tag}'
add_git_tag(
tag: tagName
)
# git push --tags
push_git_tags

# pod lib lint
pod_lib_lint(allow_warnings: true)

#通过trunk push到Cocoapods公开库中
# pod trunk push "#{targetName}.podspec"
pod_push(path: path,allow_warnings:true)

## You may also push to a private repo instead of Trunk 发布到私有库中
# pod repo push XMGFMSpecs "#{targetName}.podspec"
# pod_push(path: "#{targetName}.podspec", repo: repoName, allow_warnings:true)

其中git_tag_existsfastlaneAction中并不存在的,所以需要我们自定义一个这样判断tag是否存在的Action,如果tag存在,则删除本地和远程的tag,具体是如何自定义的,可以参考我的GitHub

其实长得都差不多,这里我就不再截图了.....

写在最后

我只想说码字真的很伤脑,尤其是想把一个东西讲明白就更烧脑

参考:
GitHub

fastlane官方文档

Fastlane 入门实战教程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容