fastlane 在mac上配置iOS自动化上架

1 序言

fastlane是一个自动打包工具集合,可以预先配置好相关的文件,然后只需要一行打包命名即可将Product->Archive->Export->Confirm等一些列繁琐的步骤快速执行完成。首先介绍一下他的官方文档github地址

2 环境配置

2.1 安装Xcode command line tools

xcode-select --install
当然,你可以先执行以下代码检查是否已经安装了该工具:
$ xcode-select -p

note:安装过程中可能会遇到如下错误:

错误.png

解决方法:
手动下载dmg文件并安装,工具下载地址

2.2 安装fastlane

使用Homebrew安装:
brew cask install fastlane
或者Rubygems安装:
sudo gem install fastlane -NV
我在mac下用gem安装应该有权限问题【SIP(System Integrity Protection)】,那是因为即使是root用户也没有mac的 /usr/bin 执行权限,你当然可以修改该目录权限,但是我不推荐这么修改,因为这里存放的是mac系统预装可执行程序(Unix System Resource),会随着系统的升级而变化。我推荐安装到/usr/local/bin下,这里是用户放置自己的可执行程序的地方,推荐放在这里,不会被系统升级而覆盖同名文件。

这里说一下题外话,如果两个目录下有相同的可执行程序,谁优先执行受到PATH环境变量的影响,我的mac电脑上是:
echo $PATH

执行顺序.png

所以这里推荐使用第一种brew方法安装,安装好之后在根目录下会有.fastlane的文件夹(PS如果看不见, 请按command+shift+.快捷键),此文件下有/bin/fastlane可执行文件。打开命令行工具,输入:$ fastlane -v ,会有如下显示:
提示.png

如果提示fastlane 命令不存在,则说明PATH中没有添加fastlane可执行程序。
解决方法:
1 命令行中输入export PATH=/Users/danielmini/.fastlane/bin:$PATH 则OK,但是下次重新启动命令行工具又会有问题,则再次复制改代码。
2 查看根目录下有无.base_profile,无则创建一个,然后在里面输入:
export PATH=/Users/danielmini/.fastlane/bin:$PATH
danielmini用你的用户名替代。
然后再命令行中输入:source ~/.bash_profile生效。此处还有一个坑:下次打开终端fastlane还是找不到该命令,后来我发现 我的.bash_profile文件根本没有执行,所以可以将. ~/.bash_profile添加到~/.bashrc末尾(如果用的是zsh,则追加到 ~/.zshrc 末尾。其他类推。)
重启终端,输入$ fastlane -v,ok。

2.3 安装bundler

在mac上由于权限问题,此处可以安装至/usr/local/bin目录下:
sudo gem install bundler -n /usr/local/bin
PS:如果你对unix下的PATH不太熟悉,我推荐这篇文章

3 配置fastlane

首进入你项目的根目录下:

3.1 初始化fastlane

fastlane init
中途会让你输入AppleID和密码,之后fastlane会自动检测当前项目中App bundle name等,如果有问题可以选择No,也或者待会去配置文件中修改(后面会讲)。
其中,初始化时应该会有如下选项:

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

主要意思是:
1 自动截屏。(帮助我们截取App的显示到appstore上的 截图)
2 自动发布beta到TestFlight上,用于内测。
3 自动打包发布到AppStore上。
4 手动设置。
我选择3,最后会在项目的根目录下生成一个fastlane文件夹,其中包含AppfileFastfile两个文件。

3.2 配置Gemfile

如果你的项目根目录下没有生成Gemfile,则手动新建一个Gemfile文件。然后输入如下内容:

source "https://rubygems.org"
gem "fastlane"
gem "cocoapods" #如果项目中采用了cocoapods

最后,终端运行一下:bundle update ,会生成Gemfile.lock文件,该文件

note:Gemfile 文件所列的 gem 只是项目依赖的一部分,gem 本身也有自己的依赖,不同的 gem 本身可能依赖了某一 gem 不同的版本,如何让这么多不同版本的依赖不发生冲突,这就是 bundle 的发挥作用的时候了。bundle 不仅用来安装 gem,更重要的是还负责计算出不同 gem 的依赖版本,最终生成 Gemfile.lock 文件,该文件记录了确切的 gem 名称和版本号,以及他们所依赖的 gem 的名称和版本号。
第一次运行 bundle install 时自动生成 Gemfile.lock 文件。以后每次运行 bundle install 时,如果 Gemfile 中的条目不变 bundle 就不会再次计算 gem 依赖版本号,直接根据 Gemfile.lock 检查和安装 gem。如果出现依赖冲突时可以通过 bundle update 更新 Gemfile.lock。

3.3 配置Fastfile文件

Fastfile文件主要结构如下:

fastlane_version "2.14.2" #指定fastlane使用的最小版本
default_platform :ios     #iOS、android、mac
platform :ios do          
    before_all do   #在执行每个lane之前都会先执行
        cocoapods
    end
    
    lane :test do    #名叫test的lane指令集合
    end
    
    lane :beta do  #名叫beta的lane指令集合
    end
    
    lane :release do #名叫release的指令集合
    end
    
    after_all do |lane| #每个lane执行完之后会执行这里

    end

    error do |lane, exception| #每个lane执行出错会执行

    end
end

每一个lane就是一个任务,里面是全部的action组成的工作流。
例如我的项目中的fastlane配置如下所示:

