Fastlane證書管理(二):match

1. 前言

match這個(gè)Tool的作用可以分為兩步

  1. 獲取合適的cert和profile
  2. 將獲取的cert和profile安裝到本機(jī)

其簡(jiǎn)單流程如下圖所示


  • 首先,從:git_url指定的git倉(cāng)庫(kù)中獲取cert和profile,如果沒有,則從AppleID賬號(hào)中獲取。
    當(dāng)從AppleID賬號(hào)中獲取cert時(shí),即使你的AppleID賬號(hào)中有創(chuàng)建好的簽名證書,match也只會(huì)嘗試去創(chuàng)建一個(gè)新的的簽名證書,如果你的AppleID賬號(hào)中簽名證書的數(shù)目已達(dá)到了2個(gè),則會(huì)創(chuàng)建失敗,然后match異常退出;
    當(dāng)從AppleID賬號(hào)中獲取profile時(shí),會(huì)強(qiáng)制創(chuàng)建一個(gè)新的來使用。具體過程可查看上一節(jié)cert和sigh。
  • match的最終目的就是把cert和profile安裝到本機(jī)
    cert被導(dǎo)入到鑰匙鏈中
    profile被安裝到xcode中

2. 內(nèi)部流程

macth特別適合在一個(gè)團(tuán)隊(duì)里面使用,在使用match時(shí),一般會(huì)先使用match創(chuàng)建一套可使用的cert和profile上傳到git倉(cāng)庫(kù)中,然后共享這個(gè)git倉(cāng)庫(kù)給團(tuán)隊(duì)的其他成員,這樣就可以一次創(chuàng)建,多次使用了。另外,macth提供了一個(gè)只讀模式,可以防止你修改AppleID賬號(hào)中或git倉(cāng)庫(kù)中的cert和profile。

2.1. 只讀模式

當(dāng):readonly的值是true時(shí),match不會(huì)訪問AppleID賬號(hào),只會(huì)從git倉(cāng)庫(kù)獲取cert和profile,并且不會(huì)修改git倉(cāng)庫(kù)。在只讀模式中,:force必須是false,否則,程序異常退出。在只讀模式中,:force_for_new_devices不會(huì)生效。

  1. 從倉(cāng)庫(kù)克隆cert和profile
    通過:git_url指定git倉(cāng)庫(kù)的地址,默認(rèn)情況是克隆master分支,可通過:git_branch指定分支。如果在同一個(gè)倉(cāng)庫(kù)中管理多個(gè)team,可使用不同的分支來存儲(chǔ)不同的team。
    克隆完畢之后,整個(gè)庫(kù)會(huì)被存儲(chǔ)在一個(gè)臨時(shí)地址中,庫(kù)的文件結(jié)構(gòu)如下圖所示
-certs
  -enterprise
    -#{cert_id}.cer
    -#{cert_id}.p12

  -development
    -#{cert_id}.cer
    -#{cert_id}.p12

  -distribution
    -#{cert_id}.cer
    -#{cert_id}.p12

-profiles
  -enterprise
    -InHouse_#{bundleID}.mobileprovision

  -appstore
    -AppStore_#{bundleID}.mobileprovision

  -adhoc
    -AdHoc_#{bundleID}.mobileprovision

  -development
    -Development_#{bundleID}.mobileprovision

上述文件結(jié)構(gòu)列出了certs/profiles/目錄中所有可能的子目錄,具體使用哪個(gè)子目錄,則是由:type指定,比如在使用企業(yè)賬號(hào)時(shí),且:type等于enterprise,則certs目錄下會(huì)有一個(gè)enterprise子文件夾。
cert和profile文件的命名必須按照上述格式,否則match會(huì)識(shí)別不出來。

:type與子目錄名對(duì)照表

type certs/下子目錄名 profiles/下子目錄名
enterprise enterprise enterprise
appstore distribution appstore
adhoc distribution adhoc
development development development

倉(cāng)庫(kù)中存儲(chǔ)的cert和profile文件都被OpenSSL加密過,所以克隆下來之后的第一件事就是解密,這時(shí)match需要一個(gè)密碼用來解密,可以通過環(huán)境變量MATCH_PASSWORD來指定,如果沒有指定,則match會(huì)嘗試去鑰匙鏈的密碼列表中尋找名稱為match_#{:git_url}的鑰匙串項(xiàng),如果仍然沒有,則需要用戶手動(dòng)輸入。在CI環(huán)境中,最好事先使用環(huán)境變量MATCH_PASSWORD設(shè)置好。

match使用類似下列終端命令的代碼來加解密

