Fastlane

Fastlane簡介

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


Fastlane依賴環(huán)境

  • 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使用

  • 進(jìn)入項(xiàng)目文件夾,初始化fastlane
fastlane init

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

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

該步驟結(jié)束后,會在項(xiàng)目根目錄生成一個fastlane的文件夾,如下圖:


fastlane初始化.png

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


Fastfile文件.png

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

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

3.beta這個lane執(zhí)行了gym和pilot,gym用于build、sign程序,pilot用于上傳應(yīng)用到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執(zhí)行了gym和deliver,deliver用于上傳應(yīng)用到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.被執(zhí)行的lane成功之后,執(zhí)行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.被執(zhí)行的lane失敗之后,執(zhí)行error
  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end

Fastlane中部分action介紹

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

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

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

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

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

Fastlane進(jìn)階

  • 傳遞參數(shù)
從command line傳遞參數(shù)給你自定義的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
正在執(zhí)行l(wèi)ane時,切換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
  • 提前終止正在執(zhí)行的lane
關(guān)鍵字next用于提前終止正在執(zhí)行的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時,會返回到上一個正在執(zhí)行的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
當(dāng)你使用next提前終止正在執(zhí)行的lane時,你所定義的after_each、after_all blocks依然會如常觸發(fā);
在任意lane被調(diào)用前會先執(zhí)行before_each blocks;
在任意lane成功執(zhí)行完后會執(zhí)行after_each blocks,如果lane執(zhí)行失敗,則不會調(diào)用after_each blocks,而是調(diào)用error block;
e.g. 如下案例,會執(zhí)行4次before_each、after_each
lane :deploy do
  archive
  sign
  upload
end
lane :archive do
  # ...
end
lane :sign do
  # ...
end
lane :upload do
  # ...
end
  • 直接執(zhí)行actions
如果你未將actions加入Fastfile中就想執(zhí)行某個action,如下,但是這種方式在某些類型的parameters 時會失敗:
fastlane run notification message:"My Text" title:"The Title"
查看action具體信息(如可用options):
fastlane action [action_name]
  • parameters、options的優(yōu)先級
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.如果需要,請?jiān)谧远xlane聲明前導(dǎo)入其他Fastfile
2.定義一個新的lane時,請確保不會出現(xiàn)名字沖突
3.如果你用重寫一個已經(jīng)存在的lane(比如重寫導(dǎo)入的Fastfile中的lane),請使用關(guān)鍵字override_lane
  • 環(huán)境變量
你可以在Fastfile文件的同級目錄下的.env 或 .env.default文件中定義環(huán)境變量
  • 私有l(wèi)anes
直接執(zhí)行某些lanes可能并沒有意義,這時你可以私有化他們:
private_lane :build do |options|
  # ...
end

Fastlane實(shí)戰(zhàn)

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號  只能是整數(shù)和浮點(diǎn)數(shù)
    say 'build number:'
    say options[:build]
    increment_build_number(
        build_number: options[:build],
        xcodeproj: "#{PROJECT_FILE_PATH}",
    )
end

# 設(shè)置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 針對本人項(xiàng)目使用
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  #執(zhí)行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| #測試都是在本地已經(jīng)有證書和描述文件情況下,如果沒有證書和對應(yīng)描述文件,可打開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

執(zhí)行

 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

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

使用homebrew安裝Jenkins

brew install jenkins

執(zhí)行

sh build.sh 1.0.0 1

參考資料

1.Fastlane官網(wǎng)
2.fastlane Tutorial: Getting Started
3.fastlane 教程: 入門
4.iOS 持續(xù)集成之 fastlane + jenkins

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容