Fastlane

Fastlane簡介

Fastlane是用Ruby語言編寫的一套自動化工具集和框架,每一個工具實際都對應一個Ruby腳本,用來執行某一個特定的任務,而Fastlane核心框架則允許使用者通過類似配置文件的形式,將不同的工具有機而靈活的結合在一起,從而形成一個個完整的自動化流程。
到目前為止,Fastlane的工具集大約包含170多個小工具,基本上涵蓋了打包、簽名、測試、部署、發布、庫管理等等移動開發中涉及到的內容。如果這些工具仍然沒有符合你需求的,沒有關系,得益于Fastlane本身強大的Action和Plugin機制,如果你恰好懂一些Ruby開發的話,可以很輕易的編寫出自己想要的工具。


Fastlane依賴環境

  • OS X 10.9 (Mavericks) or newer
  • Ruby 2.0 or newer
  • Xcode Command Line Tools (CLT)
  • Paid Apple Developer Account

Fastlane安裝

  • 安裝最新版Xcode command line tools
xcode-select --install
  • 安裝Fastlane
sudo gem install fastlane --verbose
或:sudo gem install -n /usr/local/bin fastlane --verbose

Fastlane工具鏈

Fastlane工具鏈.png

Fastlane使用

  • 進入項目文件夾,初始化fastlane
fastlane init

完成后,如有提示新版本更新,然后你按照指令 sudo gem update fastlane 執行后, 可能出現 Nothing to update 提示,那就是當前設置的ruby源并沒有同步這項,添加ruby源可解決

gem sources --add https://rubygems.org

該步驟結束后,會在項目根目錄生成一個fastlane的文件夾,如下圖:


fastlane初始化.png

Appfile里面存放了App的基本信息包括app_identifier、apple_id、team_id等等。如果在第一步init的時候你輸入了正確的appId賬號和密碼會在這里生成正確的team_id信息。
Fastfile是最重要的一個文件,可以編寫和定制我們打包腳本的一個文件,我們自定義的一些功能就寫在這里。
Fastfile文件中內容:


Fastfile文件.png

從platform :ios do開始下面的就是fastlane可以執行的任務。
1.執行所有lane之前都先執行before_all,該功能里執行了cocoapods 這個action,cocoapods用于為項目執行pod install操作
  before_all do
    # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
    cocoapods
  end

2.test這個lane執行了scan這個action,scan用于運行單元測試
  desc "Runs all the tests"
  lane :test do
    scan
  end

3.beta這個lane執行了gym和pilot,gym用于build、sign程序,pilot用于上傳應用到TestFlight
  desc "Submit a new Beta Build to 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: "YourAppScheme") # Build your app - more options available
    pilot
    # sh "your_script.sh"
    # You can also use other beta testing services here (run `fastlane actions`)
  end

4.release這個lane執行了gym和deliver,deliver用于上傳應用到App Store
  desc "Deploy a new version to the App Store"
  lane :release do
    # match(type: "appstore")
    # snapshot
    gym(scheme: "YourAppScheme") # Build your app - more options available
    deliver(force: true)
    # frameit
  end

5.自定義lane

6.被執行的lane成功之后,執行after_all
  after_all do |lane|
    # This block is called, only if the executed lane was successful
    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end

7.被執行的lane失敗之后,執行error
  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end

Fastlane中部分action介紹

  • gym:build、sign應用
gym(
  workspace: "MyApp.xcworkspace",  # 指定.xcworkspace文件的路徑。
  scheme: "MyApp",  # 指定項目的scheme名稱
  clean: true,  # 在打包前是否先執行clean。
  output_directory: "path/to/dir",  # 指定.ipa文件的輸出目錄,默認為當前文件夾。
  output_name: "my-app.ipa",  # 指定生成的.ipa文件的名稱,應包含文件擴展名。
  configuration: "Debug",  # 指定打包時的配置項,默認為Release。
  silent: true,  # 是否隱藏打包時不需要的信息。
  codesigning_identity: "iPhone Distribution: xxx Co.,Ltd. (5JC8GZ432G)",  # 代碼簽名證書。(XCode8 該配置已忽略)
  include_symbols: true, 
  include_bitcode: true,
  export_method: "ad-hoc",  # 指定導出.ipa時使用的方法,可用選項:app-store, ad-hoc, package, enterprise, development, developer-id
)
  • xcode_select:根據安裝路徑指定要使用的Xcode
xcode_select "/Applications/Xcode6.1.app"
  • xcversion:根據版本號指定要使用的Xcode
