「Azure PipelinesのYAMLでiOSアプリのCI/CD環境を構築する」は3部構成です。
記事を順番に読み進めると、Azure PipelinesでiOSアプリのCI/CD環境が構築できるようになります。
- 第一部:CI環境の構築
- 第二部:App Center配布パイプラインの構築
- 第三部:TestFlight配布パイプラインの構築 ←イマココ
はじめに
Azure Pipelinesを使い、iOSアプリをTestFlightへ配布するCDを構築します。
本記事で説明しないこと
- Azure Pipelinesの概要や基本的な操作方法
私が以前書いた記事が参考になると思います -
CI環境の構築とAppCenter配布パイプラインの構築で説明した内容
以前説明した内容を説明するのは冗長なのでしません
証明書とProvisioning Profileのアップロード
証明書とProvisioning ProfileをAzure Pipelines内の安全な場所へアップロードします。
AppCenter配布パイプラインの構築で紹介したので省略します。
App Store Connectのユーザー名とパスワードの追加
App Store Connectのユーザー名とパスワードをAzure Pipelinesの安全な場所で保持します。
AppCenter配布パイプラインの構築を参考に、 AppStoreConnectUserName
、 AppStoreConnectPassword
のようにわかりやすい名前で変数を追加してください。
パスワードにロックをかけるのを忘れないようにしましょう。
Apple IDに2ファクタ認証を設定している場合、パスワードはApp用パスワードを使う必要があります 。
App用パスワードの設定方法はこちらの記事をご参照ください。
Apple IDのパスワードを使った場合、認証が通らず以下のエラーになります。
$ xcrun altool --upload-app -f ./Foo.ipa -t ios -u {username} -p {password}
…
"Error Domain=ITunesSoftwareServiceErrorDomain Code=-22014 \"We are unable to create an authentication session.\" UserInfo={NSLocalizedDescription=We are unable to create an authentication session
Makefileの作成
IPAファイルのバリデーションやTestFlight配布などの実行コマンドをまとめたMakefileを作成します。
CI環境の構築とAppCenter配布パイプラインの構築で紹介したコマンドは省略します。
Makefile
APPSTORE_EXPORT_OPTIONS_PATH := ./ExportOptions/ExportOptionsAppStore.plist
としているので、このパスに.plistファイルを配置してください。
Xcode上からアーカイブ→エクスポートすると.plistが生成されるので、それをそのまま使うのがオススメです。
IPA_PATH := ${EXPORT_PATH}/${PRODUCT_NAME}.ipa
APPSTORE_PROVISIONING_PROFILE_SPECIFIER := Foo_AppStore
APPSTORE_EXPORT_OPTIONS_PATH := ./ExportOptions/ExportOptionsAppStore.plist
.PHONY: generate-ipa-appstore
generate-ipa-appstore: # Generate IPA file for App Store
$(MAKE) archive-appstore
$(MAKE) export-archive-appstore
.PHONY: archive-appstore
archive-appstore:
$(MAKE) archive PROVISIONING_PROFILE_SPECIFIER=${APPSTORE_PROVISIONING_PROFILE_SPECIFIER}
.PHONY: export-archive-appstore
export-archive-appstore:
$(MAKE) export-archive EXPORT_OPTIONS_PATH=${APPSTORE_EXPORT_OPTIONS_PATH}
.PHONY: validate
validate: # Validate IPA file # ASC_USERNAME=[user name] ASC_PASSWORD=[password]
xcrun altool --validate-app -f ${IPA_PATH} -t ios -u ${ASC_USERNAME} -p ${ASC_PASSWORD}
.PHONY: upload
upload: # Distribute IPA file to App Store Connect # ASC_USERNAME=[user name] ASC_PASSWORD=[password]
xcrun altool --upload-app -f ${IPA_PATH} -t ios -u ${ASC_USERNAME} -p ${ASC_PASSWORD}
今回のMakefileは、本記事で使うコマンドのみを抜粋および編集して紹介しています。
私が普段使っているMakefileの全容はこちらにあるので、よかったら参考にしてください。
設定ファイルの構成
CI環境の構築で紹介したので省略します。
各項目の紹介
各項目を上から順に紹介します。
name
CI環境の構築と同様なので省略します。
trigger
AppCenter配布パイプラインの構築と同様、私は手動で配布したいため、トリガーをOFFにしています。
trigger: none
pool
CI環境の構築と同様なので省略します。
variables
AppCenter配布パイプラインの構築と同様なので省略します。
steps
パイプライン内のステップを1つずつ紹介します。
ライブラリや証明書のインストールなど、CI環境の構築やAppCenter配布パイプラインの構築と同様のステップは省略します。
IPAファイルのバリデーション(任意)
IPAファイルをバリデーションします。
必須ではありませんが、配布前にアプリアイコンの画像が不足しているなどの問題に気づけます。
- script: make validate ASC_USERNAME=$(AppStoreConnectUserName) ASC_PASSWORD=$(AppStoreConnectPassword)
displayName: Validate IPA file
TestFlightへ配布
作成したIPAファイルをTestFlightへ配布します。
- script: make upload ASC_USERNAME=$(AppStoreConnectUserName) ASC_PASSWORD=$(AppStoreConnectPassword)
displayName: Distribute IPA file to TestFlight
設定ファイルの全体図
最後に設定ファイルの全体図を載せます。
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_AppStore.mobileprovision'
# IPAファイルの作成
- script: make generate-ipa-appstore
displayName: Generate IPA file for App Store
# アーティファクトのステージングへコピー
- 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'
# IPAファイルのバリデーション
- script: make validate ASC_USERNAME=$(AppStoreConnectUserName) ASC_PASSWORD=$(AppStoreConnectPassword)
displayName: Validate IPA file
# TestFlightへ配布
- script: make upload ASC_USERNAME=$(AppStoreConnectUserName) ASC_PASSWORD=$(AppStoreConnectPassword)
displayName: Distribute IPA file to TestFlight
おまけ:App Store Connect API
App Store Connect APIを使うと、ユーザー名やパスワードを指定せずにTestFlightへの配布などを自動化できるようです。
https://developer.apple.com/app-store-connect/api/
私は業務で使っているアカウントに権限がなかったので使えませんでした。
おわりに
Azure PipelinesのYAMLでiOSアプリをTestFlightへ配布することができました!
これでiOSアプリのCI/CD環境が整いました。
どんなアプリにも適用できるので、ぜひCI/CD環境構築の参考にしてください。