fastlane match でiOSアプリ開発者を「証明書管理の苦しみ」から解放せよ!

はじめまして、ビズリーチ・キャンパスでiOSアプリエンジニアをやっている河内です。
河内と書いてコウチと読みます。

今回は、iOSアプリ開発で誰もが苦しめられる証明書関連についてお話したいと思います。

はじめに

私は2012年にビズリーチに入社しました。
当時はまだ社員は100人もいなくて、アプリは1つもありませんでした。
それからビズリーチで初めてアプリを開発する段階から私は関わってきたのですが、今となっては多くの事業が立ち上がり、アプリも増えました。

現在はサービス(事業)ごとに開発チームが存在していて、そのうちアプリを持つチームが6つもあります。

iOSアプリを開発するためには、AppleのDeveloperページから証明書を作成する必要があります。
チームが増えて、これらを管理する手間が徐々に増えてきたところで、fastlane match (以下match)を導入して証明書管理の効率化を行いました。

その辺りの四苦八苦していたことについてお話できればと思います。

私達が抱えていた問題

私達は今まで手動で証明書を作成していました。管理と呼べそうなことはやっておらず、有効な証明書を持っている人から直接もらう、といった形で開発を進めていました。

そんな状態だったため、以下のような問題を抱えていました。

  • 配布用証明書が手元になくてビルドできない
  • 配布用証明書が作成できない
  • メンバーが増えたときに開発用証明書を作るのが非常に手間

経験豊富なiOSアプリエンジニアが少ないため、この辺をいつも私がサポートして行っていました。具体的な事例としてはこんな感じです。

  • 他チームの人「配布したいんですけどビルドできません・・・!」
    • その人の席まで行ってトラブルシュート → 証明書の期限切れとか知らずにビルドしてた
    • 証明書の作り方をレクチャー
    • ビルド成功を見届ける😂
  • 新規メンバー「実機で確認しながらコード書きたいんですが・・・!」
    • Apple Developer Program のチームに招待する
    • 証明書の作り方をレクチャー
    • ビルド成功を見届ける😂

社員がガンガン増えてフロアもどんどん分かれていき、各チームへのサポートが難しくなってきました。みんなが幸せになるにはどうしたら・・・ということで、効率化と仕組み化について動き始めました。

配布用証明書について

こちらはAdHocでのアプリ配布時やAppStoreへのアプリ提出時に必要となるもので、1法人アカウント内で3個までしか作成できません。そのため、チームを横断して使いまわしていました。

使っていた証明書の期限が切れたときに作り直して、メンバーに配布して(場合によっては他チームにも)・・・と結構手間がかかっていました。

また、知らぬ間に誰かが新しく作り直してしまったということもたびたび発生していました。

自分「あれ、昨日はビルドできたのに今日はできなくなってる・・・」

自分「(Slackにて)誰か証明書作ったりしましたか?」

みんな(全員身に覚えがなさそう)

自分「じゃあこれ(古くて使われてなさそうな証明書)消して新しいの作りますね」

(そして後日)

自分「またビルドできなくなってる・・・」

自分「Yくん(仮)が作成した証明書が増えてる・・・?」

自分「Yくんの作成した証明書が増えてるみたいなんですけど、何かした?」

Y「いやー、特には・・・」

自分「証明書のエラー出たときどうやって解決してた?」

Y「Xcode(ver7)のエラーのときに出るこの Fix it ってボタンを」

自分「それやんけ!!」

Xcodeは証明書のエラーをよしなに解決をしてくれるのですが、任せていたら勝手に古い証明書を消していたようでした。
彼には Fix it は絶対に押すんじゃないぞ、と念押しして私は自席に戻りました。

そんなこともありましたが、この問題についてはmatchの導入でなんとかなりそうだなと思っていました。このときにはもう誰がどの証明書を使っているのか把握できなかったので、早く導入したほうがいいね、と同僚と話していました。

開発用証明書について

もう一つ、開発用証明書に関する問題です。開発メンバーが増えたときの導入で必要なのですが、これがまた非常に手間のかかるものでした。

  1. Apple Developer Team への招待
  2. 開発用証明書の作成
  3. Provisioning Profile の更新

と開発を行うまでに必要な手順が多いです。

これについては、matchの導入に加えて、開発用アカウントを一つ作って、みんなで使い回せる証明書を作ればなんとかなるかなと思っていました。

matchを使って何をするか

こんな状態を作りたいと思います。

match

ざっくり説明すると、以下の2点が運用される状態を作ろうと思いました。

  • adminに任命された人は、matchを使って証明書& Provisioning Profile の作成&commitを行う
  • memberは、matchを使って証明書& Provisioning Profile をダウンロードして使う

matchを実際に導入する

matchは、作成した証明書や Provisioning Profile を暗号化してリポジトリの管理下に置くことができます。

リポジトリを用意する段階では、以下のコマンドで作成したディレクトリをpushしておくだけです。

$ fastlane match init

このコマンドの処理中に

  • リポジトリのurl
  • Passphrase(暗号化するため)

など入力します。

リポジトリには暗号化された証明書や Provisioning Profile が保存されるため、復号化するときにもPassphraseが必要になります。そのため、開発者にはPassphraseを伝えておく必要があります。

リポジトリができたら、あとはアプリごとにコマンドを叩いていくだけです。証明書が存在しなければ新規作成してくれるし、Provisioning Profile も同様に存在しなければ新規作成してくれます。

$ fastlane match
  --type appstore
  --app_identifier [アプリのBundle ID]
  --team_id [チーム識別ID]
  --git_url [リポジトリのURL]
  --username [メールアドレス]

また、typeを development にすれば開発用証明書と Provisioning Profile が作れます。

一度作ってしまえば、あとで他のメンバーが使う際にreadonlyオプションをつけて実行してもらいます。readonlyだとリポジトリから証明書を取得するだけになるので、Appleのサーバーへアクセスしなくなり手間が省けます。

$ fastlane match
  --type appstore
  --app_identifier [アプリのBundle ID]
  --team_id [チーム識別ID]
  --git_url [リポジトリのURL]
  --readonly true

Passphraseを聞かれるので、それを入力すれば証明書もろもろが手に入ります。

GitHub Team で権限の管理

ただmatchを導入しただけだと、readonlyオプションを忘れてしまう人が出るかもしれません。そうなるとまた「いつの間にか無効になっている」事態が発生する可能性があります。

そのため、私達はteamを2つ作成して権限を分けることにしました。

ios-developers ios-developers-admin
iOSアプリ開発者を全員追加 iOSアプリ開発のチームリーダーを追加
リポジトリへのread権限のみ付与 リポジトリへのread, write権限を付与
ios-developersのmaintainer権限を付与

権限を分けておくことで、member権限の人がreadonlyオプションを忘れて実行したとしても、コミットされることはありません。チームに新メンバーが増えても、各チームのリーダーがメンバー追加することができるので、毎回私が作業する必要もなくなりました。

ここまで設定することで、証明書関連の作業はチーム内で完結するようになりました。

最後に

今回は私達のmatch活用方法についてご紹介しました。

これによりコミュニケーションコストが削減され、個人の作業コストも削減することができました。まだまだ非効率なところがあるため、組織を横断しての効率化施策の第一弾といったところでしょうか。CIサービスの活用などもやりたいと思っています。

今回はmatchのご紹介でしたが、fastlaneには他にも便利な機能がたくさんありますので、一度調べてみると開発の生産性が高まるかもしれません。