xcversion(version: "8.1")
  • snapshot:生成多設備上的本地化屏幕截圖,如果在fastlane init之后沒有生成Snapfile文件需執行
fastlane snapshot init

1.將./SnapshotHelper.swift文加到UI Test target
2.在配置完成后在 UI Tests 的 setup 方法中添加

let app = XCUIApplication()
setupSnapshot(app)
app.launch()

3.在需要截屏的地方是調 snapshot("some name") 方法進行截屏。
4.可以修改 Snapfile 文件來配置需要截屏的設備型號、語言、輸出路徑等,如下修改設備和語言

devices([
   "iPhone 6",
   "iPhone 6 Plus",
   "iPhone 5",
   "iPhone 4s"
 ])
languages([
  "en-US",
  ["pt", "pt_BR"] # Portuguese with Brazilian locale
])
output_directory "./screenshots" #輸出路徑
clear_previous_screenshots true #清除之前圖片
  • increment_build_number:設置Build號
increment_build_number  # 設置Build號每次自增1
increment_build_number(
  build_number: "75"  # 設置一個指定的Build號
)
  • set_info_plist_value:設置項目Info.plist文件中某個key
set_info_plist_value(
path: "./Info.plist",  # 指定Info.plist文件的路徑
key: "CFBundleIdentifier",   # 指定要修改的key
value: "com.krausefx.app.beta"  # 指定key要設定的value
)
  • update_info_plist:更新項目Info.plist文件中的bundle identifier 和 display name
Note:這個action允許你在building之前修改項目的Info.plist文件
update_info_plist(
  display_name: "MyApp-Beta",  # 更新display_name
  app_identifier: "com.example.newappidentifier"  # 更新app_identifier,在Xcode7這里只會修改Info.plist請調用 update_app_identifier來更新
)
  • increment_version_number:設置Version號
Note:patch Version指補丁版本號(7.2.3中的3),minor Version指副版本號(7.2.3中的2),major  Version指主版本號(7.2.3中的7)
version = increment_version_number  # 設置patch Version每次自增1
increment_version_number  # 設置patch Version每次自增1
increment_version_number(
  bump_type: "patch"  # 設置需要自增1的版本類型,可用選項:patch, minor, major
)
increment_version_number(
  version_number: "2.1.1"  # 設置版本號,會覆蓋bump_type參數的值
)
  • update_app_identifier:更新項目的bundle identifier
update_app_identifier(
  xcodeproj: PROJECT_FILE_PATH , #可選
  plist_path: "MyApp/Info.plist",  # 指定項目Info.plist文件的路徑
  app_identifier: "com.test. MyApp"  # 設置bundle identifier
)
  • get_ipa_info_plist_value:獲取.ipa文件中Info.plist文件里某個key的value
get_ipa_info_plist_value(
ipa: "path.ipa",  # 設置.ipa文件的路徑
key: "KEY_YOU_READ"  # 指定要獲取value的key
)
  • match:自動同步開發團隊遠程git中的證書和描述文件到本地
match(
git_url: "path",  # 指定包含所有證書的git私有倉庫地址
git_branch: "branch", # 指定所使用的git分支
type: "appstore",  # 指定創建證書的類型,可用選項:appstore(生產)、development(開發)
app_identifier: ["tools.fastlane.app", "tools.fastlane.sleepy"],  # 程序的bundle identifier(s),多個時用逗號分隔
readonly: true,  # true:僅獲取已經存在的證書和描述文件,而不生成新的
force: true,  # 每次執行match時,是否更新描述文件
force_for_new_devices: true  # 當Apple Developer Portal上的設備數量發生變化時,是否更新描述文件
)
  • sigh:生成描述文件并存入當前文件夾
Note:當生成、匹配證書時,推薦使用match
sigh(
  adhoc: true,  # true:生成AdHoc profiles,false:生成App Store Profiles
  development: ???  # 更新開發證書而不是生產證書
  skip_install: ???  # 默認會自動添加證書到你的本地機器上,設置該參數可以跳過該步驟
  force: true,  # 更新描述文件并忽略其狀態,同時自動為ad hoc profiles添加所有設備
  provisioning_name: ??? # 指定Apple Developer Portal(蘋果開發者中心網)上使用的描述文件名稱
  ignore_profiles_with_different_name: true  # 與provisioning_name參數聯合使用,true:當描述文件名稱完全匹配provisioning_name時才下載,false:不完全匹配也下載
  filename: "myFile.mobileprovision"  # 設置所生成描述文件的名稱,必須包含文件類型后綴. mobileprovision
)
  • cert:獲取或生成最新可用的code signing identity
