Help us understand the problem. What is going on with this article?

iOSアプリのCI/CD〜Azure Pipelines編〜

More than 1 year has passed since last update.

はじめに

Azure PipelinesでiOSアプリのCI/CDを実現します。
Travis CIやCircle CI、Bitriseの記事はよく見かけるのですが、Pipelinesの記事はあまり見かけないのが寂しいです。。

前回は署名なしで単体テストを実行するジョブを構築しました。
今回はそれに加え、署名してAppCenterへデプロイするまでのジョブを構築します。

環境

Xcode:10.1 (10B61)
Swift:4.2.1
Carthage:0.32.0
CocoaPods:1.7.0.beta.1

Pipelinesでジョブの作成

前回と同様なので省略します。

ジョブの詳細([Tasks]タブ)

前回との差分のみ記載します。

  • Pipeline > Name
    {プロジェクト名}-iOS-Deploy-AppCenter

タスクの詳細

前回との差分のみ記載します。

不要なジョブの削除

前回削除した以下のタスクは使うので削除しません。

Install an Apple certificate
Install an Apple provisioning profile
Copy Files to: …
Publish Artifact: drop
Deploy */.ipa to Visual Studio App Center

以下のタスクのみ削除します。

Test with Visual Studio App Center
∵今回はUIテストを実施しないため

タスクの入れ替え

今回はテストとビルドでタスクを入れ替えません。
∵テストに失敗したらビルドしないようにしたいため

タスクの追加・編集

前回との差分のみ記載します。

Install an Apple certificate

署名に必要な証明書をインストールするタスクです。

以下の項目を編集します。

  • Certificate (P12)
    ギアのアイコンをクリック→.p12ファイルをアップロード
  • Enabled
    OFF→ON
  • Run this task
    Custom conditions→Only when all previous tasks have succeeded

スクリーンショット_2019-03-05_12_13_17.jpg

.p12ファイルのパスワードは[Variables]タブの「P12password」に入力します。

スクリーンショット_2019-03-05_12_15_01.jpg

Install an Apple provisioning profile

署名に必要なプロビジョニングプロファイルをインストールするタスクです。

以下の項目を編集します。

  • Provisioning profile
    ギアのアイコンをクリック→.mobileprovisionファイルをアップロード
  • Enabled
    OFF→ON
  • Run this task
    Custom conditions→Only when all previous tasks have succeeded

スクリーンショット_2019-03-05_12_27_49.jpg

例ではAdHoc版のプロビジョニングプロファイルを使っています。

Xcode test

Xcodeでテストを実行するタスクです。

前回と異なる項目のみ記載します。

  • Signing style
    Project defaultsのまま
    Do not code signでもOK

Xcode build

Xcodeでビルドするタスクです。

前回と異なる項目のみ記載します。

  • Signing style
    常に手動署名にしないとエラーになります
    (回避策を知っている方がいたらご教授お願いします)
    Xcodeの署名設定(製品ターゲット > Automatically manage signing)によって選択肢を変えます。
    Do not code sign→Project defaults(OFFの場合)
    →Manual signing(ONの場合)
  • Signing identity(「Manual signing」のみ)
    空欄→$(APPLE_CERTIFICATE_SIGNING_IDENTITY)
  • Provisioning profile UUID(「Manual signing」のみ)
    空欄→$(APPLE_PROV_PROFILE_UUID)
  • Create app package
    OFF→ON
  • Export options
    Automaticのまま
    失敗する場合は「Plist」を選択し、以下のような.plistファイルをリポジトリに作成します。
XcodeTaskExportOptions.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>{enterpriseなど}</string>
    <key>provisioningProfiles</key>
    <dict>
        <key>{Bundle Identifier}</key>
        <string>{Provisioning Profile名}</string>
    </dict>
</dict>
</plist>
  • Export options plist(Export optionsが「Plist」の場合のみ)
    作成した.plistファイルを指定します。
  • Destination platform
    Defaultのまま

スクリーンショット_2019-03-13_17_51_29.jpg

以下のようにCocoaPodsで管理しているライブラリでエラーが発生する場合、Podfileにおまじないを追加することで回避できます。

** BUILD FAILED **


❌  error: GoogleUtilities does not support provisioning profiles. GoogleUtilities does not support provisioning profiles, but provisioning profile {プロビジョニングプロファイル名} has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'GoogleUtilities')



