iOS 自動打包并上傳蒲公英附Jenkins - 最新 2020-8-27

生活中不止有茍且,還有代碼和打包

前言

開發一段時間,每次在測試上線階段,你會發現有一種酸楚感,因為你即將開始一項沒有任何技術含量的build,archive,export的過程,這時候是最累的時候,如果你們的測試很敬業,給你一點點的提bug,那么你將面臨的一次接一次的build,archive,export的過程,還有上傳第三方分發平臺,這個酸爽感??。。。。有人說不用啊,直接插我電腦上給裝一下就行了,而且現在Xcode還有無線調試了,都不用到我跟前來了,直接給安裝了。當然小團隊開發這種模式肯定是沒任何毛病的,但當你公司有好幾個測試,一個個讓你給安裝最新版本,是不是還是挺煩的!而且你可能還有這樣一個困窘,當測試給你提多個bug 的時候,你改著改著等你上線的時候,你還擔心這個提交的包到底是不是最新的版本打的包,心里多少有點害怕出錯,這時候這篇文章可以解決你所有的擔心以及減輕你所有的工作量,如果你說這個情況也不存在,那你可以關閉這個網頁尋找你感興趣的文章了。

正文

要徹底明白這個打包的過程我們還需要了解以下幾個概念

1.Workspace、Project、Scheme、Target的區別

官方文檔中對這個有明確的解釋

Xcode Workspace:一個工作空間包括多個projects

A workspace is an Xcode document that groups projects and other documents so you can work on them together. 
A workspace can contain any number of Xcode projects, plus any other files you want to include. 
In addition to organizing all the files in each Xcode project, a workspace provides implicit and explicit relationships among the included projects and their targets.

Xcode Target:多個Target可以組成一個project,說白了就是一個依賴

A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. 
A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product.
 Projects can contain one or more targets, each of which produces one product.

Xcode Project:一個project就是一個項目,可以包含多個targets,而通過 build settings來定義如何build.

An Xcode project is a repository for all the files, resources, and information required to build one or more software products.
 A project contains all the elements used to build your products and maintains the relationships between those elements. 
It contains one or more targets, which specify how to build products. 
A project defines default build settings for all the targets in the project (each target can also specify its own build settings, which override the project build settings).

Xcode Scheme:scheme是來定義一系列targets來build
一個scheme只能應用于一個workspace。

An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.
You can have as many schemes as you want, but only one can be active at a time. 
You can specify whether a scheme should be stored in a project—in which case it’s available in every workspace that includes that project, or in the workspace—in which case it’s available only in that workspace.
 When you select an active scheme, you also select a run destination (that is, the architecture of the hardware for which the products are built).
  • Workspace:簡單來說,Workspace就是一個容器,在該容器中可以存放多個你創建的Xcode Project, 以及其他的項目中需要使用到的文件。使用Workspace的好處有,1),擴展項目的可視域,即可以在多個項目之間跳轉,重構,一個項目可以使用另一個項目的輸出。Workspace會負責各個Project之間提供各種相互依賴的關系;2),多個項目之間共享Build目錄。

  • Project:指一個項目,該項目會負責管理生成一個或者多個軟件產品的全部文件和配置,一個Project可以包含多個Target。

  • Target:一個Target是指在一個Project中構建的一個產品,它包含了構建該產品的所有文件,以及如何構建該產品的配置。

  • Scheme:一個定義好構建過程的Target成為一個Scheme。可在Scheme中定義的Target的構建過程有 Build/Run/Test/Profile/Analyze/Archive

  • BuildSetting:配置產品的Build設置,比方說,使用哪個Architectures?使用哪個版本的SDK?。在Xcode Project中,有Project級別的Build Setting,也有Target級別的Build Setting。Build一個產品時一定是針對某個Target的,因此,XCode中總是優先選擇Target的Build Setting,如果Target沒有配置,則會使用Project的Build Setting。

2.build -> archive -> export 到底干了什么

平時開發中我們很輕易的點擊了 command + B 執行了一次build的過程 ,其實對Xcode 來發你給他下發了一條指令,我們可以將編譯過后的右紅變黑的 項目名.app 點擊
Show in Finder 會發現build 文件夾下產生的一系列的文件,你會發現多個tagets 被加載進來,并生成了一個 項目名.app的包,這轉換為為指令如下:

xcodebuild

我們 可以在終端執行該條命令對項目進行build,該指令還可以生成項目名.xcarchive文件,對應為我們執行選擇真機點擊archive過程,對應指令如下

WORKSPACENAME :工作區名字
SCHEMENAME : scheme名字
CONFIGURATION : release 或者 Debug
ARCHIVEPATH :文件輸入路徑, 一般為cd 路徑下拼接地址
\ : 拼接符號

  • archive
xcodebuild archive \
-workspace ${WORKSPACENAME}.xcworkspace \
-scheme ${SCHEMENAME} \
-configuration ${CONFIGURATION} \
-archivePath ${ARCHIVEPATH}