Note:當生成、匹配證書時,推薦使用match
cert
  • update_project_provisioning:通過描述文件更新項目的code signing設置
update_project_provisioning(
  xcodeproj: "Project.xcodeproj",  # 項目.xcodeproj文件路徑
  profile: "./watch_app_store.mobileprovision",  # 描述文件路徑,必須包含文件類型后綴. mobileprovision
  target_filter: ".*WatchKit Extension.*",  # 使用正則表達式來過濾target名稱
  build_configuration: "Release",  # 使用正則表達式來過濾build configuration項,如果不指定該參數,則表示update_project_provisioning這個action作用于所有build configuration項
  certificate: "path"  #  蘋果根證書路徑
)
  • resign:為已存在的. ipa文件重新Codesign
Note:當你的項目包含嵌套程序或者程序擴展,而這些嵌套程序、程序擴展需要使用各自的描述文件時,你需要提供多個描述文件
resign(
  ipa: "path/to/ipa",  # 指定需要進行重新簽名的.ipa文件路徑
  signing_identity: "iPhone Distribution: Luka Mirosevic (0123456789)",  # 指定簽名類型
  #provisioning_profile: "path/to/profile"  # 指定描述文件路徑,單個bundle identifier、描述文件時
  provisioning_profile: {
    "com.example.awesome-app" => "path/to/profile",
    "com.example.awesome-app.app-extension" => "path/to/app-extension/profile"
  }  # 指定描述文件路徑,多個bundle identifier、描述文件時
)
  • register_devices:注冊新設備到Apple Developer Portal
Note:這個action默認使用Appfile文件中指定的apple_id作為username參數的值,你可以自己指定username參數的值、或者使用環境變量ENV['DELIVER_USER']來覆蓋默認值
register_devices(
  #devices_file: "./devices.txt",  # 指定包含設備信息的文件路徑,文件具體格式參考https://devimages.apple.com.edgekey.net/downloads/devices/Multiple-Upload-Samples.zip
  devices: {
    "Luka iPhone 6" => "1234567890123456789012345678901234567890",
    "Felix iPad Air 2" => "abcdefghijklmnopqrstvuwxyzabcdefghijklmn"
  },  # 指定要注冊的設備列表,格式為:設備名稱 => UDID
  username: "luka@goonbee.com"  # 設置Apple ID
) 
  • pilot:上傳應用到TestFlight
testflight  # pilot的別名
pilot
testflight(
  changelog: “change”,  # 當上傳一個新測試包時,提供測試包的更新信息 
  beta_app_description: “description”,  # 當上傳一個新測試包時,提供測試包的描述信息
  beta_app_feedback_email: “***@163.com”,  # 當上傳一個新測試包時,提供測試包的email地址
  skip_submission: true, # 是否跳過pilot這個action的發布步驟,而僅僅是上傳.ipa文件
  distribute_external: true  # 是否需要將應用發布給外部測試者
)
  • pem:確保推送描述文件有效,如有需要則自動創建推送描述文件
pem(
  development: true,  # true:更新開發推送證書,false:更新生產推送證書
  generate_p12: true,  # 生成p12和gem文件
  force: true, # true:即使舊推送描述文件依然可用,仍然創建新的推送描述文件
  app_identifier: "net.sunapps.9", # optional app identifier,
  save_private_key: true,
  p12_password: 123456,  # 所生成p12文件的密碼
  new_profile: proc do |profile_path|  # 如果生成了新的推送描述文件,該block會被調用
    puts profile_path  # 新的PEM文件的絕對路徑
    # 添加上傳PEM文件到服務器的代碼
  end
)
  • deliver:上傳元數據、屏幕截圖、應用到AppStore
appstore  # deliver的別名
deliver(
  force: true,  #忽略認證
  itc_provider: "abcde12345"  # iTMSTransporter的名字
)
  • commit_version_bump:創建一個’Version Bump’提交操作,在increment_build_number之后使用
Note:這個action將會創建一個’Version Bump’提交操作,與increment_build_number聯合使用才有效。該action會檢索git倉庫,確保你僅僅修改了相關文件(如.plist、.xcodeproj文件)時,提交這些文件到git倉庫。如果你還有其他未提交的修改,這個action將會失敗。
commit_version_bump(
  message: "message"  # 設置提交信息,默認為Version Bump
)
  • push_to_git_remote:push本地修改到遠程分支
