FastLane实战

1、安装fastlane

gem install fastlane

2、配置fastlane

打开命令行,cd到你的工程根目录运行

fastlane init

这时候fastlane会提示你,你想要用fastlane做什么,fastlane会根据你的选择生成对应的文件配置,这里选择2

接下来会提示你输入AppleID的用户名和密码


看到"Successfully generated fastlane configuration"说明设置fastlane成功了,这时候在项目根目录下fastlane会为我们生成两个很重要的文件,后面的大部分时间我们都将用来编辑Fastfile来完成我们的自动化打包流程

打开Appfile,可看到fastlane为我们创建了appid相关的信息,这里创建了apple_id,在后续使用sigh或者match(fastlane提供的一个用来管理证书的action)管理证书的时候将不用再输入appleID

app_identifier("com.yourapp.client") # The bundle identifier of your app
apple_id("yourAppid@company.com") # Your Apple email address

itc_team_id "****" # iTunes Connect Team ID
team_id "****" # Developer Portal Team ID

# For more information about the Appfile, see:
#     https://docs.fastlane.tools/advanced/#appfile

3、设置环境变量

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

4、使用fastlane构建app

打开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
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

# 工程文件路径
PROJECT_FILE_PATH = './FastLaneDemo.xcodeproj'

# plist文件路径
INFO_PLIST_FILE_PATH = './FastLaneDemo/SupportFiles/Info.plist'

# app名
APP_NAME = 'FastLaneDemo'

# scheme名
SCHEME_NAME = 'FastLaneDemo'

# workspace名
WORKSPACE_NAME = 'FastLaneDemo.xcworkspace'

# ipa导出路径
OUTPUT_DIRECTORY = '/Users/Shared/FastLaneDemo_iOS/'

