【iOS】fastlane matchのセットアップ

# はじめに
普段の開発では既に構築されているCI/CD環境を使用しているせいか、`fastlane match`についての理解が不足しており少し危機感を感じているので、セットアップを一から行ってみることにしました。
せっかくなのでざっくり内容まとめてみます。

# 内容

https://docs.fastlane.tools/actions/match/

基本はドキュメントの内容通りです

#### fastlaneのmatchとは
> match は、必要なすべての証明書とプロビジョニング プロファイルを作成し、それらを別の git リポジトリ、Google Cloud、または Amazon S3 に保存します。選択したストレージにアクセスできるすべてのチーム メンバーは、これらの資格情報をコード署名に使用できます。


使う前に👇を読むように書いてありましたので確認していきます

https://codesigning.guide/

> アプリを App Store やベータ テスト サービスに展開したり、デバイスにインストールしたりする場合でも、ほとんどの開発チームはメンバーごとに個別のコード署名 ID を持っています。これにより、重複を含む多数のプロファイルが生成されます。
`fastlane match` を使うことで開発チームはコード署名IDを共有することで、セットアップを簡略化し、コード署名の問題を解消できます

> コードサイニングにGitを使う方法：
基本的な要件は、チーム全体で共有するコード署名用のIDをひとつにすることです。そのための最も簡単な方法は、チーム用に新しいApple IDを作成し、今後はそれを使うことです。
> 1. まず、プロファイルを保存するための新しいプライベートな Git リポジトリを作成します。
> 2. 次に、「Distribution」と「Development」のような環境ごとに、新しい秘密鍵と証明書を作成します。そして、これらの秘密鍵と証明書をGitリポジトリに保存します。
> 3. 次に、「Development」、「App Store」、「Ad hoc」などのさまざまなターゲットに対して、一致する証明書とともに新しいプロビジョニングプロファイルを作成し、これらをGit repoに格納します。
> 4. Gitにファイルをコミットする前に、それらのファイルを暗号化することをお勧めします（例：opensslを使用）。
> 5. これで、各マシンがGitリポジトリにアクセスし、最新の証明書とプロビジョニング・プロファイルをインストールすることができます：
> - 証明書と秘密鍵は、Finderを使うか、「security import」コマンドを使って、Keychainにインポートする必要があります。
> - プロビジョニングプロファイルは、「~/Library/MobileDevice/Provisioning Profiles/」にコピーしておく必要があります。

> 考慮すべきこと
プロビジョニングプロファイルが正しい証明書を使用して作成されていることを確認します。
アプリに複数のターゲットがある場合（例：Todayウィジェット）、各ターゲットに対して上記を繰り返す必要があります。
Xcodeプロジェクトのプロビジョニングプロファイルは、常に正しいプロファイルを選択するわけではないので、Automaticに設定しないでください

## 設定ステップ
まずは共通アカウントとレポジトリを作ります
- matchをチームで使うにあたって共通アカウントを作成
- 証明書管理用のプライベートGitHubレポジトリを作成

作成したら早速`match`を使っていきます

### `match init`実行

https://docs.fastlane.tools/actions/sync_code_signing/#:~:text=Usage-,Setup,-Optional%3A%20Create%20a

（今回は）gitを選択
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/9e4ffa48-fa0e-ce17-a955-f9beb8c5d0ce.png">
作成したプライベートレポジトリのURLを入力
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/b7a0d51d-71b5-8c91-66d7-93fb098622d3.png">
完了するとMatchfileがfastlaneファイルの中に生成される
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/9a2c287d-8274-709a-93ab-2cf6b46f980b.png">

`app_identifier`, `username`に適当な値を入れる
(以下は生成直後の状態)
```yml: Matchfile
git_url("https://github.com/...")

storage_mode("git")

type("development") # The default type, can be: appstore, adhoc, enterprise or development

# app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
# username("user@fastlane.tools") # Your Apple Developer Portal username

# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options

# The docs are available on https://docs.fastlane.tools/actions/match
```

### `fastlane match appstore`を実行

https://docs.fastlane.tools/actions/sync_code_signing/#:~:text=the%20team%20ID.-,Run,-Before%20running%20match

実行の過程で`MATCH_PASSWORD`の入力を求められるので保存しておくこと
このPASSWORDは証明書を取得するときに必要になるのでBitriseのSecretsにも入れておきます

**Matchの実行Summary**

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/0214fbd7-7e61-ad4c-75b7-ca4c608fbdee.png">

