Fastlane 基础打包配置

Fastlane


fastlane是用Ruby语言编写的一套自动化工具集和框架,每一个工具实际都对应一个Ruby脚本,用来执行某一个特定的任务,而fastlane核心框架则允许使用者通过类似配置文件的形式,将不同的工具有机而灵活的结合在一起,从而形成一个个完整的自动化流程。

主要突出的几个功能:

  • sigh:生成并下载开发者证书
  • produce:在 iTunes Connector 上创建你的应用
  • gym:打包你的应用
  • snapshot:实现应用截屏并取得图片
  • pilot:将你的应用发布到 TestFlight 进行测试
  • deliver:将你的应用的二进制代码,截屏和原数据等信息上传到 AppStore

...其实还有很多很突出也很实用的功能,几乎你能想到的正常的需求都做了,到目前为止已有共计超过210个actions。如果还不够,你还可以寻找额外的plugin,至少有超过250个额外的plugin你可以使用。

fastlane - 安装篇

gem install fastlane

安心等待一会,fastlane 就安装完成了。

可能会出现 bundle 报错的问题:

# 本地没有安装 bundle 
bundle install

# 本地已经安装 bundle 
bundle update

fastlane - 初始化篇

进入到工程目录,然后执行 fastlane 初始化操作:

fastlane init

首先会让你选择一下使用 fastlane 的目的,选择 4 就好了。

What would you like to use fastlane for?
1. 📸  Automate screenshots
2. 👩‍✈️  Automate beta distribution to TestFlight
3. 🚀  Automate App Store distribution
4. 🛠  Manual setup - manually setup your project to automate your tasks

之后静静等待并且无脑回车,最后看到一下输出就代表初始化成功了,文件目录中会多出 Gemfile & Gemfile.lock 这两个文件 和 fastlane 这个文件夹。

To try your new fastlane setup, just enter and run
[17:23:27]: $ fastlane custom_lane

match - 初始化篇

还是在工程目录中执行 match 初始化操作:

fastlane match init

首先会让你选择 match 描述文件和证书存放的地方,选择 git 仓库也就是 1 就好了。

fastlane match supports multiple storage modes, please select the one you want to use:
1. git
2. google_cloud

然后输入 git 仓库的地址,例如 git@xxxxxx/FastlaneProvingProfile.git

Please create a new, private git repository to store the certificates and profiles there
URL of the Git Repo: 

接着看到下面的提示语代表 match 初始化完成了,fastlane 文件夹中会多出一个 Matchfile 文件:

Successfully created './fastlane/Matchfile'. You can open the file using a code editor.

match - 使用篇

有三个不同的命令可以拉取不同环境下的证书和描述文件:

  • 拉取 development 模式下的证书和描述文件
fastlane match development
  • 拉取 adhoc 模式下的证书和描述文件
fastlane match adhoc
  • 拉取 appstore 模式下的证书和描述文件
fastlane match appstore

Fastlane + Jenkins 配置篇

依赖环境:

  • Xcode10+
  • macOS or Linux with Ruby 2.0.0 + (本文:ruby 2.3.4 )

首先看一下已经完成 fastlane 配置的目录结构:

项目根目录
.
├── Gemfile
├── Gemfile.lock
├── exportOptions_pre.plist
├── exportOptions_release.plist
├── fastlane
│   ├── Appfile     # 存储有关开发者账号相关信息
│   ├── Fastfile    # 核心文件,主要用于命令行调用和处理具体的流程,lane 相对于一个方法或者函数
│   ├── Gymfile     # 打包工具相关配置项
│   ├── Deliverfile # 包上传和提审工具配置项
│   └── Matchfile   # 证书和描述文件管理工具配置项
└── ...

1、如果你的项目中有集成 cocoapods, 需要在 Gemfilefastlane初始化的时候创建)文件中添加上 pod 配置, 最好顺便更新一下 gem 源,避免使用过程中引起不适:

source "https://gems.ruby-china.com"

gem "fastlane"
gem "cocoapods"

2、配置 Appfile 文件(开发者账号的相关配置):

# 项目 bundle id
app_identifier("项目 bundle id")

# 苹果开发者账号
apple_id("苹果开发者账号")

# App Store Connect Team ID
itc_team_id("开发者账号的 Team ID") 

# Developer Portal Team ID
team_id("开发者账号的 Team ID")

3、配置 Matchfile (证书和描述文件工具):

通常可以选择将 match 的证书和描述文件存放在一个 git 仓库下,需要预先创建一个 git 仓库来存放证书和描述文件。

# 存放证书和描述文件的 git 仓库地址,对就是刚刚初始化 Match 时候填写的仓库地址
git_url("git@xxxxxx/FastlaneProvingProfile.git")

# 分支名称(我是使用项目的 bundleID 来命名以区分多个项目)
git_branch("xxxxxxxxxx")

# 使用 git 服务
storage_mode("git")

# 默认的 match 类型(可以不设置)
type("development") # The default type, can be: appstore, adhoc, enterprise or development

# 项目的 bundle id(数组的形式)
app_identifier(["xxxxxxxxxx"])