push_to_git_remote  # push”master”分支到遠程”origin”
push_to_git_remote(
  local_branch: "develop",  # 將被push的本地分支,默認為當前分支
  remote_branch: "develop",  # push的目的分支,默認為本地分支
  force: true,  # 是否push到遠程,默認為false
  tags: false,  # ???,默認為true
  remote: "origin"  # ???,默認為”origin”
)
  • add_git_tag:給當前分支添加tag
add_git_tag(
  tag: "my_custom_tag"  # 設置tag
)
  • ensure_git_branch:如果當前lane不是在指定git分支上進行的,將會拋出一個異常
Note:這個action會檢查你當前使用的git倉庫是不是從指定git分支上check out的,比如,一般我們會在特定的分支上發布應用,此時如果不是在正確的分支上,則該action會終止lane
ensure_git_branch  # 默認為master分支
ensure_git_branch(
  branch: 'develop'  # 指定分支名,可用分支全名,也可用正則表達式自動匹配
)
  • mailgun:發送成功、錯誤信息給你的團隊
mailgun(
  postmaster: "MY_POSTMASTER",
  apikey: "MY_API_KEY",
  to: "DESTINATION_EMAIL",  # 目標對象
  from: "EMAIL_FROM_NAME",  # 發送對象名稱
  message: "Mail Body",  # 郵件內容
  subject: “subject”,  # 郵件主題
  success: true,  # 本次build是否成功
  app_link: "http://www.myapplink.com",  # 所發布的應用鏈接
  ci_build_link: "http://www.mycibuildlink.com",
  template_path: "HTML_TEMPLATE_PATH”,  # HTML郵件模板
  reply_to: "EMAIL_REPLY_TO"
)

Fastlane進階

  • 傳遞參數
從command line傳遞參數給你自定義的lane:
fastlane [lane] key:value key2:value2
e.g. fast lane deploy submit:false build_number:24
同時,你需要修改自定義的lane聲明包含|options|,才能訪問所傳的值:
before_all do |lane, options|
  # ...
end
before_each do |lane, options|
  # ...
end
lane :deploy do |options|
  # ...
  if options[:submit]
    # Only when submit is true
  end
  # ...
  increment_build_number(build_number: options[:build_number])
  # ...
end
after_all do |lane, options|
  # ...
end
after_each do |lane, options|
  # ...
end
error do |lane, exception, options|
  if options[:debug]
    puts "Hi :)"
  end
end
  • 切換lanes
正在執行lane時,切換lanes:
lane :deploy do |options|
  # ...
  build(release: true) # that's the important bit
  hockey
  # ...
end
lane :staging do |options|
  # ...
  build # it also works when you don't pass parameters
  hockey
  # ...
end
lane :build do |options|
  scheme = (options[:release] ? "Release" : "Staging")
  ipa(scheme: scheme)
end
  • 返回values
lane中定義的最后一行為返回值
lane :deploy do |options|
  value = calculate(value: 3)
  puts value # => 5
end
lane :calculate do |options|
  # ...
  2 + options[:value] # the last line will always be the return value
end
  • 提前終止正在執行的lane
關鍵字next用于提前終止正在執行的lane
lane :build do |options|
  if cached_build_available?
    UI.important 'Skipping build because a cached build is available!'
    next # skip doing the rest of this lane
  end
  match
  gym
end
private_lane :cached_build_available? do |options|
  # ...
  true
end
切換lane期間使用next時,會返回到上一個正在執行的lane
lane :first_lane do |options|
  puts "If you run: `fastlane first_lane`"
  puts "You'll see this!"
  second_lane
  puts "As well as this!"
end
private_lane :second_lane do |options|
  next
  puts "This won't be shown"
end
當你使用next提前終止正在執行的lane時,你所定義的after_each、after_all blocks依然會如常觸發;
在任意lane被調用前會先執行before_each blocks;
在任意lane成功執行完后會執行after_each blocks,如果lane執行失敗,則不會調用after_each blocks,而是調用error block;
e.g. 如下案例,會執行4次before_each、after_each
lane :deploy do
  archive
  sign
  upload
end
lane :archive do
  # ...
end
lane :sign do
  # ...
end
lane :upload do
  # ...
end
  • 直接執行actions
如果你未將actions加入Fastfile中就想執行某個action,如下,但是這種方式在某些類型的parameters 時會失敗:
fastlane run notification message:"My Text" title:"The Title"
查看action具體信息(如可用options):
fastlane action [action_name]
  • parameters、options的優先級
