• トップ
  • ブログ一覧
  • 【CI/CD】BitriseでDeployGateなiOSをFastlane matchでやってみる
  • 【CI/CD】BitriseでDeployGateなiOSをFastlane matchでやってみる

    笹川(エンジニア)笹川(エンジニア)
    2019.06.20

    IT技術

    第2弾~はじめに~

    秋山笹川先生

    (株)ライトコードの笹川(ささがわ)です!

    CIシリーズ第2弾です!

    引き続き、Bitriseの使い方を紹介します。

    前回の記事の宣言通り、今回は「iOS」です。

    iOSは、1ビルドあたり10分以内であれば、無料で利用できるのは魅力的ですね!

    前回の記事:【CI/CD】BitriseでDeployGateをAndroidでやってみる

    早速設定を始めてみましょう

    iOSビルドの環境はこちら

    1. CLIは、fastlane
    2. 証明書の設定は、Manual
    3. ビルド時にfastlane matchを利用
    4. Configrationは、「Debug」「Stage」「Release」の3種類
    5. 証明書もそれぞれ「Development」「Adhoc」「Appstore」となります。
    6. Xcodeは、10.2.1

    設定してみる

    今回は、Fastlane matchを利用したSigningを利用しますので、公式ドキュメント通りには進めません。

    とりあえず、fastlaneworkflowsに設定し、実行したいlaneを設定します。

    お察しの通りエラーが発生いたします…

    1[14:25:08]: Cloning remote git repo...
    2[14:25:08]: If cloning the repo takes too long, you can use the `clone_branch_directly` option in match.
    3Cloning into '/var/folders/6q/wgy6jtp12w5gzgm9lzcglpqw0000gn/T/d20190528-1491-1suoeby'...
    4fatal: could not read Username for 'https://github.com': terminal prompts disabled
    5[14:25:08]: Exit status: 128
    6[14:25:08]: Error cloning certificates repo, please make sure you have read access to the repository you want to use
    7[14:25:08]: Run the following command manually to make sure you're properly authenticated:
    8[14:25:08]: $ git clone https://github.com/[match用のリポジトリ].git /var/folders/6q/wgy6jtp12w5gzgm9lzcglpqw0000gn/T/d20190528-1491-1suoeby
    9+------------------+--------------------+
    10|             Lane Context              |
    11+------------------+--------------------+
    12| DEFAULT_PLATFORM | ios                |
    13| PLATFORM_NAME    | ios                |
    14| LANE_NAME        | ios deploy_develop |
    15+------------------+--------------------+
    16[14:25:08]: Error cloning certificates git repo, please make sure you have access to the repository - see instructions above

    Fastlane match を利用したドキュメントについては、記載が…ない!

    公式ドキュメントには下記のように書いてあります。

    サードパーティツールをcode signingの管理に利用する場合、そのツールのドキュメントやissueトラッカーを利用してください。

    Bitriseでは、こちらで用意したStep(Certificate and profile installer)やtools (codesigndoc)についてのカスタマーサポートは可能ですが、サードパーティツールについてのカスタマーサポートは行なっておりません。

    Fastlane matchのエラーを解消する

    ここからは、他のCIサービスなども含めて使い方を調査し試行錯誤することにしました。

    Fastlane matchを利用する際のパスワードの設定が漏れていました。

    こちらは Workflow EditerEnv VarsMATCH_PASSWORD に対して matchを利用する際のパスワードを設定しておきます。

    fastfileMatchfileなどへの記載は不要です。

    設定して、Rebuildします。

    match(sync_code_signing)の設定は、これで問題なしです。

    gymでのエラーを解消する

    matchが成功したあとは、また別のエラーが発生しました。

    1[15:00:36]: $ set -o pipefail && xcodebuild -workspace ./JENA_INTERVIEW.xcworkspace -scheme {ProjectFile} -destination 'generic/platform=iOS' -archivePath /Users/vagrant/Library/Developer/Xcode/Archives/2019-05-28/{ProjectFile}\ 2019-05-28\ 15.00.36.xcarchive archive | tee /var/folders/6q/wgy6jtp12w5gzgm9lzcglpqw0000gn/T/fastlane_logs916760609/gym/{ProjectFile}-{ProjectFile}.log | xcpretty
    2[15:00:38]:--- xcodebuild: WARNING: Using the first of multiple matching destinations:
    3[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    4[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    5[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    6[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    7[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    8[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    9[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    10[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    11[15:00:38]:{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    12[15:00:42]: ▸ ❌  error: No profile for team '{TeamID}' matching '{Adhoc ProvisioningProfile}' found: Xcode couldn't find any provisioning profiles matching '{TeamID}/{Adhoc ProvisioningProfile}'. Install the profile (by dragging and dropping it onto Xcode's dock item) or select a different one in the General tab of the target editor. (in target '{ProjectFile}')
    13[15:00:42]:** ARCHIVE FAILED **
    14--- xcodebuild: WARNING: Using the first of multiple matching destinations:
    15{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    16{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    17{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    18{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    19{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    20{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    21{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    22{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    23{ platform:iOS, id:dvtdevice-DVTiPhonePlaceholder-iphoneos:placeholder, name:Generic iOS Device }
    24❌  error: No profile for team '{TeamID}' matching '{Adhoc ProvisioningProfile}' found: Xcode couldn't find any provisioning profiles matching '{TeamID}/{Adhoc ProvisioningProfile}'. Install the profile (by dragging and dropping it onto Xcode's dock item) or select a different one in the General tab of the target editor. (in target '{ProjectFile}')
    25** ARCHIVE FAILED **
    26[15:00:42]: Exit status: 65
    27
    28~省略~
    29
    30[15:00:42]: ▸ note: Using new build system
    31[15:00:42]: ▸ note: Planning build
    32[15:00:42]: ▸ note: Constructing build description
    33[15:00:42]:Build system information
    34[15:00:42]: ▸ error: No profile for team '{TeamID}' matching '{Adhoc ProvisioningProfile}' found: Xcode couldn't find any provisioning profiles matching '{TeamID}/{Adhoc ProvisioningProfile}'. Install the profile (by dragging and dropping it onto Xcode's dock item) or select a different one in the General tab of the target editor. (in target '{ProjectFile}')

    こちらのビルドですが、Developmentの証明書を利用したビルドをする予定で Configration も Debug となっております。

    エラー文を見るとDevelopmentの証明書じゃなくて、Adhocの証明書を利用してビルドをしようと失敗しているようです。

    指定した証明書を利用するようにlaneの内容を書き換えます。
    (変数は、適宜置き換えてください。)

    laneの内容を書き換え

    1lane :develop_deploy do
    2  get_provisioning_profiles(type: "development")
    3
    4  settings_to_override = {
    5    :BUNDLE_IDENTIFIER => ENV["APP_ID"],
    6    :PROVISIONING_PROFILE_SPECIFIER => ENV["PROVISIONING_PROFILE_DEVELOPMENT"],
    7    :DEVELOPMENT_TEAM => ENV["FASTLANE_TEAM_ID"]
    8  }
    9
    10  gym(
    11    scheme: "{schema}",
    12    configuration: "Debug",
    13    export_method: "development",
    14    export_options: {
    15      provisioningProfiles: {
    16        ENV["APP_ID"] => ENV["PROVISIONING_PROFILE_DEVELOPMENT"]
    17        },
    18    }
    19  )
    20end

    設定してRebuildします。

    これで、gymの設定は問題ないです。

    Certificateのエラーを解消する

    上記のgymの設定が完了したあとに別のエラーが発生しました。

    1[13:57:34]: $ set -o pipefail && xcodebuild -workspace ./{ProjectFile}.xcworkspace -scheme {ProjectFile} -destination 'generic/platform=iOS' -archivePath /Users/vagrant/Library/Developer/Xcode/Archives/2019-06-01/{ProjectFile}\ 2019-06-01\ 13.57.34.xcarchive BUNDLE_IDENTIFIER={Application Id} PROVISIONING_PROFILE_SPECIFIER={Development ProvisioningProfile} DEVELOPMENT_TEAM={Team Id} archive | tee /var/folders/6q/wgy6jtp12w5gzgm9lzcglpqw0000gn/T/fastlane_logs410590617/gym/{ProjectFile}-JENA_INTERVIEW.log | xcpretty
    2[13:57:40]: ▸ ❌  error: No signing certificate "iOS Development" found: No "iOS Development" signing certificate matching team ID "{Team id}" with a private key was found. (in target '{ProjectFile}')
    3[13:57:40]:** ARCHIVE FAILED **

    どうやら、Certificateの署名そのものでエラーが発生しているようです。

    certificate-and-profile-installerWorkflows に追加します。

    Code Signing タブ」をタップし、「Developer用のCertificate」から「exportしたp12ファイル」をアップロードします。

    パスワードは、exportしたときに設定したものを入力してください。

    設定してRebuildします。

    cocoapodsのエラーを解消する

    自動でcocoapodsのバージョンがアップグレードされていました。

    そのため、Gemfileでcocoapodsのバージョンを指定するようにしたら、fastlaneでcocoapodsコマンドが失敗するようになってしまいました。

    1[16:13:27]: Exit status of command 'bundle exec pod install' was 1 instead of 0.
    2bundler: failed to load command: pod (/Users/vagrant/.rbenv/versions/2.5.3/bin/pod)
    3Bundler::GemNotFound: Could not find gem 'cocoapods (~> 1.7.0)' in any of the gem sources listed in your Gemfile.

    Scriptを追加

    こちらに関しては、下記のScriptを追加し対応しました。

    1    - script@1.1.5:
    2        title: Do anything with Script step
    3        inputs:
    4        - content: |-
    5            #!/usr/bin/env bash
    6
    7            bundle install --path vendor/bundle --jobs=2

    これで、cocoapodsのバージョン指定をしてもエラーが発生しなくなりました。

    DeployGateにアップロードする

    これでアプリケーションファイル出力のビルドは、問題なく実行できるようになりました。

    次に、出力したappファイルをDeployGateで配信できるようにします。

    こちらは、Bitriseのworkflowを利用せずにfastlaneで対応します。

    laneでの書き方はこちら

    1desc "Upload to Deploy Gate"
    2lane :upload_deploy_gate do
    3  deploygate(
    4    api_token: ENV['DEPLOYGATE_API_KEY'],
    5    user: ENV['DEPLOYGATE_USER'],
    6    message: "{DeploGateの対象ファイルに対するメッセージ}",
    7  )
    8end

    gymコマンドのあとに、こちらを呼び出せばアップロードが行われます。

    Deploy to Bitrise.ioで保存されるようにする

    DeployGate には、アップロードできるようになりましたが、appファイルとdYSMファイルを別途保管していることが多いのでこちらも設定します。

    fastlane で出力先を指定せずにgymを実行すると、プロジェクトルートにファイルが出力されます。

    ですから、Artifacts として保存しておきたい場合は、以下のどちらかになります。

    1. fastlaneで出力したファイルを移動する
    2. Artifactsとして参照するパスを変更する

    Bitriseの仕様としての正解はわかりませんが、Workflow側で細かい設定をすると後に影響しそうでしたので前者で対応することにしました。

    Scriptを追加

    具体的な方法としては、Workflowのfastlaneの次にScriptを追加します。

    1- script@1.1.5:
    2    inputs:
    3    - content: |-
    4        #!/usr/bin/env bash
    5        cp $BITRISE_SOURCE_DIR/{App Name}.ipa $BITRISE_DEPLOY_DIR/{App Name}.ipa
    6        cp $BITRISE_SOURCE_DIR/{App Name}.app.dSYM.zip $BITRISE_DEPLOY_DIR/{App Name}.app.dSYM.zip

    デフォルトのDeployディレクトリに対してcpコマンドでファイルをコピーしています。

    これで無事、Aritfactsにもファイルが保存されるようになりました。

    さいごに

    Androidの設定をした記事でも述べたように、BitriseではGUIでCI設定ができるのは利点の一つです。

    今回のようにfastlane matchを利用した場合に、「どんなエラーが出て」「どんな対応をするか」は探しても見つかりませんでした。

    iOSの証明書管理によく利用される fastlane match ですが、実際に採用している人も多いのではないでしょうか。

    この記事が誰かの役に立ってくれたら幸いです!

    オススメ本

    iOSアプリ開発自動テストの教科書 〜XCTestによる単体テスト・UIテストから,CI/CD,デバッグ技術まで
    iOSアプリ開発自動テストの教科書 〜XCTestによる単体テスト・UIテストから,CI/CD,デバッグ技術まで

     

    こちらの記事もオススメ!

    featureImg2020.08.14スマホ技術 特集Android開発Android開発をJavaからKotlinへ変えていくためのお勉強DelegatedPropert...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    関連記事

    featureImg2019.06.18【CI/CD】BitriseでDeployGateをAndroidでやってみた第1弾~はじめに~笹川先生(株)ライトコードの笹川(ささがわ)です!弊社ブログの中で、あまりCIについて触れているもの...

    featureImg2019.06.20【CI/CD】BitriseでDeployGateなiOSをFastlane matchでやってみる第2弾~はじめに~笹川先生(株)ライトコードの笹川(ささがわ)です!CIシリーズ第2弾です!引き続き、Bitriseの...

    featureImg2019.07.02【CI/CD】BitriseでDeployGateなFlutterのAndroidとiOSをやってみる第3弾~はじめに~笹川先生(株)ライトコードの笹川(ささがわ)です!CIシリーズ第3弾です!引き続きBitriseの使...

    最終的に出来上がったymlファイル

    1---
    2format_version: '7'
    3default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
    4project_type: ios
    5trigger_map:
    6- push_branch: develop
    7  workflow: deploy_develop
    8- push_branch: stage*
    9  workflow: deploy_stage
    10- push_branch: release*
    11  workflow: deploy_appstore
    12workflows:
    13  code_sign:
    14    steps:
    15    - activate-ssh-key@4.0.3:
    16        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    17    - git-clone@4.0.14: {}
    18    - cache-pull@2.0.1: {}
    19    - certificate-and-profile-installer@1.10.1: {}
    20    - script@1.1.5:
    21        title: Do anything with Script step
    22        inputs:
    23        - content: |-
    24            #!/usr/bin/env bash
    25
    26            bundle install --path vendor/bundle --jobs=2
    27    after_run: []
    28  deploy_develop:
    29    steps:
    30    - fastlane@2.4.0:
    31        inputs:
    32        - lane: develop_deploy
    33    - script@1.1.5:
    34        inputs:
    35        - content: |-
    36            #!/usr/bin/env bash
    37            cp $BITRISE_SOURCE_DIR/{App Name}.ipa $BITRISE_DEPLOY_DIR/{App Name}.ipa
    38    before_run:
    39    - code_sign
    40    after_run:
    41    - deploy_to_bitrise
    42    description: 'Upload to Deploygate of Development build '
    43  deploy_appstore:
    44    steps:
    45    - fastlane@2.4.0:
    46        inputs:
    47        - lane: appstore_deploy
    48    - script@1.1.5:
    49        inputs:
    50        - content: |-
    51            #!/usr/bin/env bash
    52            cp $BITRISE_SOURCE_DIR/{App Name}.ipa $BITRISE_DEPLOY_DIR/{App Name}.ipa
    53            cp $BITRISE_SOURCE_DIR/{App Name}.app.dSYM.zip $BITRISE_DEPLOY_DIR/{App Name}.app.dSYM.zip
    54    before_run:
    55    - code_sign
    56    after_run:
    57    - deploy_to_bitrise
    58  deploy_stage:
    59    steps:
    60    - fastlane@2.4.0:
    61        inputs:
    62        - lane: stage_deploy
    63    - script@1.1.5:
    64        inputs:
    65        - content: |-
    66            #!/usr/bin/env bash
    67            ls $BITRISE_SOURCE_DIR
    68            cp $BITRISE_SOURCE_DIR/{App Name}.ipa $BITRISE_DEPLOY_DIR/{App Name}.ipa
    69            cp $BITRISE_SOURCE_DIR/{App Name}.app.dSYM.zip $BITRISE_DEPLOY_DIR/{App Name}.app.dSYM.zip
    70    before_run:
    71    - code_sign
    72    after_run:
    73    - deploy_to_bitrise
    74  deploy_to_bitrise:
    75    steps:
    76    - deploy-to-bitrise-io@1.4.2: {}
    77    - cache-push@2.2.0: {}
    78    before_run: []
    79app:
    80  envs:
    81  - opts:
    82      is_expand: false
    83    BITRISE_PROJECT_PATH: {App Name}.xcworkspace
    84  - opts:
    85      is_expand: false
    86    BITRISE_SCHEME: Debug
    87  - opts:
    88      is_expand: false
    89    BITRISE_EXPORT_METHOD: development
    90  - opts:
    91      is_expand: false
    92    MATCH_PASSWORD: "{MATCH_PASSWORD}"

     

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    笹川(エンジニア)

    笹川(エンジニア)

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background