看到以上命令我們應該就豁然了,例如給應用商店上傳我們指定Release,在Xcode 8以前還需要指定描述文件以及開發者,也就是發布的描述文件,8以后都自動管理了,所以會自己去讀取,不需要我們去指定了.

最后一步便是生成 export

生成ipa包

看到這個界面大家更應該明白了export,對應指令如下:

xcodebuild -exportArchive \
-archivePath ${ARCHIVEPATH}.xcarchive \
-exportPath ${IPAPATH} \
-exportOptionsPlist ExportOptions.plist \

需要明確以下幾點:

1.Xcode 8 以后使用以上新命令,xcrun指令被廢棄了!

2.這里ARCHIVEPATH 對應的.xcarchive文件的輸出路徑,IPAPATH是ipa 輸出地址

3.ExportOptions.plist對應的已怎樣的方式輸出,相當于一個配置文件,我們需要以什么樣的方式輸出.ipa

ExportOptions.plist

對應的是以下我們手動打包的方式:

method

compileBitcode 和 stripSwiftSymbols
signingStyle

以上生成.ipa的流程我們應該明了于心了,接下來我們用shell腳本將整個流程自動化。

shell 腳本

#!/bin/bash

#workspaceName
WORKSPACENAME='xxx'
#schemeName 可以在工程根目錄下使用 xcodebuild -list 命令查看schemes 
SCHEMENAME= 'xxxx'
#(Release or Debug)
CONFIGURATION='xxxxxx '


#獲取時間,這個格式可以自己定義
DATE=`date +%Y%m%d_%H%M`
#源工程的地址,默認獲取cd 路徑下的地址
SOURCEPATH=$( cd "$( dirname $0 )" && pwd)
#archieve 輸出地址,這個路徑可以你自己定義
ARCHIVEPATH=${SOURCEPATH}/AutoBuildIPA/${BRANCHNAME}/${DATE}
#ipa 包輸出地址,這個路徑也可以你自己定義
IPAPATH=${SOURCEPATH}/AutoBuildIPA/${BRANCHNAME}/${SCHEMENAME}_${DATE}
#ipa 包名
IPANAME=${SCHEMENAME}.ipa

echo "~~~~~~~~~~~~~~~~開始清理~~~~~~~~~~~~~~~~~~~"
# 清理 避免出現一些莫名的錯誤
xcodebuild clean \
-workspace ${WORKSPACENAME}.xcworkspace \
-configuration ${CONFIGURATION}  \
-scheme ${SCHEMENAME}

echo "~~~~~~~~~~~~~~~~開始構建archive~~~~~~~~~~~~~~~~~~~"
# build xxx
xcodebuild archive \
-workspace ${WORKSPACENAME}.xcworkspace \
-scheme ${SCHEMENAME} \
-configuration ${CONFIGURATION} \
-archivePath ${ARCHIVEPATH}

#判斷 'xx.xcarchive' 文件存在,即 build 成功
if [ -e ${ARCHIVEPATH}.xcarchive ]; then
echo "xcodebuild Successful"
else
echo "erro:Build failed!!"
exit 1 #退出命令執行
fi

echo "~~~~~~~~~~~~~~~~開始輸出ipa~~~~~~~~~~~~~~~~~~~"
# xcrun xxx
xcodebuild -exportArchive \
-archivePath ${ARCHIVEPATH}.xcarchive \
-exportPath ${IPAPATH} \
-exportOptionsPlist ExportOptions.plist \

# 如果  xx.ipa 存在則輸出成功
if [ -e ${IPAPATH}/${IPANAME} ]; then
echo "\n-------------------------\n\n\n"
echo "Configurations! Build Successful!"
echo "\n\n\n-------------------------\n\n"
else
echo "\n---------------------------------------------------------------\n"
echo "erro:Create IPA failed!!"
echo "\nPlease check the case of failure and contact developers,thanks!"
echo "Export Error Path : ${IPAPATH}/${IPANAME}"
echo "\n---------------------------------------------------------------\n"
exit 1
fi

以上是便是腳本文件,直接將腳本放在項目工程同級目錄下,在終端執行 sh xxxx.sh(注:xxxx為腳本文件名),和python 腳本執行是一樣的,接下來等待即可輸出ipa包。(注:大多出錯就是路徑定義有問題,檢查路徑正確性即可排除問題)

接下來我們需要上傳蒲公英,我們可以查看官網文檔,發現很簡單的執行步驟


https://www.pgyer.com/doc/view/upload_one_command

我們可以在上述shell腳本中將這條命令添加上去

# 是否上傳蒲公英
UPLOADPGYER=false

