React Native + CircleCIでCI/CD環境を構築する
こんにちは。graphy事業部の遠藤と申します。
今回は、React NativeとCircleCIの組み合わせでCI/CD環境を構築する機会がありましたので、その詳細について記載していきたいと思います。
CIツールの選定
CIツールはCircleCI、Bitrise、TravisCIなどいろいろありますが、調査した結果、大きく以下の理由でCircleCIを選択しました。
- ググったときの情報量が圧倒的に多い
- iOS、Androidアプリのビルド環境に対応している
- クライアント側・サーバー側共に同じCIツールが使える
- 費用を安く抑えてスタートできる
CI環境の構築中にハマってしまうと、何度もビルドを繰り返すことになって非常に時間がかかってしまいます。 情報量が多いと解決策を見つけやすい為、予算や工数を大きく割けないプロジェクトにとっては、大事なポイントになってくると考えています。
準備
CircleCIのアカウント準備やGitHubとの連携の話は、公式ドキュメントで詳しく解説されていますので割愛します。
また、記載する内容でfastlaneを利用したビルドコマンドを使う部分がある為、こちらのReact Nativeにfastlaneを導入する手順の記事を読んでおくと理解がしやすいと思います。
環境構築後のイメージはこのような感じです。
テスト版アプリの配信サービスにはVisual Studio App Studioを使用しています。
CircleCIの設定ファイルを追加
React Nativeプロジェクトのルートに.circleci/config.ymlを追加します。
フォルダ構成は以下のような形になっています。
以下のconfig.ymlの設定ではdevelopブランチに変更が入ったタイミングで、iOS/Androidそれぞれに対し、ビルドからデプロイまでが実行されるようになります。 ビルドからデプロイの処理は、fastlaneを使ってワンライナーで走らせられるようにしています。
# config.yml
version: 2.1
jobs:
android:
docker:
- image: circleci/android:api-27-node
steps:
- checkout
- run: bundle install --path vendor/bundle
- run: npm install
- run: bundle exec fastlane android build_dev
ios:
macos:
xcode: "10.1.0"
shell: /bin/bash --login -o pipefail
steps:
- checkout
- run: bundle install --path vendor/bundle
- run: npm install
- run: bundle exec fastlane ios build_dev
workflows:
android-ios:
jobs:
- android:
name: android_dev
filters:
branches:
only:
- develop
- ios:
name: ios_dev
filters:
branches:
only:
- develop
# Fastfile
platform :ios do
before_all do
setup_circle_ci
end
lane :build_dev do
match(
type: "adhoc",
app_identifier: "<BUNDLE IDENTIFIER>",
readonly: true
)
gym(
workspace: "ios/sample.xcworkspace",
output_directory: "ios",
scheme: "sample-dev",
export_options: {
method: "ad-hoc"
}
)
appcenter_upload(
api_token: "<API_TOKEN>",
owner_name: "<OWNER_NAME>",
app_name: "<APP_NAME>",
ipa: "ios/sample-dev.ipa",
notify_testers: true
)
end
end
platform :android do
lane :build_dev do
gradle(
task: "assembleDevRelease",
project_dir: "android"
)
appcenter_upload(
api_token: "<API_TOKEN>",
owner_name: "<OWNER_NAME>",
app_name: "<APP_NAME>",
apk: "android/app/build/outputs/apk/dev/sample-dev-release.apk",
notify_testers: true
)
end
end
config.ymlに記載した設定は以下のような流れになるように作られています。
- GitHubからソースコードをクローンしてくる
- npmとbundlerで依存ライブラリのインストール
- fastlaneコマンドでビルドからデプロイ
parametersを使用して一部のステップを変更する
CircleCIを利用していると、config.ymlに記載したステップのうち一部だけ変更したいことがあります。 CircleCIのバージョン2.1ではparametersの機能を利用することで、ステップの設定で変数を利用することができるようになります。
例えば、development/staging/production環境別にアプリをビルドしたいという状況はよくありますが、そんな状況でparametersは活用できます。
環境別にビルドができるように、以下のようにFastfileを更新したとします。
# Fastfile
platform :ios do
before_all do
setup_circle_ci
end
lane :build_dev do
# 省略
end
lane :build_stg do
# 省略
end
lane :build_prd do
# 省略
end
end
platform :android do
lane :build_dev do
# 省略
end
lane :build_stg do
# 省略
end
lane :build_prd do
# 省略
end
end
そして、parametersを利用して環境別のビルドに対応したconfig.ymlの中身は以下のようになります。
# config.yml
version: 2.1
jobs:
android:
# parameters追加
parameters:
env:
type: enum
enum: ["dev", "stg", "prd"]
docker:
- image: circleci/android:api-27-node
steps:
- checkout
- run: bundle install --path vendor/bundle
- run: npm install
# 変数を使用したコマンドに更新
- run: bundle exec fastlane android build_<< parameters.env >>
ios:
# parameters追加
parameters:
env:
type: enum
enum: ["dev", "stg", "prd"]
macos:
xcode: "10.1.0"
shell: /bin/bash --login -o pipefail
steps:
- checkout
- run: bundle install --path vendor/bundle
- run: npm install
# 変数を使用したコマンドに更新
- run: bundle exec fastlane ios build_<< parameters.env >>
workflows:
android-ios:
# iOSとAndroidそれぞれに対しstaging/production用のジョブを追加し、envを使って値を定義する
jobs:
- android:
name: android_dev
env: dev
filters:
branches:
only:
- develop
- android:
name: android_stg
env: stg
filters:
branches:
only:
- develop
- android:
name: android_prd
env: prd
filters:
branches:
only:
- develop
- ios:
name: ios_dev
env: dev
filters:
branches:
only:
- develop
- ios:
name: ios_stg
env: stg
filters:
branches:
only:
- develop
- ios:
name: ios_prd
env: prd
filters:
branches:
only:
- develop
workflowsの部分が少し冗長な感じになってしまいますが、この設定の状態でdevelopブランチに変更が入るとiOS/Androidそれぞれのdevelopment/staging/production用のビルドが同時に走るようになります。
開発中のアプリはdevelopment環境のアプリでチェックするのが基本だと思いますので、staging/production用のビルドはworkflows>jobs>branchesの設定をmasterブランチに設定しても良いかと思います。
まとめ
今回はReact NativeプロジェクトにCircleCIを導入して、CI/CD環境を作る手順について説明しました。
また、CircleCIはconfig.ymlに設定を記載してコードで管理できるので、メンテナンスがしやすいツールだと思いました。 React NativeでCIしたい方は、ぜひ今回の内容を参考にしてみてください。