ionic(cordova) CircleCI2とFastlaneでiOSアプリをデプロイゲートにアップロードする手順まとめ
はじめに
今回やりたかったことは
・ionicで開発したiOSアプリをCircleCI2上でAdHoc版ビルド
・ビルドしたアプリをデプロイゲートへアップロード
・Fastlane Matchは使わず手元にある証明書とプロビジョニングプロファイルで行う
ビルドとアップロードはFastlaneというツールを使う
必要なもの
・証明書
キーチェーンアクセスから書き出す「iPhone Distribution:xxxxxxxxxxx(xxxxxx)」いつものp12ファイル。
・プロビジョニングプロファイル
・デプロイゲートのAPIキーとアカウント名
流れ
CircleCI上で証明書等を予め登録しておく
・証明書とプロビジョニングプロファイルをCircleCI上に暗号化して登録(環境変数を利用)
・デプロイゲートのアカウントとAPIキーもCircleCI上に登録(環境変数を利用)
https://circleci.com/gh/[githubアカウント]/[リポジトリ名]/edit#env-vars
↑ここから登録できる
以下を用意
・.circleci/config.yml
・fastlane/Fastfile
イメージとしては普段macでおこなっている作業をCircleCI上のmacで行うだけ。
・cordova、ionic と依存するnode_modulesのインストール
・予め登録した証明書とプロビジョニングプロファイルを復号化してマシンにインストール
・インストールした証明書等を使ってアプリをビルド
・予め登録したデプロイゲートの情報を使って、デプロイゲートへアップロード
ハマったこと
証明書とプロビジョニングプロファイルを正しく指定してるのにSigning Errorが消えない
エラー
Code Signing Error: Signing for "circleci_demo" requires a development team. Select a development team in the project editor. Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 11.2'
xcodeでいうところの「Automatically manage signing」がONになっている状態だとエラーになってしまっていた。
ONが奨励されてる?のかわからないけど今回はこれをOFFにすることで解決した。
後述するFastlane の disable_automatic_code_signing メソッドを使うとOFFになる。
cordova-iosが生成するxcodeの project.pbxproj ファイルの形式が不完全
エラー
Seems to be a very old project file format - please open your project file in a more recent version of Xcode
TargetAttributes属性がないとFastlaneがこのエラーで終了してしまう。
Cordovaで生成した直後のプロジェクトだとこの属性がないらしい(最新のcordova-iosでは改善してるかも)
で、platforms/ios/circleci_demo.xcodeproj/project.pbxproj もgitで管理してビルドする前にこのファイルを使うことで解決することにした。
アーカイブに成功してエクスポートでエラー
エラー
Exit status: 70 No provisioning profile provided Make sure to pass a valid provisioning for each required target Check out the docs on how to fix this: https://github.com/fastlane/fastlane/tree/master/gym#export-options
よくわかってないのだが、xcodebuildでのアーカイブで出力されるplistをエクスポートの際に使用するようなのだが、それが正しくないらしい。スタックオーバーフローとか見てると、xcode上でエクスポートする際に作られるExportOptions.plistを使うと良いらしい。これもGitで管理するようにしてFastfileで指定することで解決した。gymのexport_optionsで指定可能でした。
実装
証明書とプロビジョニングプロファイルをCircleCI2に登録
$ base64 -i xxxxx.p12 | pbcopy $ base64 -i xxxxx. mobileprovision | pbcopy
こちらのページに細かく書かれている(というかまんま)
http://developabout0309.blogspot.com/2018/05/circleci20fastlanefabric_1.html
今回は以下の変数名で登録した
CERTIFICATES : pm12ファイル
PROVISIONING_PROFILES : プロビジョニングプロファイル
DEPLOYGATE_USER : デプロイゲートのアカウント
DEPLOYGATE_API_KEY : デプロイゲートのAPIキー
.circleci/config.yml
version: 2 jobs: build: macos: xcode: "9.2.0" shell: /bin/bash --login working_directory: ~/workspace steps: - checkout - run: name: install ionic command: | # Ionicインストール npm install -g cordova@6.5.0 npm install -g ionic@2.2.3 npm install # 最新のcordova-iosでプロジェクト作成 ionic platform rm ios ionic platform add ios@4.5.4 ionic prepare - run: name: build and upload deploygate command: | # stagingブランチの場合、デプロイゲートへアップロード if [ "${CIRCLE_BRANCH}" == "staging" ]; then # 証明書をデコード base64 -D -o circleci_demo.p12 <<< $CERTIFICATES # プロビジョニングプロファイルのインストール mkdir -pv ~/Library/MobileDevice/Provisioning\ Profiles/ base64 -D -o ~/Library/MobileDevice/Provisioning\ Profiles/CircleCI_Adhoc.mobileprovision <<< $PROVISIONING_PROFILES # xcodeprojファイルをチェックアウト git checkout platforms/ios/circleci_demo.xcodeproj/project.pbxproj # AdHocビルド fastlane ios build # デプロイゲートへアップロード fastlane ios upload_deploygate # masterブランチの場合、AppStoreへアップロード elif [ "${CIRCLE_BRANCH}" == "master" ]; then fi
fastlane/Fastfile
platform :ios do desc "Build for iOS" lane :build do if is_ci? setup_circle_ci import_certificate( keychain_name: ENV["MATCH_KEYCHAIN_NAME"], keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"], certificate_path: 'circleci_demo.p12', certificate_password: '' ) end update_app_identifier( xcodeproj: "platforms/ios/circleci_demo.xcodeproj", plist_path: "circleci_demo/circleci_demo-Info.plist", app_identifier: 'ciecleci.test' ) disable_automatic_code_signing( path: "platforms/ios/circleci_demo.xcodeproj" ) gym( scheme: 'circleci_demo', workspace: 'platforms/ios/circleci_demo.xcworkspace', configuration: 'Debug', export_method: "ad-hoc", clean: true, verbose: true, output_directory: "build", output_name: "circleci_demo", xcargs: "OTHER_SWIFT_FLAGS='$(inherited) -DSTGING' PROVISIONING_PROFILE_SPECIFIER='CircleCI Adhoc' CODE_SIGN_IDENTITY='iPhone Distribution'", export_xcargs: "-allowProvisioningUpdates", export_options: "fastlane/ExportOptions.plist" ) end desc "Upload To Deploygate" lane :upload_deploygate do deploygate( api_token: ENV["DEPLOYGATE_API_KEY"], user: ENV["DEPLOYGATE_USER"], ipa: "build/circleci_demo.ipa" ) sh "rm -rf ../build" end end
こんなもんかな。以上です。