使用現(xiàn)有的證書創(chuàng)建/修改fastlane match證書庫

使用fastlane的match工具可以非常方便地管理iOS項(xiàng)目的證書和provisioning profile。
match可以全自動地創(chuàng)建證書。但有些情況下,需要使用已有的證書來生成provisioning profile。

  • 比如項(xiàng)目組規(guī)定不得新發(fā)行distribution證書;
  • 比如不想增加development證書的數(shù)量,同時又不想讓已分發(fā)的adhoc應(yīng)用失效這種很微妙的特殊情況。
  • 等等

(沒錯,說的都是我現(xiàn)在所在的這個麻煩的項(xiàng)目組...)

網(wǎng)上搜到了一些手動將證書及p12文件導(dǎo)入match證書庫的文章,但實(shí)際操作下來會報錯。
一頓google后,終于在fastlane文檔的角落里發(fā)現(xiàn)了官方支持的方案,將過程分享出來。

官方文檔

官方文檔在此,英文好的大佬們直接看文檔就好了。
https://docs.fastlane.tools/advanced/other/#manually-manage-the-fastlane-match-repo

實(shí)踐分享

0. 用半途而廢的個人項(xiàng)目做實(shí)驗(yàn)

  • 使用rbenv限定local的ruby版本
  • 使用bundler來管理gems (fastlane, cocoapods)
項(xiàng)目文件夾

1. 獲取cert id

首先我們需要對象證書的cert id,可以利用spaceship來獲取。
將下述代碼保存為{任意文件名}.rb文件,在Spaceship.login()處改為自己的開發(fā)者賬號。

require 'spaceship'

Spaceship.login('{開發(fā)者賬號your_developer_account@address.com}')
Spaceship.select_team

Spaceship.certificate.all.each do |cert| 
  cert_type = Spaceship::Portal::Certificate::CERTIFICATE_TYPE_IDS[cert.type_display_id].to_s.split("::")[-1]
  puts "Cert id: #{cert.id}, name: #{cert.name}, expires: #{cert.expires}, type: #{cert_type}"
end

打開終端執(zhí)行ruby {任意文件名}.rb,然后比較證書的失效時期,找到我們需要使用的證書的cert id。

獲取cert id

2. 導(dǎo)出.cer和.p12文件

從keychain中找到對象證書,導(dǎo)出.cer及.p12文件。
注意.p12文件導(dǎo)出時不要設(shè)置密碼。match不支持導(dǎo)入設(shè)置過密碼的.p12文件。

導(dǎo)出.cer及.p12文件

文件名設(shè)為步驟1中獲取的cert id。

3. 下載并解密證書庫

終端cd到項(xiàng)目目錄下輸入bundle console進(jìn)入bundle控制臺

$ bundle console
irb(main):001:0>

按下述所示,設(shè)置證書庫url,分支branch,以及match密碼。
match密碼在match下載證書時需要用到,match會將其保存在keychain中。
在keychain中搜索match會發(fā)現(xiàn)match_{證書庫url}的密碼項(xiàng),需要時發(fā)給項(xiàng)目組其他成員。
一個證書庫對應(yīng)一個match密碼

irb(main):001:0> require 'match'
irb(main):002:0> git_url = 'https://github.com/fastlane/example-certificate-repo'
=> "https://github.com/fastlane/example-certificate-repo"
irb(main):003:0> shallow_clone = false
=> false
irb(main):004:0> ENV["MATCH_PASSWORD"] = 'example-password'
=> "example-password"
irb(main):005:0> branch = 'master'
=> "master"

然后依次執(zhí)行以下操作,下載并解密證書庫。

irb(main):006:0> storage = Match::Storage.for_mode("git", { git_url: git_url, shallow_clone: shallow_clone, git_branch: branch, clone_branch_directly: false})
irb(main):007:0> storage.download
irb(main):008:0> encryption = Match::Encryption.for_storage_mode("git", { git_url: git_url, working_directory: storage.working_directory})
irb(main):009:0> encryption.decrypt_files
[14:24:42]: ??  Successfully decrypted certificates repo
irb(main):010:0> storage.working_directory
=> "/var/folders/ql/4rgq9x7j51n_971xb332w9lc0000gn/T/d20181105-65220-1oalh6v"

