Daily Build 是一件很是有意義的事情,也是敏捷開發中關於 「持續集成」 的一個實踐。Daily Build 對於開發來講有以下好處:html
- 保證了每次 check in 的代碼可用,不會形成整個工程編譯失敗。
- 進度跟進。產品經理能夠天天看到最新的開發進度,而且試用產品,調整一些細節。不少時候,一個新功能,你真正用了一下才能有體會好或很差,因此 daily build 也給產品經理更多時間來調理他的設計。
- 需求確認。產品經理能夠確認開發的功能細節是他的預期。由於咱們的開發比較緊湊,因此都沒有傳統的需求說明文檔,因此 daily build 也給產品經理用於儘早確認開發的功能細節是他的預期,我就遇到一次產品經理髮現開發出的一個功能細節和他的預期不一致,可是由於有 daily build,使得我能夠儘早作修改,把修改的代價減少了。
- 測試跟進。若是功能點是獨立的話,測試同事徹底能夠根據 daily build 來進行一些早期的測試。越早的 Bug 反饋可使得修改 bug 所需的時間越短。
步驟
xcodebuild 命令
如何作 daily build 呢?其實 Xcode 就提供了命令行 build 的命令,這個命令是 xcodebuild,用 xcodebuild -usage
能夠查看到全部的可用參數,以下所示:python
[tangqiao ~]$xcodebuild -usage Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]... xcodebuild [-project <projectname>] -scheme <schemeName> [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]... xcodebuild -workspace <workspacename> -scheme <schemeName> [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]... xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ] xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] xcodebuild -showsdks
|
通常狀況下的命令使用以下:ios
xcodebuild -configuration Release -target "YourProduct"
|
但在 daily build 中,用 Release 用爲 configuration 其實不是特別好。由於 Release 的證書可能會被常常修改。咱們能夠基於 Release 的 Configuation,建一個專門用於 daily build 的 configuration。方法是:在工程詳細頁面中,選擇 Info 一欄,在 Configurations 一欄的下方點擊 「+」 號,而後選擇 「Duplicate Release Configuration」, 新建名爲 「DailyBuild」 的 Configuration, 以下圖所示:web
以後就能夠用以下命令來作 daily build 了windows
xcodebuild -configuration DailyBuild -target "YourProduct"
|
執行完命令後,會在當前工程下的 build/DailyBuild-iphoneos/ 目錄下生成一個名爲: YourProduct.app 的文件。這個就是咱們 Build 成功以後的程序文件。xcode
生成 ipa 文件
接下來咱們須要生成 ipa 文件,在生成 ipa 文件這件事情上,xcode 彷佛沒有提供什麼工具,不過這個沒什麼影響,由於 ipa 文件實際上就是一個 zip 文件,咱們使用系統的 zip 命令來生成 ipa 文件便可。須要注意的是,ipa 文件並非簡單地將編輯好的 app 文件打成 zip 文件,它須要將 app 文件放在一個名爲 Payload 的文件夾下,而後將整個 Payload 目錄打包成爲 .ipa 文件,命令以下:bash
cd $BUILD_PATH mkdir -p ipa/Payload cp -r ./DailyBuild-iphoneos/$PRODUCT_NAME ./ipa/Payload/ cd ipa zip -r $FILE_NAME *
|
生成安裝文件
蘋果容許用 itms-services 協議來直接在 iphone/ipad 上安裝應用程序,咱們能夠直接生成該協議須要的相關文件,這樣產品經理和測試同窗均可以直接在設備上安裝新版的應用了。相關的參考資料能夠見:這裏 和 這裏服務器
具體來講,就是須要生成一個帶 itms-services 協議的連接的 html 文件,以及一個 plist 文件。app
生成 html 的示例代碼以下:less
cat << EOF > install.html <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title> 安裝此軟件 </title> </head> <body> <ul> <li> 安裝此軟件:<a href="itms-services://?action=download-manifest&url=http%3A%2F%2Fwww.yourdomain.com%2Fynote.plist">$FILE_NAME</a></li> </ul> </div> </body> </html> EOF
|
生成 plist 文件的代碼以下,注意,須要將下面的涉及 www.yourdomain.com 的地方換成你線上服務器的地址,將 ProductName 換成你的 app 安裝後的名字。
cat << EOF > ynote.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>items</key> <array> <dict> <key>assets</key> <array> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <string>http://www.yourdomain.com/$FILE_NAME</string> </dict> <dict> <key>kind</key> <string>display-image</string> <key>needs-shine</key> <true/> <key>url</key> <string>http://www.yourdomain.com/icon.png</string> </dict> <dict> <key>kind</key> <string>full-size-image</string> <key>needs-shine</key> <true/> <key>url</key> <string>http://www.yourdomain.com/icon.png</string> </dict> </array><key>metadata</key> <dict> <key>bundle-identifier</key> <string>com.yourdomain.productname</string> <key>bundle-version</key> <string>1.0.0</string> <key>kind</key> <string>software</string> <key>subtitle</key> <string>ProductName</string> <key>title</key> <string>ProductName</string> </dict> </dict> </array> </dict> </plist>
EOF
|
定時運行
這一點很是簡單,使用 crontab -e 命令便可。你們能夠隨意 google 一下 crontab 命令,能夠找到不少相關文檔。假如咱們要每週 1-5 的早上 9 點鐘執行 daily build,則 crontab 的配置以下:
0 9 * * * 1-5 /Users/tangqiao/dailybuild.sh >> /Users/tangqiao/dailybuild.log 2>&1
|
失敗報警
在 daily build 腳本運行失敗時,最好能發報警郵件或者短信,以便可以儘早發現。發郵件能夠用 python 的 smtplib 來寫,示例以下:
import smtplib
sender = 'sender@devtang.com' receivers = ['receiver@devtang.com']
message = """From: Alert <sender@devtang.com> To: Some one <receiver@devtang.com> Subject: SMTP email sample
Hope you can get it. """
try: obj = smtplib.SMTP('server.mail.devtang.com') obj.sendmail(sender, receivers, message) print 'OK: send mail succeed' except Exception: print 'Error: unable to send mail'
|
上傳
daily build 編譯出來若是須要單獨上傳到另一臺 web 機器上,能夠用 ftp 或者 scp 協議。若是 web 機器悲劇的是 windows 機器的話,能夠在 windows 機器上開一個共享,而後用 mount -t smbfs 來將這個共享 mount 到本地,相關的示例代碼以下:
mkdir upload mount -t smbfs //$SMB_USERNAME:$SMB_PASSWORD@$SMB_TARGET ./upload if [ "$?" -ne 0 ]; then echo "Failed to mount smb directory" exit 1 fi mkdir ./upload/$FOLDER cp $FILE_NAME ./upload/$FOLDER/ if [ "$?" -eq 0 ]; then echo "[OK] $FILE_NAME is uploaded to $SMB_TARGET" else echo "[ERROR] $FILE_NAME is FAILED to uploaded to $SMB_TARGET" fi umount ./upload
|
遇到的問題
原本我寫的自動化腳本在 Mac OS X 10.6 下運行得很好。可是升級到 lion 後,腳本在手動執行時很正常,可是在用 crontab 啓動時就會出現找不到開發者證書的錯誤。在網上搜了好久也沒有找到解決辦法。最後我試了一下在 「鑰匙串訪問」 中把開發者證書從 「登陸」 那欄拖動到 「系統」 那欄,竟然就解決了,以下圖所示:
另外我搜到 2 個相似的問題的解決方案,雖然對我這個沒起做用,也一併放在這兒,或許對遇到相似問題的人有幫助:
總結
將以上各點結合起來,就能夠用 bash 寫出一個 daily build 腳本了。天天這一切都會自動完成,心情至關好。