1.CLI parameter (e.g. gym --scheme Example) or Fastfile (e.g. gym(scheme: 'Example'))
2.Environment variable (e.g. GYM_SCHEME)
3.Tool specific config file (e.g. Gymfile containing scheme 'Example')
4.Default value (which might be taken from the Appfile, e.g. app_identifier from the Appfile)
5.If this value is required, you'll be asked for it (e.g. you have multiple schemes, you'll be asked for it)
  • Note
1.如果需要,請在自定義lane聲明前導入其他Fastfile
2.定義一個新的lane時,請確保不會出現名字沖突
3.如果你用重寫一個已經存在的lane(比如重寫導入的Fastfile中的lane),請使用關鍵字override_lane
  • 環境變量
你可以在Fastfile文件的同級目錄下的.env 或 .env.default文件中定義環境變量
  • 私有lanes
直接執行某些lanes可能并沒有意義,這時你可以私有化他們:
private_lane :build do |options|
  # ...
end

Fastlane實戰

Appfile

app_identifier "your identifier" # The bundle identifier of your app
apple_id "your id" # # Your Apple email address

team_id "3MK2KJ67U7"  # Developer Portal Team ID

for_lane :testBeta do  # 可在這里對自定義lane修改appId,identifier,也可以在自定義lane里面修改
    app_identifier "YourAppId"
    apple_id "YourAppleAccount"
end
# you can even provide different app identifiers, Apple IDs and team names per lane:
# More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md

Fastfile

# Customise this file, documentation can be found here:
# https://github.com/fastlane/fastlane/tree/master/fastlane/docs
# All available actions: https://docs.fastlane.tools/actions
# can also be listed using the `fastlane actions` command

# Change the syntax highlighting to Ruby
# All lines starting with a # are ignored when running `fastlane`

# If you want to automatically update fastlane if a new version is available:
# update_fastlane

# This is the minimum version number required.
# Update this, if you use features of a newer version
fastlane_version "2.3.0"

default_platform :ios

PROJECT_FILE_PATH = './test1.xcodeproj'
APP_NAME = 'test1'
SCHEME_NAME = 'test1'

APPSTORE_IDENTIFIER = 'com.test.app'
TESTFlIGHT_IDENTIFIER = 'com.test.app6'
PUSH_IDENTIFIER = 'com.test.apptest'
PLIST_FILE_PATH = 'test1/Info.plist'

# 更新bundle信息
def update_app_bundle(bundle)
  update_app_identifier(
    xcodeproj: PROJECT_FILE_PATH ,
    plist_path: "#{PLIST_FILE_PATH}",
    app_identifier: bundle
  )
end

# build number++
def prepare_version(options)
    #增加版本號
    say 'version number:'
    say options[:version]
    increment_version_number(
        version_number: options[:version],
        xcodeproj: PROJECT_FILE_PATH,
    )
    #增加build號  只能是整數和浮點數
    say 'build number:'
    say options[:build]
    increment_build_number(
        build_number: options[:build],
        xcodeproj: "#{PROJECT_FILE_PATH}",
    )
end

# 設置Info_plist_value里的值(也可直接用 update_info_plist )
def set_info_plist_value(path,key,value)
    #sh 這里是fastline目錄里
    sh "/usr/libexec/PlistBuddy -c \"set :#{key} #{value}\" ../#{path}"
end

# 打包 注:這里needClean 針對本人項目使用
def generate_ipa(needClean,exportMethod,options)
    #say 'generate ipa'
    fullVersion = options[:version] + '.' + options[:build]
    gym(
      project: "test1.xcodeproj",
      #workspace: ‘./test1.xcworkspace',
      scheme: 'test1',
      clean: needClean,
      output_directory: "../Test" + fullVersion,
      output_name: 'test1.ipa',
      #configuration: 'Release',
      include_symbols: 'true',
      include_bitcode: 'false',
      archive_path: "../Test" + fullVersion,
      export_method: "#{exportMethod}”
    )
    # sh "mv ./../build/#{APP_NAME}.app.dSYM.zip ./../build/#{APP_NAME}_#{fullVersion}_#{typePrefix}.app.dSYM.zip"
end

