2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Azure PipelinesのYAMLでiOSアプリのApp Center配布パイプラインを構築する方法

Last updated at Posted at 2020-03-18

「Azure PipelinesのYAMLでiOSアプリのCI/CD環境を構築する」は3部構成です。
記事を順番に読み進めると、Azure PipelinesでiOSアプリのCI/CD環境が構築できるようになります。

はじめに

Azure Pipelinesを使い、iOSアプリをApp Centerへ配布するCDを構築します。

本記事で説明しないこと

  • Azure Pipelinesの概要や基本的な操作方法
    私が以前書いた記事が参考になると思います
  • Visual Studio App Centerの概要や基本的な操作方法
  • CI環境の構築で説明した内容
    以前説明した内容を説明するのは冗長なのでしません

App Centerのコネクションを追加

Azure DevOpsのプロジェクトに、App Centerを接続します。

Azure DevOps > Project Settings > Pipelines - Service connections > 「New service connection」をクリック
スクリーンショット_2020-03-18_17_43_19.jpg

以下のURLからでもアクセスできる
https://dev.azure.com/{Organization}/{Project}/_settings/adminservices

「Visual Studio App Center」を選択し、「Next」をクリック
スクリーンショット 2020-03-18 17.53.26.png

API TokenにApp CenterのAPIトークン、Service connection nameに「App Center」など適当な名前を入力し、「save」をクリック
スクリーンショット 2020-03-18 17.55.14.png

スクリーンショットを撮るのが手間だったので、API Tokenの発行方法とサービスの追加方法は記載できていません。
以下の記事が参考になるので、こちらに沿って行ってください。
https://qiita.com/gremito/items/08d44b5e18afe05910a5

これでApp Centerの接続は完了です。

証明書とProvisioning Profileのアップロード

証明書とProvisioning ProfileをAzure Pipelines内の安全な場所へアップロードします。

Azure DevOps > Pipelines > Library > [Secure files]タブ > 「+ Secure file」をクリック
スクリーンショット_2020-03-18_17_59_51.jpg

ファイルをドラッグ&ドロップし、「OK」をクリック
スクリーンショット 2020-03-18 18.03.10.png

これをファイル数分繰り返せば、証明書とProvisioning Profileのアップロードは完了です。

P12ファイルのパスワードの追加

P12ファイルのパスワードをAzure Pipelinesの安全な場所で保持します。

まず変数のグループを作成し、その中に変数を追加します。

Azure DevOps > Pipelines > Library > [Variable group]タブ > 「+ Variable group」をクリック
スクリーンショット_2020-03-18_18_15_32.jpg

Variable group nameに適当な名前を入力し、VariablesにP12ファイルのパスワードを追加し、「Save」をクリック
スクリーンショット_2020-03-18_18_39_13.jpg

パスワードの変数名は適当な名前でOKです。
Standardのみ契約している場合、単純に P12Password でいいと思います。

これでP12ファイルのパスワードの追加は完了です。

Makefileの作成

アーカイブやIPAファイルの作成などの実行コマンドをまとめたMakefileを作成します。
CI環境の構築で紹介したコマンドは省略します。

Makefile

例はAd Hocなので、In-Houseの場合は変数名などを適当に修正してください。

DEVELOPMENT_TEAMPRODUCT_BUNDLE_IDENTIFIERADHOC_PROVISIONING_PROFILE_SPECIFIER は自分のプロジェクトの値に置き換えてください。

ADHOC_EXPORT_OPTIONS_PATH := ./ExportOptions/ExportOptionsAdHoc.plist としているので、このパスに.plistファイルを配置してください。
Xcode上からアーカイブ→エクスポートすると.plistが生成されるので、それをそのまま使うのがオススメです。

Makefile
SDK := iphoneos
CONFIGURATION := Release
ARCHIVE_PATH := ./build/${PRODUCT_NAME}.xcarchive
EXPORT_PATH := ./output/${SDK}/${CONFIGURATION}

XCODEBUILD_ARCHIVE_LOG_NAME := xcodebuild_archive.log
XCODEBUILD_EXPORT_ARCHIVE_LOG_NAME := xcodebuild_exportArchive.log

DEVELOPMENT_TEAM := XXXXXXXXXX
PRODUCT_BUNDLE_IDENTIFIER := com.example.Foo
ADHOC_PROVISIONING_PROFILE_SPECIFIER := Foo_AdHoc
ADHOC_EXPORT_OPTIONS_PATH := ./ExportOptions/ExportOptionsAdHoc.plist

