LoginSignup
26
14

More than 3 years have passed since last update.

React NativeのiOS/Androidビルドするbitrise.ymlを晒してみる&ビルド高速化など

Last updated at Posted at 2019-12-10

この記事はReact Native Advent Calendar 2019の11日目の記事です。

はじめに

こんにちは。
React Native開発3年目のワダ(@takahi5)です。

現在React Native(Expoなし)でiOS/Androidのアプリを開発しています。
bitriseでビルドを自動化しているのですが、おかげで運用が非常に楽になりました♪

一方でネイティブ知識の不足からか、はじめのセットアップには手間取りました。

先人の残してくれた資料に助けられたのですが、bitriseの進化もあり資料の通りには行かない部分もありました。
そこで、2019年現在、利用しているbitrise.ymlを晒したいと思います!

bitriseとは

モバイル開発に特化したCIです。
Circle CIやgithub actionsと同じ類のものですが、モバイル特化という部分が特徴になります。
React Native用のワークフローも雛形を自動で作成してくれます。

無料でも使えますが、無料プランだとビルド時間10分でタイムアウトするため、React Native(特にiOS)をビルドする場合は有料プランに入る必要があると思います。
僕のチームでは$36/月のプランを使っています。

iOSビルドのbitrise.yml

まずiOSです。

このワークフローをmasterブランチへのpushをトリガーにして実行しています。

チーム内へのアプリ配布はTestFlightを利用していますが、
このワークフローではitune connectにipaファイルをアップロードするところまでしか対応していないので、最後にTestFlight配信するところは手動でやっています。
この作業も自動化できるといいですね。

審査への提出も最後のポチッは手動でやっています。


  deploy-ios:
    description: "(略)"
    steps:
    - activate-ssh-key@4.0.3:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@4.0.17: {}
    - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash

            echo $ENV_FILE | base64 --decode > .env
    - cache-pull@2.1.1: {}
    - yarn@0.0.8:
        inputs:
        - command: install
    - install-react-native@0.9.2:
        inputs:
        - version: 2.0.1
    - cocoapods-install@1.9.0:
        inputs:
        - podfile_path: "./ios/Podfile"
        is_always_run: true
    - set-xcode-build-number@1.0.8:
        inputs:
        - build_short_version_string: "$APP_VERSION"
        - plist_path: "./ios/your-app-name/Info.plist"
    - certificate-and-profile-installer@1.10.1: {}
    - xcode-archive@2.6.0:
        inputs:
        - project_path: "$BITRISE_PROJECT_PATH"
        - scheme: "$BITRISE_SCHEME"
        - export_method: app-store
        - team_id: "$IOS_TEAM_ID"
        - force_team_id: "$IOS_TEAM_ID"
        - force_code_sign_identity: iPhone Distribution
        - force_provisioning_profile_specifier: ''
        - force_provisioning_profile: "$PROVISIONING_PROFILE"
        - xcodebuild_options: CODE_SIGN_STYLE="Manual" -UseModernBuildSystem=YES
        - configuration: Release
    - cache-push@2.2.1:
        inputs:
        - cache_paths: |-
            $BITRISE_CACHE_DIR
            node_modules -> yarn.lock
    - deploy-to-bitrise-io@1.9.2: {}
    - deploy-to-itunesconnect-application-loader@0.10.1:
        inputs:
        - password: "$APPLE_ID_PASSWORD"
        - app_password: "$APPLE_APP_SPECIFIED_PASSWORD"
        - itunescon_user: "$APPLE_ID"
    - ipa-info@1.1.0: {}
    - slack@3.1.3:
        inputs:
        - buttons: View Build|${BITRISE_BUILD_URL}
        - webhook_url: "$SLACH_CHANNEL_ENGINEERING"
        - channel: "#engineering"
        - from_username: Bitrise(iOS)
        - fields: |-
            App|${IOS_APP_NAME}
            Version|${IOS_APP_VERSION_NAME}
            Branch|${BITRISE_GIT_BRANCH}
            Build#|${BITRISE_BUILD_NUMBER}
            Message|${BITRISE_GIT_MESSAGE}
    meta:
      bitrise.io:
        stack: osx-xcode-11.2.x

補足

細かい設定について補足させていただきます。

バージョン名やビルド番号をbitrise側で設定する

バージョン名(1.2.0など)とビルド番号(毎回インクリメントする通し番号)をbitrise側で指定しています。

バージョン名は環境変数$APP_VERSIONに指定しているので、バージョンを上げたいときは手動で環境変数を変更しています。

ビルド番号はbitriseビルドの通し番号が自動的に使われるので、毎回変更する作業が不要になりとても便利です。

    - set-xcode-build-number@1.0.8:
        inputs:
        - build_short_version_string: "$APP_VERSION"
        - plist_path: "./ios/your-app-name/Info.plist"

Slack通知

Slackのwebhook を指定すればOKです。
ここは標準的な設定です。

 - slack@3.1.3:
        inputs:
        - buttons: View Build|${BITRISE_BUILD_URL}
        - webhook_url: "$SLACH_CHANNEL_ENGINEERING"
        - channel: "#engineering"
        - from_username: Bitrise(iOS)
        - fields: |-
            App|${IOS_APP_NAME}
            Version|${IOS_APP_VERSION_NAME}
            Branch|${BITRISE_GIT_BRANCH}
            Build#|${BITRISE_BUILD_NUMBER}
            Message|${BITRISE_GIT_MESSAGE}