末行的目錄即是下載后解密得到的證書庫本地目錄

#關(guān)于證書庫和分支

fastlane推薦的實(shí)踐,是將獨(dú)自建立一個私有庫作為證書庫,每個team設(shè)一個分支存放該team的證書及provisioning profile。
實(shí)際操作可以根據(jù)項(xiàng)目的需求來設(shè)定。

本人的實(shí)際操作如下

 ~/dev/RegiQ   master ●  bundle console
[DEPRECATED] bundle console will be replaced by `bin/console` generated by `bundle gem <name>`
irb(main):001:0> require 'match'
=> true
irb(main):002:0> git_url = 'git@github.com:itsuhi-shu/RegiQ.git'
=> "git@github.com:itsuhi-shu/RegiQ.git"
irb(main):003:0> shallow_clone = false
=> false
irb(main):004:0> ENV["MATCH_PASSWORD"] = '**********************'
=> "**********************"
irb(main):005:0> branch = 'certs'
=> "certs"
irb(main):006:0> storage = Match::Storage.for_mode("git", { git_url: git_url, shallow_clone: shallow_clone, git_branch: branch, clone_branch_directly: false})
=> #<Match::Storage::GitStorage:0x00007f8d4f689758 @git_url="git@github.com:itsuhi-shu/RegiQ.git", @shallow_clone=false, @skip_docs=nil, @branch="certs", @git_full_name=nil, @git_user_email=nil, @clone_branch_directly=false, @git_basic_authorization=nil, @git_bearer_authorization=nil, @type="", @platform="">
irb(main):007:0> storage.download
[16:47:27]: Cloning remote git repo...
[16:47:27]: If cloning the repo takes too long, you can use the `clone_branch_directly` option in match.
[16:47:30]: Checking out branch certs...
=> ["git checkout --orphan certs", "git reset --hard"]
irb(main):008:0> encryption = Match::Encryption.for_storage_mode("git", { git_url: git_url, working_directory: storage.working_directory})
=> #<Match::Encryption::OpenSSL:0x00007f8d4f6c54d8 @keychain_name="git@github.com:itsuhi-shu/RegiQ.git", @working_directory="/var/folders/dj/qqssnmsn6hdgdjjcl98tj98sp6yz76/T/d20200612-9861-zkzbwg">
irb(main):009:0> encryption.decrypt_files
[16:48:19]: ??  Successfully decrypted certificates repo
=> []
irb(main):010:0> storage.working_directory
=> "/var/folders/dj/qqssnmsn6hdgdjjcl98tj98sp6yz76/T/d20200612-9861-zkzbwg"

個人習(xí)慣,直接在代碼庫下建立certs分支作為證書庫,
在log中看到,match自動為我創(chuàng)建了certs的孤兒分支,將其作為我的證書庫。

4. 添加現(xiàn)有證書并上傳

open /var/folders/*********{步驟3中證書庫目錄}打開證書庫目錄。
如果是空的可以按match的規(guī)格創(chuàng)建certs文件夾,在其下創(chuàng)建development和distribution文件夾分別儲存開發(fā)和發(fā)布用證書。

建立certs目錄并添加現(xiàn)有證書

然后進(jìn)行下述操作加密并上傳證書庫

irb(main):010:0> encryption.encrypt_files
irb(main):011:0> files_to_commit = Dir[File.join(storage.working_directory, "**", "*.{cer,p12,mobileprovision}")]
irb(main):012:0> storage.save_changes!(files_to_commit: files_to_commit)

5. 完工

在項(xiàng)目的fastlane目錄下配置Matchfile,并執(zhí)行match操作之后,fastlane會使用上傳的證書創(chuàng)建并下載provisioning profile。


證書庫

接下來只需要在項(xiàng)目文件中設(shè)置provisioning profile為match打頭的即可。大功告成!

參考

http://macoscope.com/blog/simplify-your-life-with-fastlane-match/#migration
https://docs.fastlane.tools/advanced/other/#manually-manage-the-fastlane-match-repo

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

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