# fastlane流程开始
platform :ios do
  # desc "Description of what the lane does"
  # lane :custom_lane do
  #   # add actions here: https://docs.fastlane.tools/actions
  # end

  before_all do
    
    # 同步源码
    #git_pull

  end 

  # 根据options参数进行打包
  lane :buildExportIpa do |options|

    evn = options[:value] # 获取打包参数deubg/release
    now = Time.now.strftime("%Y%m%d%H%M") # 获取当前时间

  versionNumber = get_info_plist_value(path: "#{INFO_PLIST_FILE_PATH}", key: "CFBundleShortVersionString") # 获取version版本号
  buildNumber = get_info_plist_value(path: "#{INFO_PLIST_FILE_PATH}", key: "CFBundleVersion") # 获取build版本号
  fullIpaName = "#{APP_NAME}" + "_v#{versionNumber}" +  "_Build#{buildNumber}" + "_#{now}" # ipa名
  dSYMFileName = "#{OUTPUT_DIRECTORY}/" + "#{APP_NAME}" + "_v#{versionNumber}" +  "_Build#{buildNumber}" + "_#{now}"

  # 设置环境参数
  if evn == "Debug"
      fullIpaName = "#{fullIpaName}" + "_Debug.ipa"
      dSYMFileName = "#{dSYMFileName}" + "_Debug.app.dSYM.zip"
      exportMethod = "development"
  else 
    fullIpaName = "#{fullIpaName}" + "_Release.ipa"
    dSYMFileName = "#{dSYMFileName}" + "_Release.app.dSYM.zip"
    exportMethod = "ad-hoc"
  end

    # Note:这个action会检查你当前使用的git仓库是不是从指定git分支上check out的,比如,
    # 一般我们会在特定的分支上发布应用,此时如果不是在正确的分支上,则该action会终止lane
  ensure_git_branch(
    branch: 'feature_ios'  # 指定分支名,可用分支全名,也可用正则表达式自动匹配
  )

  # Note: 根据参数编译打包导入ipa
    gym(
      workspace: "#{WORKSPACE_NAME}", # 指定.xcworkspace文件的路径。
      scheme: "#{SCHEME_NAME}", # 指定项目的scheme名称
      clean: 'true',  # 在打包前是否先执行clean。
      output_directory: "#{OUTPUT_DIRECTORY}", # 指定.ipa文件的输出目录,默认为当前文件夹。
      output_name: "#{fullIpaName}", # 指定生成的.ipa文件的名称,应包含文件扩展名。
      configuration: "#{evn}",  # 指定打包时的配置项,默认为Release
      include_symbols: 'true',   # 是否导出符号表
      include_bitcode: 'false',  # 是否使用bitcode打包
      export_method: "#{exportMethod}", # 指定导出.ipa时使用的方法,可用选项:app-store, ad-hoc, package, enterprise, development, developer-id
    )

    # 删除dSYM文件
    if File.exist?("#{dSYMFileName}")
      puts "file dSYMFileName is found"
      File.delete("#{dSYMFileName}")
    end

    fullIpaName  # 返回包名,注意:写在最后一行
 
  end

  # 发布到apphost
  lane :upload_apphost do |options|
    ipaName = options[:value]
    # 执行shell脚本发布到apphost
    `curl --form plat_id=2 --form token=4d355607a661b0e35973301a689ac6c3d02bf4b2 --form releaseNote="http://www.tuandai888.com/plugins/viewsource/viewpagesrc.action?pageId=15386675" --form file=@#{OUTPUT_DIRECTORY}/#{ipaName} http://192.168.13.169:3000//api/pkgs`
  end

  # RN文件打包为bundle
  lane :RNArchive do |options|
    evn = options[:value]

    puts Dir.getwd

    if evn == "Debug"
      `
      cd ../..
      npm install
      react-native bundle --entry-file index.js --platform ios --dev true --bundle-output ./ios/bundle/main.jsbundle --assets-dest ./ios/bundle
      cd ios/
      `
    elsif 
      `
      cd ../..
      npm install
      react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ./ios/bundle/main.jsbundle --assets-dest ./ios/bundle
      cd ios/
      `
    end
        
  end
    
  # 不同环境的打包发布流程
  # 发布Release包
  lane :upload_Release do

    # 更新签名证书
    sigh(adhoc: true, output_path: "/tmp")

    # RN资源打包
    RNArchive(value: "Release")

    # 编译导出ipa,返回ipa名
    ipaName = buildExportIpa(value: "Release")

    # 发布到apphost
    upload_apphost(value: ipaName)

    # 钉钉通知
    DingdingRobot(value: ipaName)

  end

  # 发布Debug包
  lane :upload_Debug do    

    # 更新签名证书
    sigh(development: true, output_path: "/tmp")

    # RN资源打包
    RNArchive(value: "Debug")

    # 编译导出ipa,返回ipa名
    ipaName = buildExportIpa(value: "Debug")

    # 发布到apphost
    upload_apphost(value: ipaName)

    # 钉钉通知
    DingdingRobot(value: ipaName)

  end

  # 同时发布debug和release包
  lane :uploadAll do
    upload_Debug
    upload_Release
  end

  # 单元测试
  lane :test do
    scan(device: "iPhone 6s")
  end

  # 钉钉机器人通知
  lane :DingdingRobot do |options|
    ipaName = options[:value]
    `curl 'https://oapi.dingtalk.com/robot/send?access_token=2c051c5c076b522af6637684c0f480adbeb718954ee08465da37666b2dafcfa0' \
     -H 'Content-Type: application/json' \
     -d '
    {    "actionCard": {
          "title": "最新测试版本", 
          "text": "### 最新测试版本 \n #{ipaName}", 
          "hideAvatar": "0", 
          "btnOrientation": "0", 
          "singleTitle" : "点击下载",
          "singleURL" : "http://192.168.13.169:3000/apps/2/plats/2"
      }, 
      "msgtype": "actionCard"
    }'
    `
  end

end



5、打包并发布

打开命令行,进入工程根目录切换到需要打包的branch,运行

fastlane uploadDebug # 打Debug包
fastlane uploadRelease # 打Release包
fastlane uploadAll # 同时上传Debug和Release包

打包成功之后会看到如下日志:


参考:
fastlane官网
https://www.jianshu.com/p/aa34e6ac47cc

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

推荐阅读更多精彩内容