26
13

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.

Bitriseを利用してミニマルにiOSのCI / CD環境を構築する

Last updated at Posted at 2021-08-25

この記事では、Bitriseを利用してiOSのCI/CDを構築します。
CI/CD環境の構築は日頃アプリを作るエンジニアにとっては慣れない作業であり、
利用するCIサービスによってやり方は異なるので、他のサービスを構築した知見が活きにくいものです。
また、チームの中でもCertificatesやProvisioning Profileといった、XcodeのCode Signingは経験がないとDeveloperであってもセットアップに苦慮するという状況にあります。

この記事で案内する方法は、BitriseのStepとApp Store Connect APIを利用します。
これによりCode Signingの管理を簡単にし、配布もTest Flightにすることで、できるだけミニマルにCI/CDを構築することができます。

2022/01/26 更新
ios-auto-provision-appstoreconnect step がdeprecatedとなり、各ステップに automatic_code_signing: api-key を指定するようになりました。

基本的なセットアップ

Bitriseの管理画面にある Add New Appの手順に従い進めます。
最初のビルドが終わった時点で次の手順に進みます。

特筆することは特にありません。

目指すもの

次の2つができれば、ひとまずやりたいことは満たせるでしょう。

  • Unit Testを実行する
  • Test FlightでStaging / Production環境のアプリを配布する

Unit Testの実行に必要なのはShared Scheme

Xcode上でSchemeを選択し、 Manage Schemes... 選択します。
CIで利用したいSchemeにSharedのチェックを入れます。
gitに含めてPushすることで、CI上でcloneしたときに利用できるようになります。

Schemeを作った場合は、Testが追加されていることを確認します。
Screen Shot 2021-08-25 at 16.46.50.png

ローカル環境に fastlane は必要かを考える

fastlaneはiOSアプリのビルドや配布を自動化するツールです。

iOSアプリのビルドや配信の自動化には xcodebuildxcrun といった、Xcode同梱のコマンドラインツールを利用することができます。
fastlaneには、Certificate や Provisioning Profile を管理する仕組みも備わっています。
従来は fastlane なしでの開発は考えられないほど恩恵を大きく受けていました。

しかしながら、CI 環境で Ruby のセットアップが必要であったり、fastlane match の導入によりかえって証明書や Provisioning Profile の管理が煩雑になってしまっているのも事実です。

CocoaPodsを利用している場合はRubyのセットアップは求められるので問題ないですが、Swift Package Managerを利用している場合、fastlaneのためにRubyのセットアップをするのは少々ためらわれます。

Bitriseでは、xcodebuildxcrun を利用したStepが作られてる他、内部ではfastlaneに依存しているものもあり、ローカル環境で fastlane を導入しなくとも fastlane の恩恵を受けることができます。

Bitrise に預けるのは Certificate と API Key

他のCI環境に比べて、Bitriseの開発体験がよいところがこのCertificateをアップロードするGUIが備わっていることです。
他のCIでは fastlane match を利用してCertificateを管理すると記載があります。

例: Circle CI https://circleci.com/docs/2.0/ios-codesigning/

Note: CircleCI only officially supports Fastlane Match for code signing. Other methods may be used, but are not guaranteed to work and are unsupported.

厳密に管理がなされれば良いのは、Distribution Certificateのみで、App StoreやTest Flightで利用するapp-storeのProvisioning Profileは、なければ都度生成して問題ありません。

Bitriseの iOS Auto Provisioning Stepではこの方式が取られており、とてもリーズナブルです。
Xcode archiveで automatic_code_signing を指定するように変更となりました。
(すでに存在している場合はそのProvisioning Profileを利用します)

Automatic Signingに対応しているので、Provisioning Profileを固定する必要はありません。

背景と設定手順この記事にまとめましたAd hoc配信をやめてTestFlightで配信する

実はこれで終わり

実はこれ以上書くことはないほどにBitriseのセットアップは簡単です。
次に記載するyamlの内容で、Pull Requestが作成されたらTestが動いたり、main ブランチにマージコミットされたらStaging用のTest Flightアプリが配布されるところまで実現できます。

Production用のアプリはBitriseのGUIから実行させたり、専用のトリガーを作って外部から起動させるという方法も取れます。

