美文网首页iOS 进阶学习
iOS使用fastlane实现自动化打包

iOS使用fastlane实现自动化打包

作者: 小盟城主 | 来源:发表于2018-11-14 20:32 被阅读3426次

    一、fastlane简介

    fastlane是一套使用Ruby写的自动化工具集,用于iOS和Android的自动化打包、发布等工作,可以节省大量的时间。

    fastlane官网:
    https://fastlane.tools/

    fastlane的官方Github:
    https://github.com/fastlane/fastlane

    fastlane文档说明:
    https://docs.fastlane.tools/

    使用fastlane前,确保你已经可以使用Xcode手动打包成功(说明你已经配置好证书)

    证书配置

    1. 配置环境

    1.安装HomeBrew

    # 查看电脑有没有安装  HomeBrew 没有的话进行下面的安装
    brew -v
    
    #安装
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    #更新到最新版
    brew update
    #更新包
    brew upgrade
    

    2.安装ruby

    # 查看电脑是否已经安装ruby 没有的话进行下面的安装
    ruby -v  
    
    #安装
    brew install ruby
    
    #查看版本
    ruby -v  
    # 例如我的电脑的ruby版本为
    # ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin17]
    

    3.安装fastlane

    确保你的电脑上已安装最新版本的Xcode命令行工具(Xcode command line tools)

    xcode-select --install
    

    如果没有安装,会弹出对话框,点击安装。如果提示xcode-select: error: command line tools are already installed, use "Software Update" to install updates表示已经安装

    开始安装fastlane

    #安装
    gem install fastlane -NV
    

    或者使用

    brew cask install fastlane
    

    安装完之后

    # 确认下是否安装完成和当前使用的版本号
    fastlane -v 
    
    # 我的目前电脑版本
    # fastlane installation at path:/Users/hf/.rvm/gems/ruby-2.2.3/gems/fastlane-2.108.0/bin/fastlane
    # -----------------------------
    # [✔] 🚀 
    # fastlane 2.108.0
    

    二、使用fastlane

    创建一个测试demo,我创建的是HFMyTest
    我的项目的bundle id为www.hf.mytest,这个bundle id需要在开发者中注册provisioning profile
    同时注意设置schemeShared,不然fastlane init的时候会失败,一般默认是选择Shared的,可以不用去管

    设置方法为:A、打开项目的Manage Schemes

    scheme1
    B、勾选上Shared
    scheme2
    1. 先cd到项目路径
    cd /Users/hf/MyTest/HFMyTest/Example
    
    1. 初始化fastlane
    fastlane init 
    
    fastlane init

    可以看见有四个选项

    1. 自动化截图
    2. 将测试版分发自动化到TestFlight
    3. 自动上传、发布到App Store
    4. 手动设置 - 手动设置您的项目以使您的任务自动化

    3. 我这里选择的是3

    select scheme
    1. 可能需要你去select scheme,注意这里面的sheme不是你的项目名,例如我的项目名为HFMyTestsheme就是上面介绍的勾选的Manage ShemesHFMyTest-Example,所以这里选择1

      select sheme
    2. 由于选择3是要发布都AppStore,所以接下来输入用户的app id,这个id应该是具有开发者资格的账号
      输入id之后接下来输入id的密码

    Apple ID
    1. 输入账号和密码后
      如果开发者账号上没有对应的bundle id的App,会提示是否创建一个新的App,这里我们选择否(n),因为这样快速创建的App设置的信息有限


    2. 接下来等待加载,按照步骤回车就可以完成初始化


      初始化完成
    1. 初始化完成后,打开项目目录


      HFMyTest
    2. 发现项目中多出了fastlane目录,通过sublime或者文本编辑打开Appfile和Fastfile

    app_identifier("www.hf.mytest") # The bundle identifier of your app
    apple_id("webmaster@xspcf.com") # Your Apple email address
    
    itc_team_id("118090429") # App Store Connect Team ID
    team_id("MQJL2427R9") # Developer Portal Team ID
    
    # For more information about the Appfile, see:
    #     https://docs.fastlane.tools/advanced/#appfile
    
    
    1. 上面这个Appfile默认已经初始化好了,不用再去操作
    # This file contains the fastlane.tools configuration
    # You can find the documentation at https://docs.fastlane.tools
    #
    # For a list of all available actions, check out
    #
    #     https://docs.fastlane.tools/actions
    #
    # For a list of all available plugins, check out
    #
    #     https://docs.fastlane.tools/plugins/available-plugins
    #
    
    # Uncomment the line if you want fastlane to automatically update itself
    # update_fastlane
    
    default_platform(:ios)
    
    platform :ios do
      desc "Push a new release build to the App Store"
      lane :release do
        increment_build_number(xcodeproj: "HFMyTest.xcodeproj")
        build_app(workspace: "HFMyTest.xcworkspace", scheme: "HFMyTest-Example")
        upload_to_app_store(skip_metadata: true, skip_screenshots: true)
      end
    end
    
    
    1. 以上Fastfile代码中,默认已经设置为上传到AppStore的操作
      release为lane的名字,在执行lane的时候会用到,你可以为lane取任意的名字,也就是release可以取其它的,如appRelease
      build_app用来编译app,你可以为其指定更多的的参数
      打开终端cd到项目目录,运行就可以打包发布到
      AppStore
      使用以下命令来执行这个lane:
    cd /Users/hf/MyTest/HFMyTest/Example
    fastlane release
    

    由于上面我们选择了否(n),也就是现在AppStore上面还没有我们这个HFMyTest这个app,所以上面的操作会最终失败的

    上传AppStore失败
    1. 但是这时候打开HFMyTest本地目录会发现里面会有打出的ipa包
      HFMyTest

    三、自定义Fastfile

    我们知道上面的Fastfile是我们在fastlane init初始化时4个选择中选择了3发布到AppStore,所以生成的Fastfile的功能是只具有发布到AppStore的功能

    打开本地的HFMyTest目录
    删除下面三个文件

    HFMyTest

    然后重新运行一次初始化

    cd /Users/hf/MyTest/HFMyTest/Example
    fastlane init
    

    然后在四个选项中选择第二个


    TestFlight

    然后按照开始的步骤来,最终的到的Fastfie如下

    default_platform(:ios)
    
    platform :ios do
      desc "Push a new beta build to TestFlight"
      lane :beta do
        increment_build_number(xcodeproj: "HFMyTest.xcodeproj")
        build_app(workspace: "HFMyTest.xcworkspace", scheme: "HFMyTest-Example")
        upload_to_testflight
      end
    end
    

    这个Fastfile主要是用于发布到TestFlight进行测试的,
    所以我们可以再终端运行

    fastlane beta
    

    进行发布到testflight,和上面的一样,AppStore是上面没有创建对应的app,这个运行最终会失败。

    Fastfile自定义,它的格式如下

    ···
    # 自动更新fastlane 工具
    # update_fastlane
     
    #需要的fastlane的最小版本,在每次执行之后会检查是否有新版本,如果有会在最后末尾追加新版本提醒
    fastlane_version "2.100.0"
     
    #默认使用平台是 ios,也就是说文件可以定义多个平台
    default_platform :ios
     
    platform :ios do
      before_all do
        # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
     
      end
     
      desc "Runs all the tests"
      lane :test do
        scan
      end
     
      desc "提交一个新的Beta版本到 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: "app_ scheme") # Build your app - more options available
        pilot
     
        # sh "your_script.sh"
      end
     
      desc "部署一个新版本到App Store"
      lane :release do
        # match(type: "appstore")
        # snapshot
        gym(scheme: "app_ scheme") # Build your app - more options available
        deliver(force: true)
        # frameit
      end
     
      # 你可以定义自己的lane
     
      #执行lane成功后的回调
      after_all do |lane|
        # slack(
        #   message: "Successfully deployed new App Update."
        # )
      end
     
      # 如果流程发生异常会走这里并终止
      error do |lane, exception|
        # slack(
        #   message: exception.message,
        #   success: false
        # )
      end
    end
    
    fastlane主要的操作就是action,常用的action有

    scan

    release情况下无法正常运行scan,需要手动去Build Setting中更改enable Testability 在release 下的状态,改为 yes才可以运行。但是官方不建议做release下开启,Test一般在development configuration 下执行。
    

    gym

    常用参数:
    scheme :指定打的哪个scheme
    project :指定project (未使用cocopods)
    workspace :指定workspace (使用cocopods)
    clean :打包前clean
    xcargs : 附加一些参数传递给xcodebuild 如: xcargs: 'DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"',
    export_method :出包方法 app-store, ad-hoc, package, enterprise, development
    configuration : 指定构建App的配置  Release、Debug、自定义
    output_directory : 输出目录
    output_name :输出名称
    include_symbols :是否包含调试符号
    include_bitcode :是否开启bitcode
    

    pilot

    #用于发布**testflight**内部测试,属于**testflight action**的别名
    #常用参数:
    #ipa :要提交的包地址
    #team_name、team_id :如果有多个team 用于区分team
    #skip_waiting_for_build_processing : 在提交完成后的等待是否跳过,一般跳过changelog
    pilot(
      ipa : '../xx.ipa'
    )
    

    deliver

    #用于**直接发包到appstore**,可以选择跳过图片和元数据上传,只提包,后面再配图和数据:如下 skip_screenshots 和  skip_metadata 参数
     deliver(
        ipa: "#{OUTPUT_DIRECTORY}" + "/" + "#{IPA_NAME}",
        skip_screenshots: true,
        skip_metadata: true
    )
    

    四、插件的使用

    1. 查看所支持的插件
    fastlane search_plugins
    
    1. 查看某种插件
    fastlane search_plugins [query] #query为插件名
    
    1. 添加插件
    fastlane add_plugin [name] #name 为插件名
    
    1. 插件使用实例:上传ipa包至蒲公英pyger
      首先添加pyger插件:
    # cd 到项目目录
    cd /Users/hf/MyTest/HFMyTest/Example
    # 安装插件
    fastlane add_plugin pyger 
    

    编辑FastFile,添加以下信息

    desc "打包并上传测试版至蒲公英"
      lane :beta_pgyer do 
        #编译并导出ipa包
        gym(
          clean: true,
          scheme: "scheme_name",
          export_method: "development",
         )
        #上传至蒲公英
        pgyer(
          api_key: "", 
          user_key: "", 
        )
     end
    

    然后终端输入

    fastlane beta_pgyer
    

    就可以上传包到蒲公英
    其中蒲公英的api_key和user_key需要用户去注册蒲公英账号,然后去获取


    蒲公英

    在Fastfile中可以自定义一个有外部传进来参数的方法options,这个options类似于一个字典,可以传入不同的key来获取value,例如通过options[:myKey] 就可以获取value

    lane :myTest do |options|
        myTestStr = options[:key1]
    end
    

    传入options的值

    fastlane myTest key1:myValue1 key2:myValue2
    
    # 传入了两个数字
    {"key1": myValue1,"key2":"myValue2"},
    # 获取数值方式为
    options[:key1] = myvalue1
    

    在Fastfile中设置了increment_build_number进行自动build数字增加,作用是防止本地版本的build号比App Store(或上次)低而做的自动增长版本号的处理,需要先在Xcode中配置如下

    incrementBuild

    下面给出我的一套写好的Fastfile

    # This file contains the fastlane.tools configuration
    # You can find the documentation at https://docs.fastlane.tools
    #
    # For a list of all available actions, check out
    #
    #     https://docs.fastlane.tools/actions
    #
    # For a list of all available plugins, check out
    #
    #     https://docs.fastlane.tools/plugins/available-plugins
    #
    
    # Uncomment the line if you want fastlane to automatically update itself
    
    
    
    ################## READ  FIRST ##################
    
    ######## 使用方法1 自定义version和build #########
    ###### fastlane iosDebug version:1.0.1  build:1 ######
    
    ######## 使用方法2 不写version和build 这时build会根据之前的build+1 #########
    ###### fastlane iosDebug  ######
    
    ###如果需要上传到蒲公英,请运行前先安装插件安装蒲公英的fastlane add_plugin pgyer ###
    
    
    default_platform(:ios)   # 设置默认的平台为ios
    
    ############# 需要根据项目自定义设置 ############
    APP_NAME = "HFMyTest"                # app的名字
    APP_SCHEME = "HFMyTest-Example"  
    APP_IPA_OUTPUT_DIRECTORY = "build/packages"    # 打包所保存的文件目录,可以不设置
    # 配置蒲公英的apiKey 和 userKey 需要设置 
    APP_PGYER_API_KEY = ""
    APP_PGYER_USER_KEY = ""
    
    
    ######## 不用设置的 #####################
    APP_XCODEPROJ = "#{APP_NAME}.xcodeproj"      # app的xcodeproj
    APP_WORKSPACE = "#{APP_NAME}.xcworkspace"    # app的xcworkspace
    APP_IPA_TIME = Time.now.strftime("%Y-%m-%d_%H:%M")  # 打包的时间
    # APP_INFO_PLIST_PATH = './HFMyTest/HFMyTest-Info.plist'
    APP_ENV_PREFIX = ""   # 打包完成后的包文件名字的前缀 区别release和debug
    
    
    
    # 版本 build number++
    def prepare_version(options)
    
        #增加version版本号
        if options[:version]
          increment_version_number(
            version_number: options[:version],
            xcodeproj: "#{APP_XCODEPROJ}",
          )
        else
          # 可以不设置
        end
    
        
        #增加build号  只能是整数和浮点数
        if options[:build]
          increment_build_number(
            build_number: options[:build],
            xcodeproj: "#{APP_XCODEPROJ}",
          )
        else
          last_build = get_build_number(xcodeproj: "#{APP_XCODEPROJ}")
          now_build = last_build.to_i + 1
          increment_build_number(
            build_number: now_build,
            xcodeproj: "#{APP_XCODEPROJ}",
          )
        end
    end
    
    
    #统一的打包方法
    def generate_ipa(exportMethod,configuration,options)
        
        # 设置version和build
        prepare_version(options)  
    
        app_version = get_version_number(xcodeproj: "#{APP_XCODEPROJ}")     # 得到最新的version
        app_build = get_build_number(xcodeproj: "#{APP_XCODEPROJ}")         # 最新的build
        # app包名
        app_ipa_name = "#{APP_NAME}_" "#{APP_ENV_PREFIX}_" + "#{APP_IPA_TIME}_" + "#{app_version}_" + "#{app_build}"
       
        #打包
        gym(
          clean: true,       # 打包前clean项目
          silent: true,      # 隐藏没有必要的信息
          scheme: "#{APP_SCHEME}",
          workspace: "#{APP_WORKSPACE}", 
          configuration: "#{configuration}",  # 环境
          export_method: "#{exportMethod}",   # app-store、ad-hoc、development、enterprise
          output_directory: "#{APP_OUTPUT_DIRECTORY}", #ipa的存放目录
          output_name: "#{app_ipa_name}", # 输出ipa的文件名
          # 生成的ipa文件是否包含symbols,这个文件是内存标记文件,用来定位错误信息的,有了这个安装包大小会变大
          include_symbols: true,
          # 生成的ipa文件是否包含bitcode,在本身项目中也可以配置
          include_bitcode: false,
          # keychain授权 Xcode9不允许访问钥匙串密码,所以我们需要手动开权限
          export_xcargs: "-allowProvisioningUpdates"
          )
    
    end
    
    platform :ios do
      # before_all就是先于所有lane执行的任务
      before_all do
           # 根据安装路径指定要使用的Xcode 
           xcode_select "/Applications/Xcode.app"
           # 超时失败,默认的timeout是10秒
           ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"
      end
    
      # lane  自定义的任务
    
      #debug包 option类似一个字典 option[:version] 取其中value值version
      lane :iosDebug do |options|
        APP_ENV_PREFIX = "debug_"
        generate_ipa("development","Debug",options)
    
        # 上传至蒲公英 在这之前请安装插件 fastlane add_plugin pgyer
        if APP_PGYER_API_KEY.length > 0 && APP_PGYER_USER_KEY.length > 0
          pgyer(
            api_key: "#{APP_PGYER_API_KEY}", 
            user_key: "#{APP_PGYER_USER_KEY}", 
          )
        end
      end
    
      # release发布包
      lane :iosRelease do |options|
        APP_ENV_PREFIX = "appstore_"
        generate_ipa("app-store","Release",options)
        # 上传至app-store
        deliver(
          force: true,              #是否跳过HTML验证报告,默认false
          skip_metadata: true,      #是否跳过上传metadata,默认false
          skip_screenshots: true    #是否跳过上传屏幕截图,默认false
        )
      end
    
      # testFlight包  
      lane :iosTestFlight do |options|
        APP_ENV_PREFIX = "adhoc_"
        generate_ipa("ad-hoc","Release",options)
        # 管理TestFlight的测试用户,上传二进制文件
        pilot
      end
    
      # 当lane执行完成之后进行哪些操作
      after_all do |lane|
    
      end
    
      error do |lane, exception|
    
      end
    
    end
    

    相关文章

      网友评论

        本文标题:iOS使用fastlane实现自动化打包

        本文链接:https://www.haomeiwen.com/subject/wfgjfqtx.html