Azure Pipelines で iOS ビルドの設定について

## 概要

iOSアプリのビルドをAzurePipelinesでCI/CD対応した際にP12およびプロビジョニングプロファイルの設定が必要になります。

そのため、P12およびプロビジョニングプロファイルの準備とAzurePipelinesに設定する方法をまとめます。

「Azure Pipelinesとは何か」などの初歩的な話は、過去にまとめた「[App Center と Azure Pipelines について](https://qiita.com/gremito/items/265d15d6fcf53db3db2d)」があるので割愛します。

また、公式ドキュメントに大筋があるので先にこちらを確認しておくと把握しやすいと思います。

- [Azure DevOps/Azure Pipelines/エコシステムと統合/Xcode アプリのビルド、テスト、デプロイ](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/ecosystems/xcode?view=azure-devops)
- [Azure DevOps/Azure Pipelines/アプリをデプロイする/モバイル アプリのデプロイ/署名証明書の管理](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/apps/mobile/app-signing?view=azure-devops&tabs=apple-install-during-build)


## azure-pipelines.yml

azure-pipelines.ymlの完成版がこちらになります。
`trigger`のところはよしなに調整してください。

`InstallAppleProvisioningProfile`と`InstallAppleCertificate`で取得しているP12およびプロビジョニングプロファイルのデータをこれから用意していきます。
`certPwd`をコメントアウトしているのは、P12出力時にパスワードを設定できるんですが、その際にパスワードなしでP12を作ると`certPwd`の設定はいらなくなります。

最後にAppCenterと連携していますが、詳細は、「[Azure Pipelines と App Center の連携方法](https://qiita.com/gremito/items/08d44b5e18afe05910a5)」にまとめています。


```yml
pool:
  vmImage: 'macOS-11'

variables:
  XCODE_ROOT_PATH: '/Applications/Xcode_13.2.1.app'

steps:

- task: InstallAppleProvisioningProfile@1
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: '$(mobileprovision_filename)'
    removeProfile: true

- task: InstallAppleCertificate@2
  inputs:
    certSecureFile: '$(distribution_filename)'
    # certPwd: '$(p12pass)'
    keychain: 'temp'
    deleteCert: true

- task: Xcode@5
  inputs:
    actions: 'clean build analyze archive'
    scheme: '$(XCODE_PROJECT_NAME)'
    sdk: 'iphoneos'
    configuration: 'Release'
    xcWorkspacePath: './*.xcodeproj'
    xcodeVersion: 'default'
    signingOption: 'manual'
    signingIdentity: '$(APPLE_CERTIFICATE_SIGNING_IDENTITY)'
    provisioningProfileUuid: '$(APPLE_PROV_PROFILE_UUID)'
    packageApp: true
    exportPath: '$(agent.buildDirectory)/output/iphoneos/Release'

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: '$(agent.buildDirectory)/output'
    artifactName: 'Publish'

- task: AppCenterDistribute@3
  inputs:
    serverEndpoint: 'AppCenter'
    appSlug: 'gremito/iOSAppSample'
    appFile: '$(agent.buildDirectory)/output/iphoneos/Release/*.ipa'
    buildVersion: '$(Build.BuildNumber)'
    symbolsOption: 'iOS'
    releaseNotesOption: 'input'
    releaseNotesInput: 'New release!'
    destinationType: 'groups'
```


## .p12/.mobileprovision

P12およびプロビジョニングプロファイルの準備は、

- [iOS 証明書 & Provisioning Profile & Apple Developer Program の更新をやったメモ（1年ぶりn回目）](https://dev.classmethod.jp/articles/update-ios-certificate-and-provisioning-profile)
- [プッシュ通知に必要な証明書の作り方2021](https://qiita.com/natsumo/items/d5cc1d0be427ca3af1cb#7-apns%E7%94%A8%E8%A8%BC%E6%98%8E%E6%9B%B8p12-%E3%81%AE%E4%BD%9C%E6%88%90)
- [Provisioning profile "XXXXXX" doesn't include signing certificate YYYY って出る場合の対処法(2019/10/9版)](https://qiita.com/warapuri/items/2a32cb2201ce75aa5f4b)

などを参考に作りました。

まず、Xcode上からDistributionを作成します。
コンソール画面上でもできますが、これが一覧手軽で作業しやすかったです。
　<img width="500" alt="スクリーンショット 2021-07-13 19.25.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/01b815e3-ca4e-9021-4df9-bb50ba4e9510.png">
作成されたことを確認します。
コンソール画面上から操作するとCertificateファイルをダウンロードして展開しますが、Xcodeから操作したので不要です。
　<img width="500" alt="スクリーンショット 2021-07-13 19.17.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/3c8abc65-9a52-38f6-cdd5-01bf0474868e.png">
次にプロビジョニングプロファイル（.mobileprovision）を作成します。
参考記事通りに作ったらダウンロードして保管とこの後のAzurePipelinesで扱います。
　<img width="500" alt="スクリーンショット 2021-07-13 19.17.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/6c94f95f-fd07-8472-4329-3647e0ac5cba.png">
最後にP12を作成します。
これも参考記事通りに作ったら保管とAzurePipelinesで扱います。　
　<img width="500" alt="スクリーンショット 2021-07-13 19.23.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/c612b5aa-107b-1002-801f-fc6354cf8ce6.png">


## Library/Secure files

AzurePipelinesのLibraryにあるSecure filesに先ほど作った、P12およびプロビジョニングプロファイルのアップロードします。
リスト上に表示されているP12とプロビジョニングプロファイルを選んで、`Pipeline permissions`からビルドするパイプラインを選んでおきましょう。
この設定を忘れていてもパイプラインを実行した際に警告が表示されてそこから設定することもできます。

P12とプロビジョニングプロファイルの名前は、azure-pipelines.ymlで設定している`InstallAppleProvisioningProfile`と`InstallAppleCertificate`のファイル指定で使うことになります。
間違ったとしてもエラーになり、途中でパイプラインが止まります。
　<img width="500" alt="スクリーンショット 2021-07-13 19.15.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/b3210028-b4d2-1338-bf7c-7722a8dd29c1.png">



## さいごに

これでAzurePipelinesでビルドされたアプリが正常に起動すれば、CI/CD対応が完了となります。
P12およびプロビジョニングプロファイルの設定は、どちらとも`Distribution`でなければなりません。
そのため、どちらかが`Development`だと

> error: Provisioning profile プロビジョニングプロファイル名 doesn't include signing certificate Certificate名

というエラーでパイプラインが止まります。

もし、ビルドが成功してAppCenterに配布されたアプリが起動直後にクラッシュされた場合は、手元でビルドして問題ないことを確認しましょう。
それでもAzurePipelinesでビルドしたアプリだけが問題の場合は、パイプラインからipaファイルをダウンロードし、手元でビルドしたipaファイルをもとに[証明書の内容を確認する](https://qiita.com/shtnkgm/items/3a8503aa8d046604b7cf)ことでAzurePipelinesの問題なのか大元のアプリの問題なのか区別できると思います。