公司中許多的專案都有 Auto Build 的機制,那 Mobile App 也有 Auto Build 的機制嗎?
ios 的 App 需要 Mac 的環境。本文將介紹如何透過 Jenkins 從 Gitlab 拉 Source 自動建置 Xamarin iOS Mobile App。
架構
Mac 環境建置
1.安裝所需憑證,我們公司是使用 Enterprise Store ,如下,
2.安裝 Visual Studio 2017 for mac
註:如果在建置時,有發生 csc.exe exited with code 1 的錯誤,可以參考「Visual Studio for Mac "csc.exe exited with code 1" when building Xamarin.iOS project.」,從下載舊版的 Mono 4.8.1.0 ,重啟OS後,再用 Xamarin Studio 去建置。
3.安裝 Git ,因為要從 Gitlab 拉 Source 下來。
4.驗證專案是否可以正常建置並發佈 ipa 。
SSH Command 測試
當透過 IDE 工具可正常建置並發佈後,就可以透過 SSH 去拉原始碼下來為建置及發行。
1.先透過 ssh 登入到 Mac (windows 請用 putty.exe)
2.從 Gitlab 將 Source Clone 到 Local
想要不用再輸入密碼從Gitlab clone 下來可以使用
git clone https://username:password@remote folderName;
或是
git clone git@remot folderName;
我們選擇後面這種方式(因為http方式,密碼是明碼,而且密碼有特殊字元,也不行),詳細可以參考(多重 SSH Keys 與 Github 帳號)。
2.1.所以我們就來建立 sshkey (可以 -C 設定檔案名稱), 如下,
cd ~/.ssh;
ssh-keygen -t rsa -b 4096;
2.2.將 .pub 檔案內容(public key) 新增到 Gitlab 之中(profile/keys),如下,
2.3.建立 ~/.ssh/config (vim ~/.ssh/config),
#公司工作用的 GitHub 帳號
Host gss
HostName 655git.655.com.tw(這裡可用ip or fqdn)
User rainmaker
IdentityFile ~/.ssh/id_rsa
2.4.將 Source 從 Gitlab 拉下來(@gss,就是對應到 .ssh/config 中的 Host ),
git clone git@gss:BeaconSystem/iBeep-iOS.git iBeep-iOS;
3.透過 xbuild 來建置產生 ipk 檔案
切換到專案的目錄,輸入 xbuild 來建置,如下,
xbuild /p:Configuration=Release /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true
這時會發生 codesign FAILED 的問題,訊息如下,
Codesign Task
CodesignAllocate: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
DisableTimestamp: False
Entitlements: obj/iPhone/Release/Entitlements.xcent
Keychain: <null>
Resources:
bin/iPhone/Release/GSS_Beacon.app
ResourceRules: <null>
SigningKey: 23A1BADAF10F41
ExtraArgs: <null>
IsAppExtension: False
Tool /usr/bin/codesign execution started with arguments: -v --force --sign 23A1BADAF10F --entitlements /Users/gsstds/iBeep-iOS/obj/iPhone/Release/Entitlements.xcent /Users/gsstds/iBeep-iOS/bin/iPhone/Release/GSS_Beacon.app
bin/iPhone/Release/GSS_Beacon.app: error : /Users/gsstds/iBeep-iOS/bin/iPhone/Release/GSS_Beacon.app: unknown error -1=ffffffffffffffff
Task "Codesign" execution – FAILED
直接拿 xbuild 中的 codesign 去 sing app 檔,還是一樣的錯誤,如下,
透過 codesign -vv -d 會發現 app 檔並沒有被 sign 成功,如下,
這個是因為透過 ssh 連進去時,Keychain 被 lock 了,所以需要再 unlock ,請下以下的 command
security -v unlock-keychain -p <<登入者的密碼>> ~/Library/Keychains/login.keychain;
再將 bin 目錄似 obj 目錄刪掉,重新再 run 一次 xbuild 就可以正常產出 ipa 檔了。
我們可以在專案目錄下新增一個 ipa 的Folder來放建置完成的 ipa 檔,如下,
mkdir ipa;
xbuild /p:Configuration=Release /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true /p:IpaPackageDir=./ipa/;
透過 Jenkins 來執行 SSH Command
所以透過 ssh 來建置 ios 的 command 如下(透過 Jenkins 使用 nuget, xbuild 需要輸入 full path),
rm -rf ~/iBeep-iOS;
git clone git@gss:BeaconSystem/iBeep-iOS.git iBeep-iOS;
cd iBeep-iOS;
/Library/Frameworks/Mono.framework/Commands/nuget restore;
mkdir ipa;
security -v unlock-keychain -p <<登入者的密碼>> ~/Library/Keychains/login.keychain;
/Library/Frameworks/Mono.framework/Commands/xbuild /p:Configuration=Release /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true /p:IpaPackageDir=./ipa/;
其中 security unlock-keychain 需要密碼,所以可以設定在 Jenkins Job 「建置環境」中的 Inject passwords to the build as environment variables ,如下,
所以 Jenkins ssh 那就可以使用到它 ${keychainPW}
rm -rf ~/iBeep-iOS;
git clone git@gss:BeaconSystem/iBeep-iOS.git iBeep-iOS;
cd iBeep-iOS;
/Library/Frameworks/Mono.framework/Commands/nuget restore;
mkdir ipa;
security -v unlock-keychain -p ${keychainPW} ~/Library/Keychains/login.keychain;
/Library/Frameworks/Mono.framework/Commands/xbuild /p:Configuration=Release /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true /p:IpaPackageDir=./ipa/;
另外,如果透過 Jenkins 連進去有 Algorithm negotiation fail 的錯誤,可依以這篇(JSch连接SSH问题Exception:Algorithm negotiation fail)去設定哦!
註:雖然 Command 沒幾行,但是卡在 codesign 那卻卡了很久,能順利完成,非常感謝 ISBG 的 Henry Kuo 、 Alice 及 QAC 的 Nita ^_^
參考資料
Visual Studio for Mac "csc.exe exited with code 1" when building Xamarin.iOS project.
JSch连接SSH问题Exception:Algorithm negotiation fail
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^