.envの配置

このアプリではAPI KEYなどを.envファイルで管理しており、このファイルはgithubリポジトリに上げていないため、bitriseビルド時になんらかの方法で配置してあげる必要がありました。

ここでは.envファイルをbase64エンコードしたものをbitriseの環境変数$ENV_FILEに格納しておいて、ビルド時にデコードするようにしました。

もし.envを利用している場合は参考になるかと思います。


   - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash

            echo $ENV_FILE | base64 --decode > .env

iOSのビルドを速くするためにやったこと

もともとビルド時間が非常に長く40分〜45分くらいかかっており、ベーシックプランだと45分でタイムアウト終了してしまうので、bitriseのご機嫌次第ではビルドができない事がありました。

そこで設定を見直した結果、ビルド時間は25分程に短縮され安心してビルドできるようになりました。

このプロジェクト特有の問題もありましたが、何らかの参考になればと共有したいと思います。

UseModernBuildSystem

これがほぼ原因だったのですが、UseModernBuildSystem=NOUseModernBuildSystem=YESに変更することで大幅に改善されました。
特に指定しなければデフォルトではYESになっているので問題ないと思います。

    - xcode-archive@2.6.0:
        - (中略)
        - xcodebuild_options: CODE_SIGN_STYLE="Manual" -UseModernBuildSystem=YES

もともとUseModernBuildSystem=NOに設定した経緯としては、react-native-vector-iconを導入した際にビルドが失敗するようになり、NOに設定することで解消したからでした。
しかし実際にはreact-native-vector-icon導入時の設定にミスがあったのが原因で、それを直すことで根本解決YESでもビルドが通るようになりました。

キャッシュの設定

これは基本的な設定ですが、これにより1分ほど速くなりました。

Podsファイルのキャッシュは特に何も指定しなくても大丈夫ですが、node_nodulesのキャッシュは下記の指定が必要になります。

    - cache-pull@2.1.1: {}
    - (中略)
    - cache-push@2.2.1:
        inputs:
        - cache_paths: |-
            $BITRISE_CACHE_DIR
            node_modules -> yarn.lock

Androidビルドのbitrise.yml

続いてAndroidのビルドです。

iOSと同様にキャッシュの利用や.envの配置をしています。

iOSとワークフローを分けていますが、合体してもよいかなと思います。

  deploy-android:
    description: "(略)"
    steps:
    - activate-ssh-key@4.0.3:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@4.0.17: {}
    - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash

            echo $ENV_FILE | base64 --decode > .env
    - cache-pull@2.1.2: {}
    - yarn@0.0.8:
        inputs:
        - command: install
    - install-react-native@0.9.2:
        inputs:
        - version: 2.0.1
    - install-missing-android-tools@2.3.7:
        inputs:
        - gradlew_path: "$PROJECT_LOCATION/gradlew"
    - set-android-manifest-versions@1.0.5:
        inputs:
        - version_name: "$APP_VERSION"
        - manifest_file: "./android/app/src/main/AndroidManifest.xml"
    - gradle-runner@1.8.3:
        inputs:
        - gradlew_path: "./android/gradlew"
        - gradle_file: "./android/build.gradle"
        - gradle_task: assembleRelease
    - sign-apk@1.4.1: {}
    - cache-push@2.2.3:
        inputs:
        - cache_paths: |-
            $BITRISE_CACHE_DIR
            node_modules -> yarn.lock
    - deploy-to-bitrise-io@1.7.1: {}
    - slack@3.1.3:
        inputs:
        - buttons: |-
            Install APK|${BITRISE_PUBLIC_INSTALL_PAGE_URL}
            View Build|${BITRISE_BUILD_URL}
        - webhook_url: "$SLACH_CHANNEL_ENGINEERING"
        - channel: "#engineering"
        - footer: Bitrise(Android)
        - from_username: Bitrise(Android)
        - fields: |-
            App|${BITRISE_APP_TITLE}
            Version|${APP_VERSION}
            Branch|${BITRISE_GIT_BRANCH}
            Build#|${BITRISE_BUILD_NUMBER}
            Message|${BITRISE_GIT_MESSAGE}

チームへのAPK配布

ビルド完了するとSlack通知していますが、Slackメッセージの中にAPKのダウンロード導線を載せています。
(下記のInstall APK|${BITRISE_PUBLIC_INSTALL_PAGE_URL}部分)

チームへ確認用アプリを配布する際は、Slack通知から直接APKをダウンロードしています。

 - slack@3.1.3:
        inputs:
        - buttons: |-
            Install APK|${BITRISE_PUBLIC_INSTALL_PAGE_URL}
            View Build|${BITRISE_BUILD_URL}

まとめ

以上になります。

今までは永らくExpoでアプリを開発していて、ExpoなしのReact Nativeアプリの開発は今回が初めてでした。
Expoのexpo publishexpo buildによるアプリ配布・ビルドは非常に効率がよく、Expoなしの開発に少し不安がありましたが、bitriseのお陰でこの当たりの不便さは全く感じませんでした。

何かの参考になれば幸いです。

明日、12日目はmrtryさんの記事になります。
楽しみにしています!

26
14
1

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
14