.PHONY: generate-ipa-adhoc
generate-ipa-adhoc: # Generate IPA file for Ad Hoc
	$(MAKE) archive-adhoc
	$(MAKE) export-archive-adhoc

.PHONY: archive-adhoc
archive-adhoc:
	$(MAKE) archive PROVISIONING_PROFILE_SPECIFIER=${ADHOC_PROVISIONING_PROFILE_SPECIFIER}

.PHONY: export-archive-adhoc
export-archive-adhoc:
	$(MAKE) export-archive EXPORT_OPTIONS_PATH=${ADHOC_EXPORT_OPTIONS_PATH}

.PHONY: archive
archive:
	set -o pipefail && \
xcodebuild \
-sdk ${SDK} \
-configuration ${CONFIGURATION} \
-project ${PROJECT_NAME} \
-scheme ${SCHEME_NAME} \
-archivePath ${ARCHIVE_PATH} \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="iPhone Distribution" \
PROVISIONING_PROFILE_SPECIFIER=${PROVISIONING_PROFILE_SPECIFIER} \
DEVELOPMENT_TEAM=${DEVELOPMENT_TEAM} \
PRODUCT_BUNDLE_IDENTIFIER=${PRODUCT_BUNDLE_IDENTIFIER} \
clean archive \
| tee ./${XCODEBUILD_ARCHIVE_LOG_NAME} \
| bundle exec xcpretty --color

.PHONY: export-archive
export-archive:
	set -o pipefail && \
xcodebuild \
-exportArchive \
-archivePath ${ARCHIVE_PATH} \
-exportPath ${EXPORT_PATH} \
-exportOptionsPlist ${EXPORT_OPTIONS_PATH} \
| tee ./${XCODEBUILD_EXPORT_ARCHIVE_LOG_NAME} \
| bundle exec xcpretty --color

アーカイブ時に CODE_SIGN_STYLE=Manual を指定し、手動で署名しているのがポイントです。
これにより、開発時に自動署名していても確実に署名できます。

今回のMakefileは、本記事で使うコマンドのみを抜粋および編集して紹介しています。
私が普段使っているMakefileの全容はこちらにあるので、よかったら参考にしてください。

設定ファイルの構成

CI環境の構築で紹介したので省略します。

各項目の紹介

各項目を上から順に紹介します。

name

CI環境の構築と同様なので省略します。

trigger

私は手動でApp Centerへ配布したいため、トリガーをOFFにしています。

trigger: none

pool

CI環境の構築と同様なので省略します。

variables

先ほど追加した変数を使うには、変数グループを明記する必要があります。
変数グループと変数を同時に指定する場合、変数は namevalue で定義しなければいけません。

variables:
- group: Foo-iOS
- name: DEVELOPER_DIR
  value: '/Applications/Xcode_12.4.app/Contents/Developer'
- name: MINT_PATH
  value: 'mint/lib'
- name: MINT_LINK_PATH
  value: 'mint/bin'
×変数グループと同時に変数を指定する場合、かんたんな書き方はできない
variables:
  DEVELOPER_DIR: '/Applications/Xcode_12.4.app/Contents/Developer'
  MINT_PATH: 'mint/lib'
  MINT_LINK_PATH: 'mint/bin'
- group: Foo-iOS

steps

パイプライン内のステップを1つずつ紹介します。
ライブラリのインストールなど、CI環境の構築と同様のステップは省略します。

証明書のインストール

証明書をインストールします。

標準で用意されているタスクを使います。
certSecureFile にP12ファイルの名前、 certPwd に先ほど追加したP12ファイルのパスワードの変数を指定します。

- task: InstallAppleCertificate@2
  inputs:
    certSecureFile: 'Certificate.p12'
    certPwd: $(P12Password)
    keychain: 'temp'

Provisioning Profileのインストール

Provisioning Profileをインストールします。

証明書のインストールと同様、標準で用意されているタスクを使います。
provProfileSecureFile にProvisioning Profileの名前を指定します。

- task: InstallAppleProvisioningProfile@1
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: 'Foo_AdHoc.mobileprovision'

IPAファイルの作成

IPAファイルを作成します。

- script: make generate-ipa-adhoc
  displayName: Generate IPA file for Ad Hoc

アーティファクトのステージングへコピー

配布に問題があった場合に調査するため、生ログとアーカイブ、IPAファイルをダウンロードできるようにします。

そのためには「ステージングへコピー→アップロード」と2つのタスクを実行します。

- task: CopyFiles@2
  inputs:
    Contents: |
      **/xcodebuild_*.log
      **/*.xcarchive/**/*
      **/output/iphoneos/Release/*
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

Contents では、Makefileで定義した生ログと ARCHIVE_PATHEXPORT_PATH をワイルドカードで指定しています。
.xcarchiveファイルはフォルダ扱いのため、末尾を **/* としています。

