一、 前言
上節(jié)講到我們團(tuán)隊多項目協(xié)同進(jìn)行開發(fā),為了避免重復(fù)造輪子,我們開發(fā)了一些公共服務(wù)組件,供業(yè)務(wù)組的小伙伴使用,以提升開發(fā)效率,同時,有些相同的業(yè)務(wù)模塊,比如IM、廣告模塊等,我們也做了組件化處理。隨著各個項目組業(yè)務(wù)的變化,組件化的更新頻次增加,維護(hù)成本變高【會花費大量的時間和注意力在 提交代碼,發(fā)布 tag 版本,推送 podspec 庫上】,于是便想到使用腳本封裝一套自動化發(fā)布流程工具。
二、腳本編寫
在寫腳本之前,我們先回憶一下,發(fā)布 cocoapods 庫更新時,都有哪些步驟:
1、把寫好的代碼提交到 git
2、在git上打一個 tag ,并且和***.podspec 上的 s.version 保持一致
3、通過 pod 命令驗證 podspec 文件
pod spec lint ***.podspec --allow-warnings
4、把 podspec 文件推送到 [私有repod]
pod repo push [私有repod] ***.podspec --allow-warnings
清晰了發(fā)布流程,我們就可以基于以上步驟,編寫自動化腳本了,在寫腳本之前確保自己電腦已安裝了 cocoapods 和 fastlane 工具,具體的安裝步驟,這里不在敘述。我們用到 fastlane 主要是為了對上述步驟命令進(jìn)行封裝。對于fastlane還不知道是什么的小伙伴,可以看下官網(wǎng) fastlane
既然是想達(dá)到自動化的目的,我們希望執(zhí)行一行命令之后,最終反饋給我們一個成功或者失敗的結(jié)果,過程我們無需關(guān)心,為了達(dá)到以上目的,分為兩步驟進(jìn)行:
步驟一、通過一個腳本文件,找到 ***.podspec 文件,并獲取需要的信息【podspec_version、podspec的文件名】
步驟二、通過 fastlane 命令完成發(fā)布流程
首先,在組件的根目錄創(chuàng)建一個 AutoUpdatePod.sh 腳本文件,腳本的內(nèi)容如下:主要實現(xiàn)的功能是找到 podspec 文件 ,并獲取提交代碼打tag時需要的版本號,并傳遞給fastlane命令
#!/bin/sh
# ************************* 配合 Fastlane 自動更新私有庫 ****************************
echo "\n************************************ 執(zhí)行自動更新 cocoapod 私有庫腳本 ************************************\n"
# 獲取到的文件路徑
file_path=""
file_name=""
# 文件后綴名
file_extension="podspec"
# 文件夾路徑,pwd表示當(dāng)前文件夾
directory="$(pwd)"
# 參數(shù)1: 路徑;參數(shù)2: 文件后綴名
function getFileAtDirectory(){
for element in `ls $1`
do
dir_or_file=$1"/"$element
# echo "$dir_or_file"
if [ -d $dir_or_file ]
then
getFileAtDirectory $dir_or_file
else
file_extension=${dir_or_file##*.}
if [[ $file_extension == $2 ]]; then
# echo "$dir_or_file 是 $2 文件"
file_path=$dir_or_file
file_name=$element
fi
fi
done
}
getFileAtDirectory $directory $file_extension
#echo "\n file_path: ${file_path}"
#echo "\n file_name: ${file_name}"
#
#
#echo "\n ---- 讀取podspec文件內(nèi)容 begin ---- \n"
# 定義pod文件名稱
pod_file_name=${file_name}
# 查找 podspec 的版本
search_str="s.version"
# 讀取podspec的版本
podspec_version=""
pod_spec_version_new=""
#定義了要讀取文件的路徑
my_file="${pod_file_name}"
while read my_line
do
#輸出讀到的每一行的結(jié)果
# echo $my_line
# 查找到包含的內(nèi)容,正則表達(dá)式獲取以 ${search_str} 開頭的內(nèi)容
result=$(echo ${my_line} | grep "^${search_str}")
if [[ "$result" != "" ]]
then
# echo "\n ${my_line} 包含 ${search_str}"
# 分割字符串,是變量名稱,不是變量的值; 前面的空格表示分割的字符,后面的空格不可省略
array=(${result// / })
# 數(shù)組長度
count=${#array[@]}
# 獲取最后一個元素內(nèi)容
version=${array[count - 1]}
# 去掉 '
version=${version//\'/}
podspec_version=$version
#else
# echo "\n ${my_line} 不包含 ${search_str}"
fi
done < $my_file
echo "\n\n\n 【 當(dāng)前正在更新的庫名字是: ${file_name} 版本號:${podspec_version} 】\n\n\n\n\n"
#執(zhí)行 fastlane 命令 ,并執(zhí)行更新 私有組件庫
if [[ "$file_name" != "" ]];then #編寫代碼時,注意[[ A ]] ,A 兩邊要留空格,不然會報錯
fastlane updatePod tag:$podspec_version specName:$file_name
else
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>> 沒有找到 podspec 文件 (⊙︿⊙) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
fi
接下來,編寫發(fā)布流程相關(guān)的命令,同樣還是進(jìn)入到組件項目的根目錄,執(zhí)行命令:
fastlane init
執(zhí)行命令之后會出現(xiàn)如下視圖:

根據(jù)提示選擇最后一個 手動設(shè)置
最后我們會在項目中得到兩個文件 APPfile、Fastfile

APPfile 主要配置 ipa 打包時需要的信息,這里我們用不到,我們主要用到的文件是 Fastfile :用于編寫我們發(fā)布組件時需要的action 命令,當(dāng)然可以封裝自己的Action,這些命令都可以在 fastlane的官網(wǎng)上找到Action,具體如下:
desc 'Hero 自動化升級維護(hù)私有庫'
lane :updatePod do |options|
tagNum = options[:tag]
podspecName = options[:specName]
# 航道上需要執(zhí)行的操作
# 具體action到 https://docs.fastlane.tools/actions 上面查找
# 這里的路徑以倉庫根目錄為準(zhǔn)
# 1、修改spec文件(修改s.version,s.description等)
# 2、pod install (使Example與pod下來的庫產(chǎn)生關(guān)聯(lián))
cocoapods(
clean: true,
podfile: "./Example/Podfile"
)
# 3、提交本地倉庫代碼至遠(yuǎn)程倉庫
git_add(path: ".")
git_commit(path: ".", message: "upgrade repo")
push_to_git_remote
# 4、打標(biāo)簽,并提交至遠(yuǎn)程
# 先驗證tag是否存在,如果存在則刪除本地標(biāo)簽和遠(yuǎn)程標(biāo)簽【前提是你擁有刪除的權(quán)限】
if git_tag_exists(tag: tagNum)
UI.message("您輸入的tag:#{tagNum}已存在,即將自動清除")
remove_git_tag(tagNum: tagNum)
end
add_git_tag(
tag: tagNum
)
push_git_tags
# 5、驗證spec,并提至私有索引庫
pod_lib_lint(allow_warnings: true,skip_import_validation:true,sources:["http://xxx.git(存放podspec文件的私有倉庫地址)", "https://github.com/CocoaPods/Specs"])
# podspec的名字需要由外界傳入
#這里的***Spec 由于是本地repod的倉庫,基本不會變化,可以寫死
pod_push(path: "#{podspecName}", repo: "***Spec", allow_warnings:true,skip_import_validation:true)
end
注意:【***Spec 】一定要換成自己的私有repod
項目文件已經(jīng)放到 github
到這里,自動化發(fā)布組件工具編寫完了,接下來,在項目根目錄下執(zhí)行命令:
./AutoUpdatePod.sh
可以看到,我們的組件已在執(zhí)行自動化發(fā)布流程


顯示 success 說明組件已發(fā)布成功。
三、總結(jié)
編寫工具的目的是為了解放我們的時間和注意力,讓這些重復(fù)性的工作交給機器執(zhí)行,歡迎大家一起交流 !