1. 前言
match
這個Tool的作用可以分為兩步
- 獲取合適的cert和profile
- 將獲取的cert和profile安裝到本機(jī)
其簡單流程如下圖所示
- 首先,從
:git_url
指定的git倉庫中獲取cert和profile痕届,如果沒有弧岳,則從AppleID賬號中獲取寝姿。
當(dāng)從AppleID賬號中獲取cert時嗡综,即使你的AppleID賬號中有創(chuàng)建好的簽名證書簇捍,match
也只會嘗試去創(chuàng)建一個新的的簽名證書只壳,如果你的AppleID賬號中簽名證書的數(shù)目已達(dá)到了2個,則會創(chuàng)建失敗暑塑,然后match
異常退出吼句;
當(dāng)從AppleID賬號中獲取profile時,會強(qiáng)制創(chuàng)建一個新的來使用事格。具體過程可查看上一節(jié)cert和sigh惕艳。 -
match
的最終目的就是把cert和profile安裝到本機(jī)
cert被導(dǎo)入到鑰匙鏈中
profile被安裝到xcode中
2. 內(nèi)部流程
macth
特別適合在一個團(tuán)隊里面使用,在使用match
時驹愚,一般會先使用match
創(chuàng)建一套可使用的cert和profile上傳到git倉庫中远搪,然后共享這個git倉庫給團(tuán)隊的其他成員,這樣就可以一次創(chuàng)建逢捺,多次使用了谁鳍。另外,macth
提供了一個只讀模式劫瞳,可以防止你修改AppleID賬號中或git倉庫中的cert和profile倘潜。
2.1. 只讀模式
當(dāng):readonly
的值是true時,match不會訪問AppleID賬號志于,只會從git倉庫獲取cert和profile涮因,并且不會修改git倉庫。在只讀模式中伺绽,:force
必須是false养泡,否則嗜湃,程序異常退出。在只讀模式中澜掩,:force_for_new_devices
不會生效净蚤。
- 從倉庫克隆cert和profile
通過:git_url
指定git倉庫的地址,默認(rèn)情況是克隆master分支输硝,可通過:git_branch
指定分支今瀑。如果在同一個倉庫中管理多個team,可使用不同的分支來存儲不同的team点把。
克隆完畢之后橘荠,整個庫會被存儲在一個臨時地址中,庫的文件結(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/
目錄中所有可能的子目錄郎逃,具體使用哪個子目錄哥童,則是由:type
指定,比如在使用企業(yè)賬號時褒翰,且:type
等于enterprise
贮懈,則certs目錄下會有一個enterprise子文件夾。
cert和profile文件的命名必須按照上述格式优训,否則match會識別不出來朵你。
:type
與子目錄名對照表
type | certs/下子目錄名 | profiles/下子目錄名 |
---|---|---|
enterprise | enterprise | enterprise |
appstore | distribution | appstore |
adhoc | distribution | adhoc |
development | development | development |
倉庫中存儲的cert和profile文件都被OpenSSL加密過,所以克隆下來之后的第一件事就是解密揣非,這時match需要一個密碼用來解密抡医,可以通過環(huán)境變量MATCH_PASSWORD
來指定,如果沒有指定早敬,則match會嘗試去鑰匙鏈的密碼列表中尋找名稱為match_#{:git_url}
的鑰匙串項(xià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倉庫。
獲取bundleIDs
通過:app_identifier
來指定bundleID棍矛,如果有多個bundleID安疗,可以通過逗號分隔。
git倉庫的同一個分支中够委,可以存放多個app的profile荐类,因?yàn)閜rofile文件名中帶有bundleID,所以可以通過文件名來區(qū)分不同的app的profile茁帽。從倉庫獲取cert
首先玉罐,根據(jù):type
指定的類型屈嗤,假設(shè)其值為enterprise
,則match
遍歷倉庫的/certs/enterprise/
目錄下的所有文件吊输,將文件名符合*.cer
格式的最后一個當(dāng)做簽名證書饶号,將文件名符合*.p12
格式的最后一個當(dāng)做其對應(yīng)私鑰。
3.1 如果簽名證書和其私鑰都存在季蚂,則將簽名證書的文件名去掉擴(kuò)展名茫船,剩余部分作為此證書的id。
3.2 如果簽名證書或其私鑰不存在扭屁,則異常退出算谈。
(其詳細(xì)流程可查看本文的第3小節(jié))安裝證書到鑰匙鏈
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`訪問這個證書的時候不需要授權(quán),也就是不需要輸入鑰匙鏈的密碼葵腹,使用xcodebuild打包app的使用會使用這個命令
security import certificate_path -k keychain_path -P certificate_password -T /usr/bin/codesign -T /usr/bin/security
從倉庫獲取profile
和[步驟3]類似高每,首先,根據(jù):type
指定的類型践宴,假設(shè)其值為enterprise
鲸匿,則match
遍歷倉庫的/profiles/enterprise/
目錄下的所有文件,將文件名符合InHouse_#{bundleID}.mobileprovision
格式的最后一個作為要使用的profile浴井。
5.1 profile存在晒骇,則執(zhí)行[步驟6]
5.2 profile不存在,則異常退出磺浙。
(其詳細(xì)流程可查看本文的第4小節(jié))安裝profile到xcode
將[步驟5]中獲取的profile文件復(fù)制到~/Library/MobileDevice/Provisioning Profiles/
目錄下,文件名為#{uuid}.mobileprovision
徒坡,其中uuid
是profile的uuid然后正常退出
注意撕氧,在獲取cert和其私鑰時,match
只是粗略的通過文件擴(kuò)展名來做篩選喇完,并沒有驗(yàn)證證書和其私鑰是否是一一對應(yīng)的伦泥,所以不要把兩套cert放在同一個子目錄下。同理锦溪,在獲取profile時不脯,也沒有驗(yàn)證cert和profile中關(guān)聯(lián)的cert是否是同一個簽名證書。所以可能出現(xiàn)一種情況刻诊,macth
執(zhí)行成功防楷,但是app打包不成功。當(dāng)然则涯,如果你沒有手動修改git倉庫复局,只通過match
來創(chuàng)建和更新冲簿,則不會出現(xiàn)這種情況。
2.2 非只讀模式
當(dāng):readonly
的值是false時亿昏,如果git倉庫中沒有找到可用的cert和profile峦剔,則match
會從AppleID賬號中創(chuàng)建新的。
從倉庫克隆cert和profile
登錄AppleID和選擇teamID
檢測type
當(dāng):type
的值是enterprise角钩,但你使用的AppleID賬號不是一個企業(yè)賬號時吝沫,異常退出。獲取bundleIDs
檢測bundleIDs的可用性
遍歷bundleIDs递礼,如果在AppleID賬號中不存在對應(yīng)App ID野舶,則異常退出,只要有一個不存在就會異常退出宰衙。獲取cert
首先嘗試從git倉庫獲取cert平道,其具體流程和[2.1節(jié)的步驟3]完全一樣,如果git倉庫中沒有供炼,則嘗試從AppleID賬號中創(chuàng)建一個新的簽名證書一屋。
為了實(shí)現(xiàn)創(chuàng)建新的證書這一功能,match
調(diào)用了cert
這個Tool袋哼,并設(shè)置cert
的:force
參數(shù)的值為true來強(qiáng)制創(chuàng)建冀墨,而不管本地鑰匙鏈中是否存在cert。如果創(chuàng)建成功涛贯,則下載創(chuàng)建的cert和其對應(yīng)私鑰到git倉庫的子目錄certs/cert_type
中诽嘉。
(調(diào)用cert
的詳細(xì)流程可查看cert和sigh,本步驟的詳細(xì)流程可查看本文的第3小節(jié))安裝cert到鑰匙鏈
檢測cert可用性
檢測在[步驟6]中獲取的cert是否存在于AppleID賬號中弟翘,具體而言就是比較cert和AppleID賬號中獲取的cert的唯一標(biāo)識符是否一致虫腋。
從步驟6可知,有兩個途徑獲取cert稀余,git倉庫和AppleID賬號悦冀。從AppID賬號中下載的cert肯定是沒問題的,這一步主要是驗(yàn)證從git倉庫中得到的cert的唯一標(biāo)識符的可用性睛琳。上文中有提到盒蟆,在git倉庫中獲取的cert的唯一標(biāo)識符就是這個cert去掉了擴(kuò)展名之后的文件名。獲取profile
和[步驟6]類似师骗,首先嘗試從git倉庫獲取profile历等,如果git倉庫中沒有,則嘗試從AppleID賬號中創(chuàng)建一個新的profile辟癌。
假設(shè):type
的值為enterprise
寒屯,從git倉庫中獲取profile的具體流程是,遍歷倉庫中/profiles/enterprise/
目錄下的所有文件名符合InHouse_#{bundleID}.mobileprovision
格式的profile文件愿待,如果這個profile存在于AppleID賬號中浩螺,則返回這個profile靴患。
為了實(shí)現(xiàn)創(chuàng)建新的profile這一功能,match
調(diào)用了sigh
這個Tool要出,并設(shè)置sigh
的:force
參數(shù)的值為true來強(qiáng)制創(chuàng)建鸳君,而不管AppleID賬號中是否已存在profile。同時患蹂,也指定了sigh
的:cert_id
參數(shù)的值為[步驟6]中獲取的cert的唯一標(biāo)識符或颊。
(調(diào)用sigh
的詳細(xì)流程可查看cert和sigh,本步驟的詳細(xì)流程可查看本文的第4小節(jié))安裝profile到xcode
提交cert和profile到倉庫
如果在[步驟6]創(chuàng)建了新的cert或在[步驟9]中創(chuàng)建新的profile传于,則需要將這些新創(chuàng)建的文件添加到倉庫囱挑,并推送的遠(yuǎn)程倉庫中。
3. 獲取cert
下圖是獲取cert的詳細(xì)執(zhí)行流程
3. 獲取profile
下圖是獲取profile的詳細(xì)執(zhí)行流程