実際のbitrise.yml

関わっているプロジェクトで運用されているbitrise.ymlは次の通りです。

format_version: "11"
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: ios
workflows:
  _finish:
    steps:
      - slack:
          inputs:
            - api_token: "$SLACK_API_TOKEN"
            - webhook_url: "$SLACK_WEBHOOK_URL"
      - cache-push: {}
  _prepare:
    steps:
      - activate-ssh-key:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - script:
          inputs:
            - content: |-
                #!/usr/bin/env bash
                set -ex
                for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan github.com,$ip; ssh-keyscan $ip; done 2>/dev/null >> ~/.ssh/known_hosts
          title: Add SSH
      - git-clone: {}
      - cache-pull: {}
      - script:
          title: Prepare CLI
          run_if: ".IsCI"
          inputs:
            - is_debug: "yes"
            - content: |-
                #!/usr/bin/env bash
                set -eux

                make bootstrap
  deliver-staging:
    steps:
      - ios-auto-provision-appstoreconnect:
          inputs:
            - distribution_type: app-store
            - scheme: Staging
            - api_issuer: "$APP_STORE_CONNECT_API_KEY_ISSUER_ID"
            - api_key_path: "$BITRISEIO_APPSTORE_CONNECT_API_KEY_URL"
      - set-xcode-build-number:
          inputs:
            - plist_path: "$BITRISE_SOURCE_DIR/App/iOS/Info.plist"
      - xcode-archive:
          inputs:
            - export_method: app-store
            - scheme: Staging
            - team_id: "$BITRISE_APPSTORE_TEAM_ID"
      - deploy-to-itunesconnect-application-loader:
          inputs:
            - api_key_path: "$BITRISEIO_APPSTORE_CONNECT_API_KEY_URL"
            - api_issuer: "$APP_STORE_CONNECT_API_KEY_ISSUER_ID"
            - team_id: "$BITRISE_APPSTORE_TEAM_ID"
    before_run:
      - _prepare
    after_run:
      - _finish
  deliver-production:
    steps:
      - set-xcode-build-number:
          inputs:
            - plist_path: "$BITRISE_SOURCE_DIR/App/iOS/Info.plist"
      - xcode-archive:
          inputs:
            - export_method: app-store
            - scheme: App
            - distribution_method: app-store
            - automatic_code_signing: api-key
            - team_id: "$BITRISE_APPSTORE_TEAM_ID"
      - deploy-to-itunesconnect-application-loader:
          inputs:
            - api_key_path: "$BITRISEIO_APPSTORE_CONNECT_API_KEY_URL"
            - api_issuer: "$APP_STORE_CONNECT_API_KEY_ISSUER_ID"
            - team_id: "$BITRISE_APPSTORE_TEAM_ID"
    before_run:
      - _prepare
    after_run:
      - _finish
  test:
    steps:
      - xcode-test:
          inputs:
            - scheme: AppFeature
            - simulator_device: iPhone 12
            - simulator_os_version: "14.5"
            - project_path: "$BITRISE_PROJECT_PATH"
    before_run:
      - _prepare
    after_run:
      - _finish
app:
  envs:
    - opts:
        is_expand: false
      BITRISE_PROJECT_PATH: xxxxxxxx.xcworkspace
    - opts:
        is_expand: false
      BITRISE_APPSTORE_TEAM_ID: XXXXXXXXXX
trigger_map:
  - push_branch: main
    workflow: deliver-staging
  - pull_request_target_branch: "*"
    workflow: test

FAQ

Q. デバイスをDeveloper Portalに追加する必要ないのですか?

TestFlightで配布する場合は、Provisioning Profileにデバイスを登録する必要がありません。

Q. fastlane deliverでメタデータのアップデートを行なってました

deploy-to-itunesconnect-deliver を利用すると、中では fastlane deliverを利用しているので、オプションにKey Valueを渡すことで同じように利用することができます。

筆者が試したときは、 deploy-to-itunesconnect-deliver がうまく動かず、 deploy-to-itunesconnect-application-loader でユースケースは満たせたので、こちらを利用しています。

Reference

26
13
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
26
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?