#加密
openssl aes-256-cbc -k "<password>" -in "<fileYouWantToEncryptPath>" -out "<encryptedFilePath>" -a -e
#解密
openssl aes-256-cbc -k "<password>" -in "<fileYouWantToDecryptPath>" -out "<decryptedFilePath>" -a -d

如果cert和profile已創(chuàng)建好,可以使用上述命令加密下載的cert和profile,然后上傳到git倉(cāng)庫(kù)。

  1. 獲取bundleIDs
    通過:app_identifier來指定bundleID,如果有多個(gè)bundleID,可以通過逗號(hào)分隔。
    git倉(cāng)庫(kù)的同一個(gè)分支中,可以存放多個(gè)app的profile,因?yàn)閜rofile文件名中帶有bundleID,所以可以通過文件名來區(qū)分不同的app的profile。

  2. 從倉(cāng)庫(kù)獲取cert
    首先,根據(jù):type指定的類型,假設(shè)其值為enterprise,則match遍歷倉(cāng)庫(kù)的/certs/enterprise/目錄下的所有文件,將文件名符合*.cer格式的最后一個(gè)當(dāng)做簽名證書,將文件名符合*.p12格式的最后一個(gè)當(dāng)做其對(duì)應(yīng)私鑰。
    3.1 如果簽名證書和其私鑰都存在,則將簽名證書的文件名去掉擴(kuò)展名,剩余部分作為此證書的id。
    3.2 如果簽名證書或其私鑰不存在,則異常退出。
    (其詳細(xì)流程可查看本文的第3小節(jié))

  3. 安裝證書到鑰匙鏈
    match使用如下命令將[步驟3]中獲取的證書和其私鑰分別安裝到鑰匙鏈中

# certificate_path 表示要導(dǎo)入證書的路徑
# keychain_path 表示鑰匙鏈的路徑,一般是`~/Library/Keychains/login.keychain-db`
# certificate_password 表示證書的密碼,默認(rèn)是空字符串,通過`cert`創(chuàng)建的證書的密碼為空
# -T usr/bin/codesign 表示使用`usr/bin/codesign`訪問這個(gè)證書的時(shí)候不需要授權(quán),也就是不需要輸入鑰匙鏈的密碼,使用xcodebuild打包app的使用會(huì)使用這個(gè)命令
security import certificate_path -k keychain_path -P certificate_password -T /usr/bin/codesign -T /usr/bin/security
  1. 從倉(cāng)庫(kù)獲取profile
    和[步驟3]類似,首先,根據(jù):type指定的類型,假設(shè)其值為enterprise,則match遍歷倉(cāng)庫(kù)的/profiles/enterprise/目錄下的所有文件,將文件名符合InHouse_#{bundleID}.mobileprovision格式的最后一個(gè)作為要使用的profile。
    5.1 profile存在,則執(zhí)行[步驟6]
    5.2 profile不存在,則異常退出。
    (其詳細(xì)流程可查看本文的第4小節(jié))

  2. 安裝profile到xcode
    將[步驟5]中獲取的profile文件復(fù)制到~/Library/MobileDevice/Provisioning Profiles/目錄下,文件名為#{uuid}.mobileprovision,其中uuid是profile的uuid

  3. 然后正常退出

注意,在獲取cert和其私鑰時(shí),match只是粗略的通過文件擴(kuò)展名來做篩選,并沒有驗(yàn)證證書和其私鑰是否是一一對(duì)應(yīng)的,所以不要把兩套cert放在同一個(gè)子目錄下。同理,在獲取profile時(shí),也沒有驗(yàn)證cert和profile中關(guān)聯(lián)的cert是否是同一個(gè)簽名證書。所以可能出現(xiàn)一種情況,macth執(zhí)行成功,但是app打包不成功。當(dāng)然,如果你沒有手動(dòng)修改git倉(cāng)庫(kù),只通過match來創(chuàng)建和更新,則不會(huì)出現(xiàn)這種情況。

2.2 非只讀模式

