Fastlane實戰: 二、自動化打包(下)

上篇說了一些問題,這篇文章就來看一下怎麼打包過程。這裏就按照步驟來講一下。git

需求

按照咱們APP現有的需求,先列舉一下:服務器

  1. 打包的版本號(版本號,編譯版本號)必須爲偶數(便於優先追蹤線上、內測版BUG)
  2. 推送到 fir.im,且成功後發送一條消息到釘釘
  3. 打包結束自動修改版本號、打標籤並推送
  4. 因爲可能會發測試版給外部用戶安裝,因此須要發送特定版本號給用戶
  5. 須要支持打混淆分支,並將版本號同步非混淆分支

非混淆分支

首先,按照常規步驟先走一遍,來看看是如何作的。markdown

desc "打測試包專用"
lane :fir do
  ...接下來這個步驟的全部命令所有在這裏...
end
複製代碼

1. 解鎖遠程機器鑰匙串

由於我我的自己仍是習慣直接經過 ssh 的,因此按照上一篇的加上網絡

# unlock_keychain
keychain_pass = sh("cat ~/.keychain_pass_file")
sh "security unlock-keychain -p #{keychain_pass}"
unlock_keychain(path: "~/Library/Keychains/login.keychain", password: "$(cat ~/.keychain_pass_file)")
複製代碼

2. 拉取最新代碼,重置本地修改

畢竟咱們打包確定要用最新代碼的吧,因此這一步作了一些事,且保證不會和咱們上傳的有區別:app

  • 獲取到當前的分支名: 有幾回發現某些馬甲包沒法自動識別分支,致使須要手動操做,其中 gsub 表示去除空行、換行符等
  • 而後首先重置一次,再拉取服務器最新代碼,其中 --no-edit 表示自動合併,不然可能拉取以後須要手動輸入合併信息
  • 最後執行 pod update 並再次重置,主要是有時候更新會致使工程文件變化。使用 --no-repo-update 純粹是由於網絡很差
# git branch
branch_name = sh("git rev-parse --symbolic-full-name --abbrev-ref HEAD").gsub(/\s+/, "")

# git pull
sh "git reset --hard"
sh "git pull origin #{branch_name} --no-edit"

# pod update
sh "pod update --no-repo-update"
sh "git reset --hard"
複製代碼

3. 修改版本號

這裏有點坑,fastlane 自帶的那個 increment_build_number 有點坑,沒辦法使用。因此只能就手動讀取、設置ssh

  • 這裏作了個兼容,也就是當版本號爲x.x.0,或者當前已經爲偶數時,會作不一樣的處理,其餘時候爲正常+1
  • #{ENV["PLISTPATH"]} 表示讀取環境變量中 PLISTPATH 的值
# set version
prev_apk_version = get_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleShortVersionString")
prev_build_version = get_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleVersion")

apk_versions = prev_apk_version.split(pattern=".")

step = 1
if apk_versions[2].to_i == 0
    step = 0
elsif (apk_versions[2].to_i % 2) == 0
    step = 2
end

current_apk_version = "#{apk_versions[0]}.#{apk_versions[1]}.#{apk_versions[2].to_i+step}"
current_build_version = "#{prev_build_version.to_i + step}"
next_apk_version = "#{apk_versions[0]}.#{apk_versions[1]}.#{apk_versions[2].to_i+step+1}"
next_build_version = "#{prev_build_version.to_i + step + 1}"

set_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleShortVersionString", value: current_apk_version)
set_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleVersion", value: current_build_version)
複製代碼

4. 打包內購包

這個步驟也就是指定了打包目錄和打包類型,沒什麼好說的。測試

# output path
output_name = "#{ENV["SCHEMA"]}_v#{current_apk_version}.ipa"
output_directory = "~/Desktop/ad-hoc/#{ENV["TAGNAME"]}/"
output_path = output_directory + output_name

# gym build
gym(
    scheme: ENV["SCHEMA"], 
    workspace: "ksh3.xcworkspace", 
    include_bitcode: false,
    export_method:"ad-hoc",
    output_name: output_name,
    output_directory:output_directory)
複製代碼