#上傳ipa到蒲公英
if [ $UPLOADPGYER = true ]
then
echo "~~~~~~~~~~~~~~~~上傳ipa到蒲公英~~~~~~~~~~~~~~~~~~~"
#installType 是安裝類型
#password 是你設置的安裝密碼
# 上面兩個新增字段可以具體查看官方文檔
curl -F "file=@${IPAPATH}/${IPANAME}" \
-F "uKey=xxxx" \
-F "_api_key=xxxx" \
-F "installType=2" \
-F "password=1" \
https://www.pgyer.com/apiv1/app/upload --verbose

    if [ $? = 0 ]
    then
    echo "~~~~~~~~~~~~~~~~上傳蒲公英成功~~~~~~~~~~~~~~~~~~~"
    else
    echo "~~~~~~~~~~~~~~~~上傳蒲公英失敗~~~~~~~~~~~~~~~~~~~"
    echo "${IPAPATH}/${IPANAME}"
    fi
fi
fi

那么上傳 Appstore 也是相應的套路,蘋果官方提供了我們類似的方法,我們需要利用終端安裝

//安裝 xctool
brew install xctool
//查看版本
xctool -version

同樣我們可以將上傳Appstore 添加到對應的shell 腳本中

# 是否上傳到APPStore
UPLOADAPPStore=false
#對應appid
AppleID='xxx'
#pwd
AppleIDPWD='xxx'

# 上傳AppStore
#首先是驗證過程,看你appstore 對應的信息是否正確
if [ $UPLOADAPPStore = true ]
then
altoolPath="/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
${altoolPath} --validate-app \
-f ${IPAPATH}/${IPANAME} \
-u ${AppleID} \
-p ${AppleIDPWD} \
-t ios --output-format xml

#驗證成功后直接上傳
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~驗證ipa成功~~~~~~~~~~~~~~~~~~~"
${altoolPath} --upload-app \
-f ${IPAPATH}/${IPANAME} \
-u ${AppleID} \
-p ${AppleIDPWD} \
-t ios --output-format xml

if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~"
else
echo "~~~~~~~~~~~~~~~~提交AppStore失敗~~~~~~~~~~~~~~~~~~~"
fi
else
echo "~~~~~~~~~~~~~~~~驗證ipa失敗~~~~~~~~~~~~~~~~~~~"
fi

以上整個自動化過程已經完成了,接下來我們看本地jenkins 搭建,首先安裝

brew install jenkins

安裝完成等待 install,可以在終端使用

 jenkins

來啟動jenkins,然后在瀏覽器輸入框輸入

http://localhost:8080

打開Jenkins,我們然后新建項目(注:以上詳細安裝過程,以及plugin缺失問題,都可以通過百度,google方式解決,我們說具體操作)

第一步:新建項目

點擊確認

第二步:設置相關的配置

6個配置項

2.1 填寫項目相關信息

00B23356-42B1-40CE-8815-BFE7BDDACD25.png

2.2倉庫地址需要填寫到項目的根路徑那一級為止

添加用戶
設置倉庫地址

svn 和 git 是一樣的設置。

2.3 在增加構建步驟中選擇Xcode

這里我們和腳本設置是一樣的,可以類比

2.4簽名設置,填寫鑰匙串的路徑,通過該路徑Jenkins可以找到打包證書

我們是自動管理證書,通過鑰匙串可以自動找到相應的證書

2.5高級設置,Scheme同shell腳本填寫是一致的

高級設置

2.6上傳蒲公英或者App Store

Execute shell

App Store 參照腳本命令執行。

附:當提交新代碼時候設置自動打包

附加高級需求

完成以上配置,點擊保存后,點擊立即構建則會輸出同shell 腳本同樣的結果。

參照Jenkins 文章:
[0]http://blog.csdn.net/yaoliangjun306/article/details/72471429

相應配置文件的github地址
https://github.com/markdashi/shellIPA

將 package.sh 和 ExportOptions.plist 導入同級目錄下,設置好相應參數,執行腳本即可。

2020-8-27 更新

Xcode更新11之后,不再包含Application Loader。為了更好的支持ipadOS、macOS、iOS統一管理。

所以上傳AppStore的命令發生了變化

如果賬號沒有開啟雙步驗證,可以通過 -u -p 賬號密碼上傳驗證,如果開啟了,需要采取密鑰上傳

# 上傳AppStore
#首先是驗證過程,看你appstore 對應的信息是否正確
if [ $UPLOADAPPStore = true ]
then
xcrun altool --validate-app \
-f ${IPAPATH}/${IPANAME} \
-apiKey ${apiKey} \
-apiIssuer ${apiIssuer} \
-t ios --output-format xml --verbose
fi

#驗證成功后直接上傳
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~驗證ipa成功~~~~~~~~~~~~~~~~~~~"
xcrun altool --upload-app \
-f ${IPAPATH}/${IPANAME} \
-apiKey ${apiKey} \
-apiIssuer ${apiIssuer} \
-t ios --output-format xml --verbose

if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~"
else
echo "~~~~~~~~~~~~~~~~提交AppStore失敗~~~~~~~~~~~~~~~~~~~"
fi
else
echo "~~~~~~~~~~~~~~~~驗證ipa失敗~~~~~~~~~~~~~~~~~~~"
fi

apiKey apiIssuer 的獲取方式可以參照

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

推薦閱讀更多精彩內容