當(dāng):readonly的值是false時(shí),如果git倉(cāng)庫(kù)中沒有找到可用的cert和profile,則match會(huì)從AppleID賬號(hào)中創(chuàng)建新的。

  1. 從倉(cāng)庫(kù)克隆cert和profile

  2. 登錄AppleID和選擇teamID

  3. 檢測(cè)type
    當(dāng):type的值是enterprise,但你使用的AppleID賬號(hào)不是一個(gè)企業(yè)賬號(hào)時(shí),異常退出。

  4. 獲取bundleIDs

  5. 檢測(cè)bundleIDs的可用性
    遍歷bundleIDs,如果在AppleID賬號(hào)中不存在對(duì)應(yīng)App ID,則異常退出,只要有一個(gè)不存在就會(huì)異常退出。

  6. 獲取cert
    首先嘗試從git倉(cāng)庫(kù)獲取cert,其具體流程和[2.1節(jié)的步驟3]完全一樣,如果git倉(cāng)庫(kù)中沒有,則嘗試從AppleID賬號(hào)中創(chuàng)建一個(gè)新的簽名證書。
    為了實(shí)現(xiàn)創(chuàng)建新的證書這一功能,match調(diào)用了cert這個(gè)Tool,并設(shè)置cert:force參數(shù)的值為true來強(qiáng)制創(chuàng)建,而不管本地鑰匙鏈中是否存在cert。如果創(chuàng)建成功,則下載創(chuàng)建的cert和其對(duì)應(yīng)私鑰到git倉(cāng)庫(kù)的子目錄certs/cert_type中。
    (調(diào)用cert的詳細(xì)流程可查看cert和sigh,本步驟的詳細(xì)流程可查看本文的第3小節(jié))

  7. 安裝cert到鑰匙鏈

  8. 檢測(cè)cert可用性
    檢測(cè)在[步驟6]中獲取的cert是否存在于AppleID賬號(hào)中,具體而言就是比較cert和AppleID賬號(hào)中獲取的cert的唯一標(biāo)識(shí)符是否一致。
    從步驟6可知,有兩個(gè)途徑獲取cert,git倉(cāng)庫(kù)和AppleID賬號(hào)。從AppID賬號(hào)中下載的cert肯定是沒問題的,這一步主要是驗(yàn)證從git倉(cāng)庫(kù)中得到的cert的唯一標(biāo)識(shí)符的可用性。上文中有提到,在git倉(cāng)庫(kù)中獲取的cert的唯一標(biāo)識(shí)符就是這個(gè)cert去掉了擴(kuò)展名之后的文件名。

  9. 獲取profile
    和[步驟6]類似,首先嘗試從git倉(cāng)庫(kù)獲取profile,如果git倉(cāng)庫(kù)中沒有,則嘗試從AppleID賬號(hào)中創(chuàng)建一個(gè)新的profile。
    假設(shè):type的值為enterprise,從git倉(cāng)庫(kù)中獲取profile的具體流程是,遍歷倉(cāng)庫(kù)中/profiles/enterprise/目錄下的所有文件名符合InHouse_#{bundleID}.mobileprovision格式的profile文件,如果這個(gè)profile存在于AppleID賬號(hào)中,則返回這個(gè)profile。
    為了實(shí)現(xiàn)創(chuàng)建新的profile這一功能,match調(diào)用了sigh這個(gè)Tool,并設(shè)置sigh:force參數(shù)的值為true來強(qiáng)制創(chuàng)建,而不管AppleID賬號(hào)中是否已存在profile。同時(shí),也指定了sigh:cert_id參數(shù)的值為[步驟6]中獲取的cert的唯一標(biāo)識(shí)符。
    (調(diào)用sigh的詳細(xì)流程可查看cert和sigh,本步驟的詳細(xì)流程可查看本文的第4小節(jié))

  10. 安裝profile到xcode

  11. 提交cert和profile到倉(cāng)庫(kù)
    如果在[步驟6]創(chuàng)建了新的cert或在[步驟9]中創(chuàng)建新的profile,則需要將這些新創(chuàng)建的文件添加到倉(cāng)庫(kù),并推送的遠(yuǎn)程倉(cāng)庫(kù)中。

3. 獲取cert

下圖是獲取cert的詳細(xì)執(zhí)行流程


3. 獲取profile

下圖是獲取profile的詳細(xì)執(zhí)行流程


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 前言 cert、sigh和match是Fastlane中的三個(gè)Tool,他們都是與證書相關(guān)的工具。cert的...
    wangzzzzz閱讀 8,507評(píng)論 3 18
  • fastlane運(yùn)行所需要的環(huán)境: OS X 10.9以上 Ruby 2.0 以上 Xcode 擁有一個(gè)開發(fā)者賬號(hào)...
    阿姣_0405閱讀 3,271評(píng)論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,697評(píng)論 19 139
  • 前言 團(tuán)隊(duì)開發(fā)中,經(jīng)常會(huì)遇到新成員加入或者證書及配置文件的變更,此時(shí)往往會(huì)造成一堆證書/pp文件失效問題,故我們可...
    肥貓記閱讀 7,817評(píng)論 0 10
  • 引言關(guān)于開發(fā)證書配置(Certificates & Identifiers & Provisioning Prof...
    molake閱讀 48,910評(píng)論 7 62

友情鏈接更多精彩內(nèi)容