❌  error: FirebaseCore does not support provisioning profiles. FirebaseCore does not support provisioning profiles, but provisioning profile {プロビジョニングプロファイル名} has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'FirebaseCore')



❌  error: nanopb does not support provisioning profiles. nanopb does not support provisioning profiles, but provisioning profile {プロビジョニングプロファイル名} has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'nanopb')



❌  error: Pods-{プロジェクト名} does not support provisioning profiles. Pods-{プロジェクト名} does not support provisioning profiles, but provisioning profile {プロビジョニングプロファイル名} has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor. (in target 'Pods-{プロジェクト名}')


##[error]Error: /usr/bin/xcodebuild failed with return code: 65
##[section]Finishing: Xcode build
Podfile
post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    # CI/CD環境でビルドエラーを防ぐためのおまじない
    # 参考:https://github.com/fastlane/fastlane/issues/10543
    #   :https://github.com/fastlane/fastlane/issues/12557
    config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = ''
    config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
    config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
  end
end

Copy Files(任意)

ファイルをコピーするタスクです。
ここではビルドした.ipaファイルをアーティファクト(後述)のステージングフォルダにコピーします。

以下の項目を編集します。

  • Display name(任意)
    Copy Files to: \$(build.artifactstagingdirectory)→Copy IPA Files to: \$(build.artifactstagingdirectory)

スクリーンショット_2019-03-05_17_23_13.jpg

Publish Build Artifacts(任意)

指定したフォルダをダウンロードできるようにする(アーティファクトをビルドして発行する)タスクです。
ここではステージングフォルダにコピーしたファイルを「Artifact name」で指定したフォルダ名でアーティファクト化します。

後ほど使いたいファイルが存在する場合に実行します。

以下の項目を編集します。

  • Run this task
    Custom conditions→Only when all previous tasks have succeeded

スクリーンショット_2019-03-05_17_32_58.jpg

App Center Distribute

バイナリファイルをApp Centerへ配布するタスクです。
ここではビルドした.ipaファイルをApp Centerにデプロイします。

以下の項目を編集します。

  • App Center connection
    「AppCenter」を選択します。
  • App slug
    AppCenterのURLを確認し、 https://appcenter.ms/users/{username}/apps/{app_identifier} の{}で括られている部分を取り出して {username}/{app_identifier} の形式で入力します。
  • Create release notes
    「Enter Release Notes」を選択します。
  • Release Notes
    リリースノートの内容を記載します。ここではテストアプリ用に様々な情報を載せます。
    - Environment:AdHoc
    - Configuration:$(Configuration)
    - Certificate:$(APPLE_CERTIFICATE_SIGNING_IDENTITY)
    - Provisioning Profile:$(APPLE_PROV_PROFILE_UUID)
    - Branch:$(Build.SourceBranchName)
    - Last Commit ID:$(Build.SourceVersion)
    - Last Commit Comment:$(Build.SourceVersionMessage)
    - Release Note:$(ReleaseNote)
  • Distribution Group ID
    特定のグループに配布したい場合に指定します。ここでは空欄とします。
  • Enabled
    OFF→ON
  • Run this task
    Custom conditions→Only when all previous tasks have succeeded

スクリーンショット_2019-03-25_23_23_14.jpg
スクリーンショット_2019-03-25_23_23_31.jpg
スクリーンショット_2019-03-25_23_23_48.jpg

ジョブの完成形

こちらがジョブの完成形です。

スクリーンショット 2019-03-05 17.50.21.png

パイプラインの実行(手動)

[queue]ボタンをクリックすることでパイプラインを手動で実行します。
$(ReleaseNote) は自分で作成した変数であり、実行時に指定できるようにしています。

スクリーンショット_2019-03-24_21_17_56.jpg

App Centerへのデプロイ結果

パイプラインの実行に成功すると、App Centerへデプロイされます。

スクリーンショット_2019-03-24_22_24_19.jpg

おわりに

これで「ソースをプッシュ→単体テスト→ビルド→デプロイ」を自動化できました!

あとはUIテストを実行したり、Gitのブランチやタグを自動で切るようにしたりすれば完璧です。

参考リンク

uhooi
iOSアプリ開発とSwiftが好きです✨ 趣味:テニス、アナログゲーム
https://theuhooi.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away