透過 Jenkins 從 Gitlab 拉 Source 自動建置 Xamarin iOS Mobile App

公司中許多的專案都有 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.

多重 SSH Keys 與 Github 帳號

JSch连接SSH问题Exception:Algorithm negotiation fail

代码签名探析

iOS Code Signing 学习笔记

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^