# 有权限修改证书和描述文件的账号名称
username("xxxxxxxxxxxxx") # Your Apple Developer Portal username

4、 配置 Gymfile (打包工具):

# 需要打包的 scheme 名称
scheme("xxxxxx")

# 如果存在多个 workspace 的话需要指定打包的 workspace
workspace("./xxxxxx.xcworkspace")

# 打包的 SDK 版本,可以不设置
# sdk("iphoneos9.0")

# 打包之前执行 clean 操作
clean(true)

# 是否支持 bitcode,因为我们项目不支持,我选择了 false
include_bitcode(false)

5、配置 Fastfile(流程控制工具,支持 ruby 语法):

定义一个简单的无参 lane 如下:

  desc "Push a new beta build to TestFlight"
  lane :beta do
  # 啥事也不干
  end

你可以在一个 lane 中添加不同的 action 去执行各种操作。

通过 jenkins 打包完整的 lane 配置如下:

# 配置 jenkins 环境, 如果使用 Jenkins 打包的话需要设置
def cl_setup_jenkins
  setup_jenkins(
    unlock_keychain: true,
    keychain_path: "钥匙串的全路径",
    keychain_password: "钥匙串的密码"
  )
end

# 更新仓库提交记录
def cl_git_update
  git_submodule_update(
    recursive: true,
    init: true
  )
end

# 更新 pod 仓库
def cl_pod_update
  cocoapods(
    podfile: "./Podfile",
    repo_update: true,
    verbose: true
  )
end

# 更新 adhoc 证书
def cl_match_pre
  match(
    # 证书类型 
    type: "adhoc",
    # 只拉取证书,不更新 apple connect 上的证书和描述文件
    readonly: true
  )
end

# 更新 release 证书
def cl_match_release
  match(
    # 证书类型 
    type: "appstore",
    # 只拉取证书,不更新 apple connect 上的证书和描述文件
    readonly: true
  )
end

# release 打包配置
def cl_gym_release
  gym(
    # 打包的方式
    export_method:"app-store", 
    # 最终输出的文件目录
    output_directory: "./release_builds", 
    # 打包相关配置
    export_options: "./exportOptions_release.plist", 
    # 打包使用的 configuration
    configuration: "Release",
    # 最终输出的包名
    output_name: "xxxxxx" 
  )
end

# pre 打包配置
def cl_gym_pre
  gym(
    # 打包的方式
    export_method:"ad-hoc",
    # 最终输出的文件目录
    output_directory: "./pre_builds",  
    # 打包相关配置
    export_options: "./exportOptions_pre.plist", 
    # 打包使用的 configuration
    configuration: "Pre", 
    # 最终输出的包名
    output_name: "xxxxxx" 
)
end

# 上传 appstore 配置
def cl_deliver_release
  deliver(
    # 即将要上传包的名称 (刚刚输出的包名填的啥就是啥)
    ipa: "./release_builds/xxxxxx.ipa", 
    # 是否跳过上传截图
    skip_screenshots: true, 
    # 是否跳过上传 metadata 文件
    skip_metadata: true 
  )
end


def normal_release

  # 更新仓库提交记录
  cl_git_update

  # 更新 pod 仓库
  cl_pod_update

  # 更新证书
  cl_match_release

  # 打包
  cl_gym_release

  # 上传 appstore
  cl_deliver_release
  
end

def normal_pre 

  # 更新仓库提交记录
  cl_git_update
    
  # 更新 pod 仓库
  cl_pod_update
  
  # 更新证书
  cl_match_pre

  # 打包
  cl_gym_pre

end

default_platform(:ios)

platform :ios do

  desc "jenkins 打包发布到 appstore"
  lane :jenkins_release do
    
    cl_setup_jenkins

    normal_release

  end

  desc "本地打包发布到 appstore"
  lane :local_release do

    normal_release

  end

  desc "上传到打包平台"
  lane :jenkins_pre do
  
     cl_setup_jenkins
     
    normal_pre

  end

end

上面我们配置了三个 lane 用于打不同的包,在项目的根目录执行 fastlane [lane_name] 即可执行 Fastfile 文件中定义的 lane

例子:如果需要在 jenkins 上打线上包,执行 fastlane jenkins_release;

问题整理:

1、jenkins 打包遇到证书和描述文件找不到的问题

jenkins 上配置的节点账户和打包的 mac 用户权限不一致,默认的 keychain 并不是 login.keychain,需要配置钥匙串的路径,并且解密钥匙串,然后把证书访问控制设置为允许所有应用程序访问此项目

setup_jenkins(
    unlock_keychain: true,
    keychain_path: "/Users/server/Library/Keychains/login.keychain-db",
    keychain_password: "2345.Com"
  )

2、账户开启了双重验证导致上传 app 包失败的问题

  • appleid.apple.com/account/manage 上生成一个 application specific password
  • 通过环境变量FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD提供这个application specific password
  • 执行fastlane spaceauth -u [useremail],生成session cookie
  • 通过环境变量FASTLANE_SESSION提供 session cookies

配置如下所示:

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

推荐阅读更多精彩内容