アーティファクトへアップロード

直前のタスクでステージングへコピーしたので、本タスクでアップロードします。

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

これにより、パイプラインの実行結果からアーカイブとIPAファイルがダウンロードできるようになります。

App Centerへ配布

作成したIPAファイルをApp Centerへ配布します。

serverEndpoint は先ほど追加したコネクションの名前を指定します。
appSlug は自分のApp Centerの値に置き換えてください。
releaseNotesInput はテストアプリの配布なのでいろいろな情報を表示しています。必要に応じて変更してください。
最後の $(ReleaseNote) はパイプラインの手動実行時に値を入れることで、リリースノートを書けるようにしています。

- task: AppCenterDistribute@3
  inputs:
    serverEndpoint: 'App Center'
    appSlug: '{Organization}/{App}'
    appFile: '**/*.ipa'
    releaseNotesOption: 'input'
    releaseNotesInput: |
      - Environment: 'Ad Hoc'
      - Configuration: Release
      - Certificate: $(APPLE_CERTIFICATE_SIGNING_IDENTITY)
      - Provisioning Profile: $(APPLE_PROV_PROFILE_UUID)
      - Build ID: $(Build.BuildId)
      - Build Number: $(Build.BuildNumber)
      - Reason: $(Build.Reason)
      - Requested For: $(Build.RequestedFor)
      - Source Branch: $(Build.SourceBranch)
      - Last Commit ID: $(Build.SourceVersion)
      - Last Commit Comment: $(Build.SourceVersionMessage)
      - Release Note: $(ReleaseNote)
    destinationType: 'groups'

設定ファイルの全体図

最後に設定ファイルの全体図を載せます。

name: $(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)

trigger: none

pool:
  vmImage: 'macos-latest'

variables:
- group: Foo-iOS
- name: DEVELOPER_DIR
  value: '/Applications/Xcode_12.4.app/Contents/Developer'
- name: MINT_PATH
  value: 'mint/lib'
- name: MINT_LINK_PATH
  value: 'mint/bin'

steps:
# Xcodeのバージョン出力
- script: xcodebuild -version
  displayName: Show Xcode version

# Makeのバージョン出力
- script: make --version
  displayName: Show Make version

# Bundlerで管理しているライブラリのインストール
- script: make install-bundler
  displayName: Bundle install

# Mintのインストール
- script: brew install mint
  displayName: Install Mint

# ライセンス情報の生成
- script: make generate-licenses
  displayName: Generate licenses

# プロジェクトファイルの生成
- script: make generate-xcodeproj
  displayName: Generate Xcode project

# 証明書のインストール
- task: InstallAppleCertificate@2
  inputs:
    certSecureFile: 'Certificate.p12'
    certPwd: $(P12Password)
    keychain: 'temp'

# Provisioning Profileのインストール
- task: InstallAppleProvisioningProfile@1
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: 'Foo_AdHoc.mobileprovision'

# IPAファイルの生成
- script: make generate-ipa-adhoc
  displayName: Generate IPA file for Ad Hoc

# アーティファクトのステージングへコピー
- task: CopyFiles@2
  inputs:
    Contents: |
      **/xcodebuild_*.log
      **/*.xcarchive/**/*
      **/output/iphoneos/Release/*
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

# アーティファクトへアップロード
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

# App Centerへ配布
- task: AppCenterDistribute@3
  inputs:
    serverEndpoint: 'App Center'
    appSlug: '{Organization}/{App}'
    appFile: '**/*.ipa'
    releaseNotesOption: 'input'
    releaseNotesInput: |
      - Environment: 'Ad Hoc'
      - Configuration: Release
      - Certificate: $(APPLE_CERTIFICATE_SIGNING_IDENTITY)
      - Provisioning Profile: $(APPLE_PROV_PROFILE_UUID)
      - Build ID: $(Build.BuildId)
      - Build Number: $(Build.BuildNumber)
      - Reason: $(Build.Reason)
      - Requested For: $(Build.RequestedFor)
      - Source Branch: $(Build.SourceBranch)
      - Last Commit ID: $(Build.SourceVersion)
      - Last Commit Comment: $(Build.SourceVersionMessage)
      - Release Note: $(ReleaseNote)
    destinationType: 'groups'

おわりに

Azure PipelinesのYAMLでiOSアプリをApp Centerへ配布することができました!

fastlaneを使えばもう少しかんたんに実現できそうですが、知識不足なのでできませんでした…。

参考リンク

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?