platform :ios do
  before_all do
    # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
    #cocoapods  #執行cocoapods
  end

  desc "打App Store包"
  lane :release do
    ensure_git_branch(
      branch: "develop"
    )
    # match(type: "appstore")
    # snapshot
    needClean = true
    prepare_version(options)
    update_app_bundle("#{APPSTORE_IDENTIFIER}")
    generate_ipa(needClean,"app-store",options)
    deliver(force: true)
    # frameit
  end

 desc "打develop包"
  lane :Develop do |options| #測試都是在本地已經有證書和描述文件情況下,如果沒有證書和對應描述文件,可打開cert和sigh(待測試)
    #cert
    #sigh(
      #adhoc:true.
      #app_identifier: "#{TESTFlIGHT_IDENTIFIER}"
    #)
    needClean = false
    prepare_version(options)
    update_app_bundle("#{TESTFlIGHT_IDENTIFIER}")
    generate_ipa(needClean,"ad-hoc",options)

  end

  desc "打testFlight"
  lane :beta do |options|
   #cert
    #sigh
    needClean = false
    prepare_version(options)
    update_app_bundle("#{TESTFlIGHT_IDENTIFIER}")
    generate_ipa(needClean,"app-store",options)
    pilot
  end

  desc "打不同identifier Push包"
  lane :enterprise do |options|
   #cert
    #sigh
   #pem
    needClean = false
    prepare_version(options)
    update_app_bundle("#{PUSH_IDENTIFIER}")
    generate_ipa(needClean,"development",options)
  end

  after_all do |lane|
    # This block is called, only if the executed lane was successful
    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end

  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end
end

# More information about multiple platforms in fastlane: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md
# All available actions: https://docs.fastlane.tools/actions

# fastlane reports which actions are used
# No personal data is recorded. Learn more at https://github.com/fastlane/enhancer

Snapfile

# Uncomment the lines below you want to change by removing the # in the beginning

# A list of devices you want to take the screenshots from
 devices([
   #"iPhone 6",
   #"iPhone 6 Plus",
   #"iPhone 5",
   "iPhone 4s"
 ])

languages([
  "en-US",
  ["pt", "pt_BR"] # Portuguese with Brazilian locale
])

# The name of the scheme which contains the UI Tests
# scheme "SchemeName"

# Where should the resulting screenshots be stored?
 output_directory "./screenshots"

 clear_previous_screenshots true # remove the '#' to clear all previously generated screenshots before creating new ones

# Choose which project/workspace to use
# project "./Project.xcodeproj"
# workspace "./Project.xcworkspace"

# Arguments to pass to the app on launch. See https://github.com/fastlane/snapshot#launch-arguments
# launch_arguments(["-favColor red"])

# For more information about all available options run
# snapshot --help

執行

 fastlane develop version:B1.0 build:1

如需要打多個包可添加如下腳本

#!/bin/sh

#
# usage:
# > sh build.sh 1.0.0 1
#

versionNumber=$1 # 1.0.0
buildNumber=$2 # 1

rm -rf build
basicLanes="develop enterprise beta release"
for laneName in $basicLanes
do
    fastlane $laneName version:$versionNumber build:$buildNumber
done

可添加參數 區別渠道
# channelIds="fir 91"
# for channelId in $channelIds
# do
    # fastlane Channel version:$versionNumber build:$buildNumber channel_id:$channelId
done

使用homebrew安裝Jenkins

brew install jenkins

執行

sh build.sh 1.0.0 1

參考資料

1.Fastlane官網
2.fastlane Tutorial: Getting Started
3.fastlane 教程: 入門
4.iOS 持續集成之 fastlane + jenkins

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • fastlane運行所需要的環境: OS X 10.9以上 Ruby 2.0 以上 Xcode 擁有一個開發者賬號...
    阿姣_0405閱讀 3,026評論 0 4
  • 更新節點:2019-05-15由于fastlane更新頻繁,已更新到 2.105.2 2.122.0更新內容:fa...
    就叫yang閱讀 61,920評論 73 146
  • 有的公司分工比較細,諸如項目打包、發布這些工作,都會有專門的測試人員去負責,這就為開發人員省去了大部分時間。當然,...
    莮亾閱讀 9,620評論 32 40
  • fastlane 介紹 Fastlane是一套使用Ruby寫的自動化工具集,旨在簡化Android和iOS的部署過...
    MirL閱讀 6,549評論 0 2
  • 生活中有苦也有甜,無論是苦是甜都要笑對人生。記人生五味,乃是酸甜苦辣咸,而經歷最多的就是苦和甜。 苦,一次次挫折,...
    迷之尷尬閱讀 201評論 0 0