default_platform(:ios)
platform :ios do
  desc "Push a new beta build to TestFlight"
  lane :beta do 
#编译代码
    #build_app(workspace: "NeteasePigsty.xcworkspace", scheme: "NeteasePigsty")
    gym(output_name: "beta2.1.2", # 导出的ipa名字
        output_directory:"~/Documents/beta2.1.2.ipa",# ipa导出目录
     scheme:"NeteasePigsty",
     export_method:"app-store"
        )
    #upload_to_testflight
    appstore       # 上传你的App iTunes Connect
  end
end

其中gym是我们最常用的工具,别名build_app。这里我例举了部分gym常用的可传入参数:

  • Key Description Default
  • workspace workspace文件路径
  • project project文件路径
  • scheme 指定工程的scheme,确认这个scheme是勾选了shared的
  • clean 在构建前是否要clean false
  • output_directory ipa文件应该存储在其中的目录 .
  • output_name 生成ipa文件的名字
  • configuration 构建app时使用的配置。默认为“发布” *
  • silent 在构建时隐藏终端不必要输出的信息 false
  • codesigning_identity 代码签名用的名字,它应该与名称完全匹配,例如'iPhone Distribution: SunApps GmbH'
  • skip_package_ipa 是否应该跳过打包ipa false
  • include_symbols 生成的ipa文件是否包含symbols,这个文件是内存标记文件,用来定位错误信息的,有了这个安装包大小会变大
  • include_bitcode 生成的ipa文件是否包含bitcode,在本身项目中也可以配置,我的项目设置为NO
  • export_method 用于导出archive的方法。有效值是:appstore, ad-hoc, package, enterprise, development, developer-id
  • export_options 指定导出选项plist的路径。使用“xcodebuild -help”来打印完整的可用选项集(应该是用来配置“xcodebuild -help”能打印出来的命令,具体怎么做和作用不明)
  • export_xcargs 将额外的参数传递给打包阶段的xcodebuild。一定要引用设置名称和值,例如OTHER_LDFLAGS="-ObjC -lstdc++" (我用到了export_xcargs: "-allowProvisioningUpdates"来解决一个EXPORT FAILED问题)
  • skip_build_archive 从构建好的archive导出ipa。使用archive_path作为源
  • skip_archive 构建后,不要archive
  • build_path archive应该存储的目录。
  • archive_path 创建archive的路径。
  • derived_data_path 构建产品和一些元数据的目录将会消失(我在想是不是指定目录后当项目构建完自动清除这个目录中的元数据)
  • sdk 应该用于构建应用程序的SDK

Fastlane文件文件是最重要的配置文件了,这里我给出其他一些现成的配置,以供参考:

default_platform(:ios)
platform :ios do
#打出测试包,上传到蒲公英
  lane :beta do            // beta是lane的名字,可以修改
  gym(output_name: "beta", # 导出的ipa名字
           scheme: "debug",  # 用哪个scheme打包,关于scheme的使用可参考我的上一篇文章
    export_method: "ad-hoc",# export_method 可以根据打包类型进行相应设置。可选的值有:app-store、ad-hoc、development、enterprise
 output_directory:"~/Documents/ipa",# ipa导出目录
    export_options: { # xcode9一定要加入export_options,配置bundleId和证书名键值对
      provisioningProfiles: { 
        "com.feiyu.BeautifulPicture" => "mmmajia1_adhoc”,
      }
    }
) 
  pgyer(api_key: "df59c69bfe382fa70f3e96acf104****", user_key: "33d775f94e25df07938ca164241****")// 蒲公英的key
  end

#打出正式包,上传到fir.im
  lane :release do |op|
increment_version_number(version_number: op[:version]) #根据入参version获取app版本号
  gym(output_name: "appstore",
           scheme: "Release",
    export_method: "ad-hoc",
 output_directory:"~/Documents/ipa") 
 firim(firim_api_token:"637bfd3dfeb2c123bd45de864575a****") # fir.im api_token
 
  end

#打出正式包,上传到iTunes Connect
  lane :itunes do
  gym(output_name: "AppStore",
           scheme: "YMPicture_Release",
    export_method: "app-store",
 output_directory:"~/Documents/ipa")
  appstore       # 上传你的App iTunes Connect
  end

当然,除了gym工具还有很多其他的例如Deliver、Sigh、Match等等,具体可以看这里

3.4 上传到itunes connect

fastlane beta

fastlane命令后面跟着lane的名字,即你要做的那个指令集合。

note:我在提交至appstore还遇到了因为苹果账号设置了二次验证的问题,如下图;

image.png
。在参考了这边国外的文章之后,我的解决方法是:
1 开发apple网站
2 选择Security中的APP-SPECIFIC PASSWORDS
image.png

3 输入一个任意的密码标签生成一个验证码,在将改验证码输入终端即可。

至此,提交appstore完毕。

3.5 升级fastlane

bundle update fastlane

4 总结

这边博客只是提交一个基本的fastlane的提交appstore流程,主要起抛砖引玉的租用,其还有非常多的强大功能并未详细说明。我也是利用一天时间摸索了一下,后续会继续研究一些高级用法,有兴趣的童鞋可以多多研究。

参考资料:
官方文档
iOS中fastlane的使用
小团队的自动化发布-Fastlane带来的全自动化部署(知乎)
iOS自动化打包-Fastlane
iOS使用fastlane一键打包审核
使用fastlane自动化部署APP

推荐阅读更多精彩内容