この記事は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=NO
をUseModernBuildSystem=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 publish
やexpo build
によるアプリ配布・ビルドは非常に効率がよく、Expoなしの開発に少し不安がありましたが、bitriseのお陰でこの当たりの不便さは全く感じませんでした。
何かの参考になれば幸いです。
明日、12日目はmrtryさんの記事になります。
楽しみにしています!