**証明書生成のSummary（Matchで実行される）**

https://docs.fastlane.tools/actions/get_certificates/

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/969868c0-4856-8d85-b72f-6bd682f4b0ec.png">

ここで実行される内容は
> - 新しい秘密鍵を作成する
> - 新しい署名依頼を作成する
> - 証明書を生成し、ダウンロードし、インストールする
> - 生成されたすべてのファイルをキーチェーンにインポートする

**プロビジョニングプロファイル生成のSummary（Matchで実行される）**

https://docs.fastlane.tools/actions/sigh/#:~:text=sigh%20in%20action%3A-,Usage,-Note%3A%20It%20is

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/a1cc6e2a-4c84-3060-cf55-84c7372af68a.png">

ここで実行される内容は
> - アプリの最新のプロビジョニング プロファイルをダウンロードする
> - プロビジョニング プロファイルの有効期限が切れたら更新する
> - プロビジョニング プロファイルが壊れている場合は修復する
> - 新しいプロビジョニング プロファイルが存在しない場合は作成します。
> - 複数の Apple アカウントのサポート、認証情報をキーチェーンに安全に保存

<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/36952918-f794-def7-0a94-a8bdd9fdd239.png">

生成したプロビジョニングプロファイルをローカル（Library/MobileDevice/ProvisioningProfiles）取得
<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/12b481ff-c71a-486d-f0bf-73e2a2134d95.png">


### `fastlane match development`を実行

流れは`fastlane match appstore`と同じなので省略

### 実行後の状態確認

https://developer.apple.com/account/resources/certificates/list

にて証明書が正しく追加されているか確認
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/1b485f48-4133-962f-ec62-c32caaa85e06.png">

証明書とプロビジョニングプロファイルがローカル取得できているか確認
- キーチェーンに証明書(Distribution、Development)が取得できているか
- Library/MobileDevice/ProvisioningProfilesにプロビジョニングプロファイル(Distribution、Development)が取得できてるか
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/2a48d538-0607-9b6e-3bd9-0a0aa9c04a29.png"><img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/7666813d-3cea-e0a7-768e-263494831fee.png">

これで設定は完了

## 証明書、プロビジョニングプロファイルの取得
別のマシンに証明書とプロビジョニングプロファイルをセットする場合

`fastlane match appstore --readonly`
`fastlane match development --readonly`

を実行する

一度で実行したいので`Fastfile`から`fastlane fetch_certificates`としても

```yml: Fastfile
  desc "Fetch certificates"
  lane :fetch_certificates do
    match(type: "development", readonly: true)
    match(type: "appstore", readonly: true)
  end
```

## 動作確認
試しにリリースを実行していきますが、早速エラーが出ました

```
Error cloning certificates repo, please make sure you have read access to the repository you want to use
```

どうやらBitriseのマシンから証明書レポジトリへのアクセス権がなく、エラーになっているようです。

Bitriseの`App settings`→ `Integrations`から確認できる`SSH public key`をGitHubの`Security`→ `Deploy keys`に保存することでBitriseのマシンからプライベートリポジトリへのアクセスができるようになりますが、複数のリポジトリ(iOSアプリのリポジトリと証明書のリポジトリなど)に登録ができません。

https://devcenter.bitrise.io/ja/connectivity/configuring-ssh-keys


対応としては

https://devcenter.bitrise.io/ja/connectivity/apps-with-submodules-or-private-repo-dependencies.html#マシンユーザーをリポジトリに追加する

Githubでmachine userを作成して証明書のレポジトリへアクセスできるようにします。

https://docs.github.com/ja/get-started/learning-about-github/types-of-github-accounts#personal-accounts

> 個人用アカウントは人間が使用するものですが、GitHub のアクティビティを自動化するアカウントを作成できます。 この種類のアカウントは、マシン ユーザーと呼ばれます。 たとえば、継続的インテグレーション (CI) ワークフローを自動化するマシン ユーザー アカウントを作成できます。

この設定をしたことで、BitriseからAppStoreConnectへのリリース配布ができるようになりました🎉

# おわりに
証明書の更新など定期的にメンテナンスが必要なので、この辺りの理解は深めていきたいと思います


# 参考

https://www.hfoasi8fje3.work/entry/fastlane/manage-certificates

https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys#machine-users

https://qiita.com/Marimoiro/items/40325da6f85a06b2d51c