iOS自动化打包

187 阅读11分钟

iOS手动打包流程

自动化打包

CD(持续交付):软件交付管道以快速、自动化和可重复的方式从源代码生成发布版本,如何完成这项工作的总体设计称为持续交付;
CI(持续集成): 启动管道

iOS自动化打包

Fastlane: 市面上比较流行的自动化流程工具,用其提供的工具集简化构建配置、证书等流程

Jenkins: 最主要的作用是帮助软件开发人员自动化构建、测试和部署他们的应用程序

Jenkins启动整个打包流程,fastlane负责打包、上传到平台;一条龙服务

Fastlane

基本介绍

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

fastlane 安装 参考

fastlane init 这个命令完成fastlane初始化,生成fastlane文件夹

其中Appfile 存储app信息,如bundle id, appleEmail address等,提供给fastfile使用

Fastfile 存储自动化脚本配置,所有任务都是在这个文件进行调度

Deleverfile:上传AppStore包需要的配置文件,在这个文件里可以设置App Store Connect的所有配置项

metadata 存放APP元数据文件,包括关键词、版本更新日志、图标等

screenshorts 存放应用截图

.env 全局的环境配置文件 ,如App_Id = "com.a.b"在其他文件中可以用ENY['App_Id']方式获取

语法 :Ruby

lane - 自定义的任务

在lane中添加合适的工具集action让fastlane按照使用者预期去顺序执行任务;可以理解为函数

lane内可以调用别的lane【称为 switch lane】

 #optionsh类似字典集
lane :laneName do [option]
  # 获取参数 option[:paramName]
  firstParam = option[:param]
  #返回值 ;可无
  put param     
end

#调用lane
laneName(firstParam: '参数', secondParam: 2)
#或命令行调用
fastlane laneName firstParam:'参数' secondParam:2
系统级lane
  • before_all,在执行所有脚本之前首先执行的代码,我们可以在这里面执行一些公共的东西,比如git_pull,cocoapods。

  • after_all, 成功结束之后,处理共有的后置逻辑

  • before_each,每次执行 lane 之前都会执行一次

  • after_each,每次执行 lane 之后都会执行一次

  • error,在执行上述情况任意环境报错都会中止并执行一次

Action --

官网工具集

工具集含括:

  • 测试 : 测试代码,如代码覆盖率报告,swift代码验证,UI测试

  • 构建:编译,cocoapods,xcode相关

  • 截图-

  • 项目: 构建号,版本号,schemes,info等信息相关,可以修改,新增这些信息

  • 代码签名: 与apple证书相关【可以自动注册新测试设备等,对多名开发多名测试的项目很有用,不用一个个去apple developer去注册设备、开发证书等】

  • beta : 将新版本上传至平台:TF、tryoutsdeng、deploygate等;上传dSYM

  • 推送:获取推送证书,如果没有新建

  • 发布:发布到app store connect 、Google Play

  • source control : git相关

  • 通知 : 发送消息到社交软件/Mac通知/邮件组

  • app store connect

  • misc

可以通过配置各种action在fastfile中,以实现不同的目的