5. 上傳、推送消息

  • 上傳到 fir.im 並從消息中讀取到 Release id,這樣子能夠拼接成指定版本的連接(以前咱們都是手動去網站找的,累)
  • 若是沒有這個功能的話,建議更新一下。或者直接用 fir publish -s #{ENV["FIRLINK"]} #{output_path}
  • 拼接一條消息推送到釘釘上,方便測試人員下載
# fir cli & grep Release id
release_id = sh("fir publish -s #{ENV["FIRLINK"]} #{output_path} | grep -i 'Release id is ' | grep -o -E '[a-z0-9]{16,}'")

# dingtalk
upload_msg = " #{ENV["APPNAME"]}v#{current_apk_version}"
upload_url = "https://fir.im/#{ENV["FIRLINK"]}?release_id=#{release_id}"
dingtalk(access_token:dingtoken, title:upload_msg, message:upload_msg, more_url: upload_url)
複製代碼

6. 收尾工做

  • 重置一次當前的修改,保證當前環境的乾淨
  • 再拉取一次服務器代碼。若是在打包時有同事提交了代碼,就會致使提交時報錯誤
  • 打標籤。這裏要注意標籤不能重複,不然會報錯誤
  • 再次修改版本號爲開發版本號,也就是單數
  • 提交,推送,結束
# update tags & version
sh "git reset --hard"
sh "git pull origin #{branch_name} --no-edit"

sh "git tag #{ENV['TAGNAME']}_#{current_apk_version}"

set_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleShortVersionString", value: next_apk_version)
set_info_plist_value(path: "#{ENV["PLISTPATH"]}", key: "CFBundleVersion", value: next_build_version)

sh "git add ."
sh "git commit -a -m 'update version'"

sh "git push origin #{branch_name} --tags"
sh "git push origin #{branch_name}"
複製代碼

混淆分支

因爲馬甲包爲了上架作了些混淆工做,因此會建立一個單獨的 分支名_appstore 的分支做爲混淆分支,這樣會便於同步最新代碼網站

主要步驟:ui

1. 拉取非混淆分支最新代碼
2. 拼接分支名,切換到非混淆分支
3. 合併不是混淆分支代碼到非混淆分支(這一步驟須要檢查,可能有改動會形成衝突)
4. 經過正常打包邏輯打混淆包
5. 打包結束後,切換到正常分支
6. 遴選到最後更新版本的那條記錄到正常分支,而後推送到服務器
複製代碼
desc "打混淆包專用"
lane :mix do


# git branch
branch_name = sh("git rev-parse --symbolic-full-name --abbrev-ref HEAD").gsub(/\s+/, "")
# 混淆後的分支名,默認爲:分支名_appstore
appstore_branch = "#{branch_name}_appstore"

# 拉服務器最新代碼
sh "git reset --hard"
sh "git pull origin #{branch_name} --no-edit"

# 切換到混淆分支打包,以後切回來,遴選更新版本的變動到主分支
sh "git checkout #{appstore_branch}"
sh "git pull origin #{appstore_branch}"
sh "git merge #{branch_name}"
fir
sh "git checkout #{branch_name}"
sh "git cherry-pick #{appstore_branch}"
sh "git push origin #{branch_name}"
end
複製代碼

完整代碼

其實上邊已經把我整個打包腳本代碼貼出來了,其中也沒有什麼敏感信息。url

環境變量文件

文件保存到和 Fastfile 同級,名稱應爲 .env.xxx。命令記得帶上 fastlane fir --env xxx

// .env.ksh3
SCHEMA=""                       # schema的名字
PLISTPATH=""                    # Info.plist 的位置,路徑爲相對於程序根目錄
FIRLINK=""                      # fir.im 的短鏈,如 wcfg2018
APPNAME=""                      # APP名,中英文隨意
TAGNAME=""                      # git標籤名,叫什麼隨意,不過最好有點意義,能夠用拼音或者英文名 
複製代碼

Fastfile

這裏我按照上篇的考慮,選擇了從遠程獲取,這樣能夠始終保持最新版本

import_from_git(url: '....git', path: 'Fastfile')
複製代碼
相關文章
相關標籤/搜索