Jenkins 概述
Jenkins 是一款流行的開源持續(xù)集成(Continuous Integration)工具,廣泛用于項(xiàng)目開發(fā)垦沉,具有自動(dòng)化構(gòu)建迫皱、測(cè)試和部署等功能。Jenkins用Java語(yǔ)言編寫沸版,可在Tomcat等流行的servlet容器中運(yùn)行,也可獨(dú)立運(yùn)行兴蒸。通常與版本管理工具(SCM)视粮、構(gòu)建工具結(jié)合使用。常用的版本控制工具有SVN橙凳、GIT蕾殴,構(gòu)建工具有Maven、Ant岛啸、Gradle钓觉。
安裝 Jenkins
由于Jenkins 依賴于Java,所以在安裝Jenkins前坚踩,需要先檢查是否已安裝Java環(huán)境荡灾。 在終端輸入命令進(jìn)行檢測(cè):
$ java -version
點(diǎn)擊進(jìn)入安裝說明頁(yè)面,可以按照提示命令安裝
使用 Homebrew 軟件包管理器安裝Jenkins 瞬铸。
自制安裝程序 jenkins-lts 批幌。
安裝命令:
- 安裝最新的LTS版本:
brew install jenkins-lts
- 安裝特定的LTS版本:
brew install jenkins-lts@YOUR_VERSION
- 啟動(dòng) Jenkins 服務(wù):
brew services start jenkins-lts
- 重新啟動(dòng) Jenkins 服務(wù):
brew services restart jenkins-lts
- 更新 Jenkins 版本:
brew upgrade jenkins-lts
安裝步驟
- 啟動(dòng) Jenkins 服務(wù)后,瀏覽 http://localhost:8080 嗓节,該頁(yè)面需要確認(rèn)是管理員安裝荧缘,讓我們輸入密碼,密碼存放在紅色的目錄下赦政,取出來填到輸入框里就行胜宇。
-
選擇安裝推薦的插件。
-
等待插件安裝完成恢着,有的插件可能會(huì)安裝失敗桐愉,建議重試,直到把建議安裝的都裝好掰派。
-
插件安裝完成后會(huì)自動(dòng)跳轉(zhuǎn)到配置完管理員賬戶
- 點(diǎn)擊保存并完成从诲,完成注冊(cè)
Jenkins 配置
打開瀏覽器,輸入localhost:8080靡羡,即可打開Jenkins系洛,輸入密碼,點(diǎn)擊繼續(xù)略步。
重啟Jenkins
因部分插件依賴可能出現(xiàn)錯(cuò)誤待創(chuàng)建好用戶后描扯,可以重啟Jenkins,并用剛創(chuàng)建的賬戶或者admin賬戶登錄Jenkins趟薄。重啟Jenkins方法绽诚,命令行中輸入jenkins-lts
,回車即可。
安裝iOS相關(guān)插件
iOS打包需要鑰匙串中訪問證書恩够、描述文件等卒落,所以我們要安裝鑰匙串和描述文件插件。進(jìn)入Jenkins->系統(tǒng)管理->插件管理安裝相關(guān)插件蜂桶,可通過右上角過濾搜索儡毕。然后選擇需要安裝的插件,進(jìn)行勾選扑媚,安裝腰湾。安裝成功后可以選擇是否重啟Jenkins。
等待安裝完成后重啟 jenkins
配置鑰匙串
成功之后钦购,我們可以在Jenkins首頁(yè)->系統(tǒng)管理中發(fā)現(xiàn)剛才我們安裝的Keychains and Provisioning Profiles Management檐盟,點(diǎn)擊進(jìn)入配置鑰匙串和描述文件。
注意:Code Signing Identity是可以配置多個(gè)的,我們可以把通知證書峰鄙、發(fā)布證書都加入到里面浸间,方法就是點(diǎn)擊下面的Add Code Sign Identity。
配置描述文件
先上傳Provisioning Profiles文件吟榴,這些文件的路徑為/Users/[你的電腦用戶名]/Library/MobileDevice/Provisioning Profiles魁蒜,在此路徑下找到相應(yīng)的項(xiàng)目的profile文件上傳,拖入終端會(huì)顯示整個(gè)路徑吩翻,復(fù)制過來兜看,點(diǎn)擊保存就OK了,現(xiàn)在 Jenkins
不需要一個(gè)一個(gè)上傳描述文件了??狭瞎。
到此為止整個(gè)插件配置完成细移。
創(chuàng)建一個(gè)工程
新建任務(wù)
選第一個(gè),輸入工程名稱熊锭,點(diǎn)擊確定葫哗。
構(gòu)建配置
General
源碼管理
我使用Git缔刹,credentials是登錄的賬號(hào)密碼球涛,打包分支可以根據(jù)需要設(shè)置
如果沒有添加一個(gè)劣针,如下圖
構(gòu)建環(huán)境
選擇剛才插件填寫的對(duì)應(yīng)證書。
構(gòu)建(關(guān)鍵)
點(diǎn)擊增加構(gòu)建步驟亿扁,選擇執(zhí)行shell捺典,輸入打包腳本
腳本說明
-exportArchive有一個(gè)文件adhoc_ExportOptions.plist。不用自己創(chuàng)建从祝,可以使用xcode導(dǎo)出ipa后襟己,從導(dǎo)出的文件夾里獲取。名字為ExportOptions.plist牍陌,修改一下名字就行了 method:有四種渠道擎浴。我將他們做了區(qū)分,分成四個(gè)不同的plist文件毒涧。
分別為 app-store ad-hoc enterprise development
打包導(dǎo)出ipa后需要執(zhí)行上傳內(nèi)測(cè)或應(yīng)用平臺(tái)贮预,我是上傳的蒲公英, 使用cURL直接上傳到蒲公英契讲,具體命令蒲公英官方有提供 蒲公英API仿吞,獲取uKey 和 _api_key也是在這個(gè)頁(yè)面
到這里就配置完了,點(diǎn)擊保存捡偏,可以開始構(gòu)建了唤冈。
附打包腳本
#!/bin/sh
export LANG=en_US.UTF-8
# 1.設(shè)置配置標(biāo)識(shí),編譯環(huán)境(根據(jù)需要自行填寫 release |debug )
configuration="release"
# 工程名(根據(jù)項(xiàng)目自行填寫)
APP_NAME="TestDome"
# TARGET名稱(根據(jù)項(xiàng)目自行填寫)
TARGET_NAME="TestDome"
# ipa前綴(根據(jù)項(xiàng)目自行填寫)
IPA_NAME="測(cè)試"
# info.plist路徑
#project_infoplist_path="./${TARGET_NAME}/Info.plist"
# 取版本號(hào)
#bundleShortVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${project_infoplist_path}")
#bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" "${project_infoplist_path}")
# 日期
DATE=$(date +%Y%m%d-%H-%M-%S)
# 工程文件路徑
ARCHIVE_NAME="${APP_NAME}_${DATE}.xcarchive"
# 存放ipa的文件夾名稱(根據(jù)自己的喜好自行修改)
IPANAME="${APP_NAME}_${DATE}_IPA"
# 工程根目錄#工程源碼目錄(這里的${WORKSPACE}是jenkins的內(nèi)置變量表示(jenkins job的路徑):/Users/plz/.jenkins/workspace/TestDome/)
# ${WORKSPACE}/TestDome/ 中的TestDome根據(jù)你的項(xiàng)目自行修改
CODE_PATH="${WORKSPACE}"
# 要上傳的ipa文件路徑 ${username} 需要換成自己的用戶名
ROOT_PATH="/Users/${username}/Desktop/Jenkins"
ARCHIVE_PATH="${ROOT_PATH}/Archive/${ARCHIVE_NAME}"
IPA_PATH="${ROOT_PATH}/Export/${IPANAME}"
echo "ARCHIVE_PATH: ${ARCHIVE_PATH}"
echo "IPA_PATH: ${IPA_PATH}"
echo "IPA_PATH:\n${IPA_PATH}">> export_history.txt
# 導(dǎo)包方式(這里需要根據(jù)需要手動(dòng)配置:AdHoc/AppStore/Enterprise/Development)
EXPORT_METHOD="AdHoc"
# 導(dǎo)包方式配置文件路徑(這里需要手動(dòng)創(chuàng)建對(duì)應(yīng)的XXXExportOptionsPlist.plist文件,并將文件復(fù)制到根目錄下[我這里在源項(xiàng)目的根目錄下又新建了ExportPlist文件夾專門放ExportPlist文件])
if test "$EXPORT_METHOD" = "AdHoc"; then
EXPORT_METHOD_PLIST_PATH=${CODE_PATH}/ExportOptions/AdHocExportOptions.plist
elif test "$EXPORT_METHOD" = "AppStore"; then
EXPORT_METHOD_PLIST_PATH=${CODE_PATH}/ExportOptions/AppStoreExportOptios.plist
elif test "$EXPORT_METHOD" = "Enterprise"; then
EXPORT_METHOD_PLIST_PATH=${CODE_PATH}/ExportOptions/EnterpriseExportOptions.plist
else
EXPORT_METHOD_PLIST_PATH=${CODE_PATH}/ExportOptions/DevelopmentExportOptions.plist
fi
# 指ipa定輸出文件夾,如果有刪除后再創(chuàng)建银伟,如果沒有就直接創(chuàng)建
if test -d ${IPA_PATH}; then
rm -rf ${IPA_PATH}
mkdir -pv ${IPA_PATH}
echo ${IPA_PATH}
else
mkdir -pv ${IPA_PATH}
fi
# 進(jìn)入工程源碼根目錄
cd "${CODE_PATH}"
# 執(zhí)行pod
pod install --verbose --no-repo-update
#mkdir -p build
# 清除工程
echo "++++++++++++++++clean++++++++++++++++"
xcodebuild clean -workspace ${APP_NAME}.xcworkspace -scheme ${APP_NAME} -configuration ${configuration}
# 將app打包成xcarchive格式文件
echo "+++++++++++++++++archive+++++++++++++++++"
xcodebuild archive -workspace ${APP_NAME}.xcworkspace -scheme ${APP_NAME} -configuration ${configuration} -archivePath ${ARCHIVE_PATH}
# 將xcarchive格式文件打包成ipa
echo "+++++++++++++++++ipa+++++++++++++++++"
xcodebuild -exportArchive -archivePath ${ARCHIVE_PATH} -exportPath "${IPA_PATH}" -exportOptionsPlist ${EXPORT_METHOD_PLIST_PATH} -allowProvisioningUpdates
# 刪除工程文件
# echo "+++++++++刪除工程文件+++++++++"
# rm -rf $ARCHIVE_PATH
# 蒲公英上傳結(jié)果日志文件路徑
PGYERLOG_PATH="${IPA_PATH}/upload_pgyer_log"
# 創(chuàng)建蒲公英上傳結(jié)果日志文件夾
mkdir -p ${PGYERLOG_PATH}
# 創(chuàng)建蒲公英上傳結(jié)果日志文
touch "${PGYERLOG_PATH}/log.txt"
# 上傳IPA到蒲公英 根據(jù)蒲公英官方文檔編寫
file_path="${IPA_PATH}/${IPA_NAME}.ipa"
echo "正在上傳文件"
echo $file_path
curl -F "file=@${file_path}" -F "uKey=0ea4142136d51cbe5aaf94cdbf6aaeb1" -F "_api_key=16d3ff684c5576f9d9f6c958cf0a7300" https://upload.pgyer.com/apiv1/app/upload
構(gòu)建 (打包上傳)
立即構(gòu)建
點(diǎn)擊立即構(gòu)建開始構(gòu)建點(diǎn)擊構(gòu)建版本可以查看狀態(tài)和控制臺(tái)輸出信息
Jenkins 打包 ipa 常見錯(cuò)誤匯總
問題1. pod時(shí)候會(huì)出現(xiàn) command not found
當(dāng)你jenkins服務(wù)在非OS X系統(tǒng)運(yùn)行時(shí)你虹,使用Mac節(jié)點(diǎn)的配置稍微不一樣。
解決方案
-
系統(tǒng)管理-系統(tǒng)配置-全局屬性
值:在終端中輸入echo $PATH將輸出內(nèi)容復(fù)制填寫彤避。
問題2:ipa包導(dǎo)出失敗傅物,導(dǎo)致報(bào)錯(cuò):curl: (26) Failed to open/read local data from file/application
- 先去文件路徑下查看打包是否成功,路徑下包含已經(jīng)IPA文件忠藤,確定路徑?jīng)]有問題挟伙;
- 查看腳本文件中的路徑,腳本中的ipa名稱與打包出來的IPA文件的名稱不一致模孩。
解決方案
將腳本中的ipa名稱改為應(yīng)用的顯示名稱
問題3. 打包時(shí)報(bào)錯(cuò):error: exportArchive: The data couldn’t be read because it isn’t in the correct format.
解決方案 1
xcode archive 導(dǎo)出 ipa 時(shí)不要勾選 Rebuild from Bitcode 尖阔,導(dǎo)出的
ExportOptions.plist
替換項(xiàng)目目錄下的AdHocExportOptions.plist
解決方案 2
需要把xcode上的BitCode關(guān)閉,設(shè)置成No即可,project和targets里面對(duì)應(yīng)的BitCode都需要關(guān)閉
問題4. 打包時(shí)報(bào)錯(cuò):xcodebuild: error: 'APP.xcworkspace' does not exist
解決方案
Choose Product > Scheme > Manage Schemes.
Share your scheme:
也可能是Xcode Workspace File 路徑錯(cuò)誤
問題5. 編輯報(bào)錯(cuò) error: /Users/plz/.jenkins/workspace/target_name/Pods/Target Support Files/Pods-HIGO/Pods-HIGO.release.xcconfig: unable to open file (in target "target_name" in project "target_name") (in target 'target_name' from project 'target_name')
解決方案
shell腳本中添加如下命令
1. sudo gem install cocoapods --pre
2. pod install
如果不行 加上 3. pod update
問題6. 編輯報(bào)錯(cuò) This project contains no schemes
解決方案
這里我們不能去Jenkins項(xiàng)目目錄下修改Xcode項(xiàng)目的shared勾選榨咐,我們應(yīng)該在本地的開發(fā)源碼上修改介却,然后提交到git遠(yuǎn)程倉(cāng)庫(kù),再次構(gòu)建?樽隆齿坷!
問題7. 編輯報(bào)錯(cuò) `xcodebuild -exportArchive -archivePath /xxx.xcarchive -exportOptionsPlist /Users/xxx/ExportOptions.plist -allowProvisioningUpdates -exportPath ./
error: archive not found at path '/xxx.xcarchive' Build step 'Execute shell' marked build as failure`
解決方案
用腳本構(gòu)建時(shí)桂肌,腳本輸寫錯(cuò)誤
問題8. 編輯報(bào)錯(cuò) error: archive not found at path '/Users/plz/Desktop/Jenkins/HIGO/Archive/HIGO_20210122-15-43-31.xcarchive'
查看日志發(fā)現(xiàn)在執(zhí)行
pod install
時(shí)中斷了,引入的三方庫(kù)沒有拉下來
解決方案
按照日志提示 shell 腳本 pod install 前執(zhí)行 pod update PLPlayerKit --no-repo-update
參考文章
Jenkins+github+fir持續(xù)集成iOS項(xiàng)目
iOS: Jenkins + xcodebuild打包ipa + 上傳蒲公英