iOSアプリ開発に必要な証明書とプロファイルをGitHubのリポジトリで一括管理する

WantedlyのUser Growthチームで開発をしている@hedjirogです。
これは、[Wantedly Advent Calendar 2015](http://qiita.com/advent-calendar/2015/wantedly) 19日目の記事です。


## はじめに

この記事では、**iOSアプリ開発に必要な証明書とプロビジョニングプロファイル**（以下、プロファイル）**をGitHubのリポジトリで一括管理する方法**を紹介します。

iOSアプリのチーム開発をしている現場では、メンバー間での証明書やプロファイルの管理が煩雑になりがちです。**この記事で紹介する内容は、チーム開発の現場で特に有効です**。

Wantedlyでは、iOS開発の様々なワークフローを定義して自動化してくれるツールである[fastlane](https://fastlane.tools/)を積極的に利用しています。過去に、fastlaneの利用事例について発表を行なって来ました。

- [fastlaneとCircleCIではじめるアプリ配布の定期実行](https://speakerdeck.com/hedjirog/continuous-deployment-with-fastlane-and-circleci)
- [How we use fastlane at Wantedly](https://speakerdeck.com/hedjirog/how-we-use-fastlane-at-wantedly)

fastlaneには様々なワークフローが簡単に実行できるように、いくつかのツールが用意されています。例えば、**申請作業などでiTunes Connectを操作可能な[deliver](https://github.com/fastlane/deliver)**や、**アプリのスクリーンショットの撮影が可能な[snapshot](https://github.com/fastlane/snapshot)**、**ビルド支援をしてくれる[gym](https://github.com/fastlane/gym)**などがあります。

そんなfastlaneに、**Gitを用いてチーム内で証明書やプロファイルを管理可能な[match](https://github.com/fastlane/match)**が新たに加わりました :tada:

今回は、**matchを利用して証明書とプロファイルをGitHubのリポジトリで管理するまで**を試してみます。また、**fastlaneと併用したアプリ自動配布の際のコード署名**を試したので、併せて記事の後半で紹介します。


## matchとは

<p align="center">
  <img src="https://qiita-image-store.s3.amazonaws.com/0/6087/eea6f8e7-f505-08fb-e4d2-4a4dfa866ca5.png" height="110">
</p>

従来のXcodeによる管理方法などでは、チームの各メンバーが異なる証明書やプロファイルを保持することになり管理が煩雑になります。

この問題を解決するmatchのアプローチはシンプルで、**Gitのプライベートリポジトリにチーム内で共通の証明書やプロファイルを管理して、メンバー間で共有して利用する**というものです。

証明書やプロファイルの生成、Gitのリポジトリへのプッシュなど、管理に必要な操作は全てコマンドラインからmatchを利用して実行することが可能です。

さらに詳しい説明は、以下のリンク先から確認すると良いでしょう。

- [Code Signing Guide for Teams](https://codesigning.guide/)


## 【基礎編】matchを利用してみる

実際にmatchを利用してみましょう。

### 1. インストール

インストールの方法はいくつかあります。

matchを直接インストールする場合は以下のコマンドを実行します。

`sudo gem install match`

もしくは、fastlaneをインストールする (`sudo gem install fastlane`) ことで、付属するmatchをインストールすることもできます。また、[Bundler](http://bundler.io/)を利用すれば、チームで利用するmatchのバージョンを揃えることも可能です。

最新のXcodeのコマンドラインツールがインストールされていることも確認してください。以下のコマンドでインストールすることが可能です。

`xcode-select --install`

### 2. プライベートリポジトリの作成

GitHubでプライベートリポジトリを作成します。リポジトリ名は`certificates`などとします。

ここでは、**必ずリポジトリの種別として`Private`を選択するように注意してください**。

<p align="center">
  <img src="https://qiita-image-store.s3.amazonaws.com/0/6087/64d3209b-5303-e600-54cd-179756f8061c.png">
</p>

### 3. Apple Developer Potalの共有アカウントの作成

matchでは、**チームで共有するApple Developer Portalのアカウント**を作成することを推奨しています。

[招待ページ](
https://developer.apple.com/membercenter/index.action#invitations)から適切なメールアドレスに招待メールを送付して、アカウントの作成を行ないましょう。

![Member_Center_-_Apple_Developer.png](https://qiita-image-store.s3.amazonaws.com/0/6087/4ee881f5-5518-7793-9d49-ee8a45d3f6a7.png)

共有アカウントに付与する権限は、[Roles Overview](https://developer.apple.com/support/roles/)のページを参考にします。

Distribution用の証明書やプロファイルをmatchで生成する場合は、`Admin`の権限を付与する必要があります。状況に応じて、`Admin`と`Member`のいずれの権限を付与するかを検討してください。

<p align="center">
  <img src="https://qiita-image-store.s3.amazonaws.com/0/6087/f488e33d-3bbe-76fc-31b5-8f4c096e73fa.png">
</p>

### 3. 初期コマンドの実行

以下の初期コマンドを実行して、作業ディレクトリに設定ファイル (`Matchfile`) を配置します。

`match init`

基本的に設定ファイルは作業ディレクトリ直下に配置されますが、fastlaneを既に利用していれば`fastlane`ディレクトリに配置されます。

コマンドを実行すると、先程作成したプライベートリポジトリのURLの入力を求められます。コマンドラインからGitHubにsshでアクセスしている場合は、`git@github.com:wantedly/hoge.git`といったURLを指定する必要があります。

配置される設定ファイルは以下のようになります。

```
git_url "git@github.com:wantedly/hoge.git"

type "development"

app_identifier "com.wantedly.app"
username "hoge@wantedly.com"
```

### 4. 証明書とプロファイルの生成

ここまで準備ができると、後はコマンドにより自由に証明書とプロファイルの生成が可能です。

例えば、以下のコマンドを実行すると、Development用の証明書とプロファイルが生成されます。生成された証明書とプロファイルは自動的にGitHubのプライベートリポジトリにpushされます。

`match development`

この際、証明書とプロファイルはopensslを利用して暗号化されます。暗号化のためのパスフレーズの入力を求められます。他のマシンでもmatchを利用できるようにパスフレーズは忘れないようにしましょう。


## 【応用編】fastlaneと併用してコード署名したアプリの自動配布を行なう

ここからは応用編です。

Wantedlyで**fastlaneと併用したアプリの自動配布の際のコード署名**を試したので、手順を紹介します。

### 1. AdHoc用の証明書とプロファイルを生成する

以下のコマンドを実行してAdHoc用の証明書とプロファイルを生成します。

`bundle exec match adhoc -a com.wantedly.app-qa`

Apple Developer Portalにアクセスすると、自動的にプロファイルが追加されたのがわかります。

![iOS_Provisioning_Profiles__Distribution__-_Apple_Developer.png](https://qiita-image-store.s3.amazonaws.com/0/6087/5ac6ec6c-7fcc-4ca7-656f-6e59ffb948ea.png)

GitHubの管理用のプライベートリポジトリにも自動的にコミットされたのが確認できます。

![Commits.png](https://qiita-image-store.s3.amazonaws.com/0/6087/da5fc59e-099e-be3f-316f-b4bc1cbccede.png)

### 2. Fastfileに証明書とプロファイルの取得処理を追加する

fastlaneと併用してmatchによる証明書とプロファイルの取得が可能です。ワークフローを記述するための`Fastfile`に変更を加えましょう。

ここでは、以下のmatchのアクションを`Fastfile`に追加します。

```rb
match type: "adhoc", app_identifier: "com.wantedly.app-qa"
```

Wantedlyではアプリ配布を実行するために`beta`というレーンを用意しています。gymでビルドする直前で、matchによる証明書とプロファイルの取得処理を実行しましょう。

以下は、`Fastfile`に記述されたWantedlyのアプリ配布用レーンのイメージです。

```rb
lane :beta
  match type: "adhoc", app_identifier: "com.wantedly.app-qa"

  gym(
   scheme: "app",
   configuration: "QA",
   use_legacy_build_api: true
  )
  
  crashlytics(
    crashlytics_path: "./Pods/Crashlytics/Crashlytics.framework",
    groups: "Developers",
    notifications: "true"
  )
end
```

### 3. CIによるアプリ配布の実現

fastlaneと併用したアプリ配布の処理は、[CircleCI](https://circleci.com/)や[Travis CI](https://travis-ci.org/)などのCIサービスでも実行可能です。

各CIサービスの設定に従って、openssl用のパスフレーズの`MATCH_PASSWORD`、Apple Developer Portalにログインするための`FASTLANE_USER`や`FASTLANE_PASSWORD`などの環境変数を適切に設定しましょう。

keychainの操作やopensslによる暗号化や復号化の操作は全てmatchが行なってくれます。matchの登場によってfastlaneがますます便利になりました :tada: 


## 最後に

Wantedlyではモバイルのエンジニアも積極採用中です！fastlaneの情報交換をしに、是非一度、Wantedlyに話を聞きに来てください！！