常用工具集

  • gym(build_app): 编译、打包,生成签名的ipa文件,可加参数控制输出目录、名字、build configuration(构建配置,默认Release),提供archive路径,打包是基于xcodebuild命令行工具,通过调用xcodebuild命令行来构建和打包,生成ipa

    • xcclean: 清Xcodebuild缓存

    • increment_build_number:增构建号

    • cocoapods:运行pod 的命令,执行pod install,可加各种bool参数控制如是否显示更多调试信息,是否执行完整的pod安装,是否加上repor_update

    • clean_cocopods_cache:清除pods缓存

    • upload_to_testflight 上传新版本到TF

    • last_git_commit 获取最后一次的git提交信息,可以在终端执行 fastlane action last_git_commit

    • git_branch git分支名字

    • mailgun( to: "emailaddress", success: true, message: "This is the mail's content") 发邮件通知

    • sh 执行shell脚本

    全局变量:打包日期

    IPA_TIME = Time.now.strftime("%Y-%m-%d_%H.%M")

    全局变量:scheme

    SCHEME = "DreamShort"

    全局变量:archive路径

    archive_path = "./DreamShortPackageArchive/DreamShort#{IPA_TIME}.xcarchive"

    全局变量:ipa名

    output_name = "#{IPA_TIME}_DreamShort.ipa"

    default_platform(:ios)

    platform :ios do

    ruby 语法:描述一个任务

    desc "Push a new beta build to TestFlight"

    系统级lane,在所有lane之前执行

    before_all do # 当前文件只保留本次构建内容 destination_path="../DreamShortHistoryPackage" dir_path="../DreamShortPackage/"

    #路径不存在创建
    sh "if [ ! -d #{destination_path}  ];then
             mkdir #{destination_path}
        else
             echo dir exist
        fi"
    
    sh "cp -a #{destination_path} #{dir_path}"
    sh "rm -rf #{dir_path}*"
    
    #执行pod install
    cocoapods(use_bundle_exec: false, podfile: "./Podfile", repo_update: false, try_repo_update_on_error: false)
    

    end

    加载 App Store Connect API 令牌

    api_key = app_store_connect_api_key( key_id: '5ZR568H3HZ', issuer_id: 'ee196482-0816-4d8b-9731-8fdb9964e8c1', key_filepath: './fastlane/AuthKey_5ZR568H3HZ.p8', duration: 1200, in_house: false )

    从appstore获取当前构建版本号

    currentBuildNumber = app_store_build_number( api_key: api_key, # 使用app_store_connect_api_key认证 live: false, # live 为 true 查询已发售的版本,false 查询测试的版本 app_identifier: "com.stary.dreamshort" )

    正式环境包,调用package,传 configuration = "Release"

    lane :tf do SCHEME = "DreamShort" package(configuration: "Release") end

    预生产环境包,调用package,传 configuration = "PreRelease"

    lane :pre do SCHEME = "DreamShort-PreRelease"

    package(configuration: "PreRelease")
    

    end

    测试环境包,调用package,传 configuration = "DevDebug"

    lane :dev do SCHEME = "DreamShort-DevDebug" package(configuration: "DevDebug") end

    lane: package

    lane :package do |option|

    # 获取权限
    sh 'security unlock-keychain -p "123456" ~/Library/Keychains/login.keychain'
    # 增加build 号
    increment_build_number(xcodeproj: "./DreamShort.xcodeproj", build_number: currentBuildNumber + 1)
    # 编译、打包、生成签名的ipa;通过传参配置编译选项
    build_app(
      clean: true, 
      output_directory: './DreamShortPackage',  #ipa文件存储目录
      output_name: output_name,                 #生成的ipa文件的名字
      archive_path: archive_path,               #生成的archive文件路径
      workspace: "DreamShort.xcworkspace", 
      scheme: "#{SCHEME}", 
      include_bitcode: false,                   #不包含二进制文件
      include_symbols: true,                    #包含符号化文件dSYM
      configuration: option[:configuration],    #配置选项
      export_method: "app-store",               #导出选项
      export_xcargs: '-allowProvisioningUpdates', #xcodebuild 附加参数
      export_options: {
        provisioningProfiles: { 
          "com.stary.dreamshort": "DreamShortDistribution",
          "com.stary.dreamshort.DSImageNotificationServiceExtension": "DSImageNotificationServiceExtension"
        }
      }
    )
    # 上传新包到TF
    upload_to_testflight(api_key: api_key, skip_waiting_for_build_processing: true)
    

    end

    ======================== 执行lane成功后的操作 ========================

    所有lane完成之后,可以使用参数lane来区分

    after_all do |lane, options|

    puts "#{IPA_TIME} 所有lane执行完毕"
    

    end

    ======================== 执行lane失败后的操作 ========================

    所有lane失败之后,可以使用参数lane来区分

    error do |lane, options| puts "#{IPA_TIME} lane执行失败" end

    end

这样在终端输入fastlane dev即可打出configuration 为DevDebug的包

输入fastlane pre 即可打出configuration 为PreRelease的包

【build configuration是指编译环境,在代码中可以使用】

但如果每次构建都要输入命令,也不是那么地自动化,利用jenkins的自动化构建可以实现一键构建,启动该打包流程

Jenkins

拉取源码

参数化构建过程:定义参数名称

增加构建步骤:执行shell 脚本,在shell中可获取参数,利用脚本启动fastlane打包

export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8

export FASTLANE_XCODE_LIST_TIMEOUT=360 
export FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=240
export FASTLANE_XCODEBUILD_SETTINGS_RETRIES=5

echo -e "=======执行自定义命令======="
#if [ ${customBuildShell} != "" ] 
#then
    bash -c "${customBuildShell}"
#fi

echo "${desc}" > fastlane/releaseNotes.txt || true

echo -e "=======打包上传======="
security unlock-keychain -p "123456" ~/Library/Keychains/login.keychain

rm  pod.lock || true
#fastlane update_fastlane
if [ ${ENV} == "test" ]
then
   fastlane dev
   echo "environment dev-release"
elif [ ${ENV} == "pre" ]
then
	fastlane pre
    echo "environment pre-release"
elif [ ${ENV} == "release" ]
then
	fastlane tf
    echo "environment release"
else
    exit 1
fi
cd dreamshortios && agvtool what-version || true

DreameShort 自动化打包整个流程

Fastlane其他妙用

  1. 打包前根据需要修改配置;如新用户包 利用 update_info_plist,可以在打包前改变info内对应key的值,代码读取该值执行对应代码

  2. 自动化管理证书和配置文件 match_nuke: 所有团队成员共享同一份证书和配置文件

  3. 打包完成自动上传dSYM upload_symbols_to_crashlytics