Flutterの自動ビルドをGithub ActionsとFirebaseで行う
Flutter #3 アドベントカレンダー 2020 - Qiita の20日目の記事です。
Flutterで開発中はホットリロードが使えるため、ビルドに困ることはありません。
しかし、いざ実機で確認しようと思うとビルド手順を忘れたり、ビルドに時間がかかって作業の手が止まることが多々あるかと思います。
今回はそれを解消するために、FlutterのCD環境をGithub ActionsとFirebase App Distributionを活用して準備しました。
前提
- コードのリポジトリ管理をGitHubで行っている
- FlutterにFirebaseを組み込んでいる
結論
実際にサンプルプロジェクトとして作ったコードを載せておきます。
GitHub Actionsのymlにはこちらの記事を参考にさせていただきました。
iOSの自動ビルド
name: iOS CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
# iOSビルド用にmacOSを使う(消費ビルド時間に注意)
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
# ProvisioningProfile をシークレットから取り出して、プロジェクトに無理やりセットする
- name: Import Provisioning Profile
run: |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
echo '${{ secrets.PROVISIONING_PROFILE }}' | openssl base64 -d -out ~/Library/MobileDevice/Provisioning\ Profiles/flutter_app_store.mobileprovision
# 証明書を設定
- name: Import Code-Signing Certificates
uses: Apple-Actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
- name: install flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '1.24.0-10.2.pre'
channel: 'beta'
- name: flutter dependencies install
run: flutter pub get
- name: build ipa
run: flutter build ios --release --no-codesign
- name: iOS Build Action
uses: yukiarrr/ios-build-action@v0.5.0
with:
project-path: ios/Runner.xcodeproj
p12-base64: ${{ secrets.CERTIFICATES_P12 }}
mobileprovision-base64: ${{ secrets.PROVISIONING_PROFILE }}
code-signing-identity: Apple Distribution
team-id: ${{ secrets.TEAM_ID }}
workspace-path: ios/Runner.xcworkspace
certificate-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
output-path: app-release.ipa
- name: Upload artifact
uses: actions/upload-artifact@v1.0.0
with:
name: ios
path: app-release.ipa
deploy:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# モジュールのダウンロード
- name: Download artifact
uses: actions/download-artifact@v1.0.0
with:
name: ios
# Firebase にデプロイ
- name: Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1.2.1
with:
appId: ${{secrets.FIREBASE_APP_ID_IOS}}
token: ${{secrets.FIREBASE_TOKEN}}
groups: testers
file: ios/app-release.ipa
Androidの自動ビルド
name: Android CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: install java 8.x
uses: actions/setup-java@v1
with:
java-version: '8.x'
- name: setup cache
uses: actions/cache@v1
with:
path: /Users/runner/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache
- name: install flutter
uses: subosito/flutter-action@v1
with:
flutter-version: '1.24.0-10.2.pre'
channel: 'beta'
- name: flutter dependencies install
run: flutter pub get
- name: build apk
run: |
echo '${{ secrets.KEYSTORE_BASE64 }}' | base64 -d > android/release.keystore
export KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}'
export KEY_ALIAS='${{ secrets.KEY_ALIAS }}'
export KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}'
flutter build apk --release
- name: Upload artifact
uses: actions/upload-artifact@v1.0.0
with:
name: android
path: build/app/outputs/flutter-apk/app-release.apk
deploy:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# モジュールのダウンロード
- name: Download artifact
uses: actions/download-artifact@v1.0.0
with:
name: android
# Firebase にデプロイ
- name: Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1.2.1
with:
appId: ${{secrets.FIREBASE_APP_ID_ANDROID}}
token: ${{secrets.FIREBASE_TOKEN}}
groups: testers
file: android/app-release.apk
なぜGithub ActionsとFirebase App Distributionなのか
以前は Bitrise を利用していたのですが、
- Xcodeのアップデート時にビルドが止まる(対応はすぐにしてくれました)
- FlutterにFirebaseを組み込んだときにビルド時間が大幅にかかって料金が上がってしまう
という点があったのでBitrise以外の以外のサービスを探したところ
- リポジトリの管理にGitHubを使っていた
- Firebaseをアプリに組み込んでいた
という状況で、GitHub ActionsとFirebase App DistributionでCD環境が構築できることを知り、この2つを利用することにしました。
Flutterのバージョンについて
今は beta
チャンネルで開発を進めているので、ビルドも beta
を使っています。
stable
が良い人は install flutter
の箇所で適宜適切な環境を設定すると良いでしょう。
flutter-version: '1.24.0-10.2.pre'
channel: 'beta'
Firebase App Distribution利用のうえでの注意
Firebase App Distributionを利用するうえで通常のビルドとは違う環境変数が必要になるので、記載しておきます。
FIREBASE_TOKEN
こちらは、Firebase CLI でログインしたときにtokenが表示されるので、
firebase login:ci
を実行してtokenを取得すれば大丈夫です。
Visit this URL on this device to log in:
Waiting for authentication...
✔ Success! Use this token to login on a CI server:
(ここにtokenが表示されます)
Example: firebase deploy --token "$FIREBASE_TOKEN"
FIREBASE_APP_ID_IOS, FIREBASE_APP_ID_ANDROID
こちらはFirebaseとiOS,Androidのアプリを連携したときに表示されるIDです。(Bundle IDやPackage Nameではありません)
Firebaseコンソールの設定画面から確認できます。
開発環境の切り替え
サンプルには記載していませんが、実際のプロジェクトでは、開発環境、ステージング環境、本番環境を切り替える必要があったので、monoさんの記事を参考に flavor
で環境を切り分けられるようにしました。
そのため、実際のプロジェクトでは build apk
build ipa
で実行するビルドコマンドを
flutter build apk --release --flavor staging
というように設定していています。
各環境へのデプロイは main
のところを対応するブランチ名に変えることで対応しました。
push:
branches: [ main ]
pull_request:
branches: [ main ]
課題
この方法でCD環境を作ったときに困ったことです。
- iOSの場合、macOSでのビルドであり、privateリポジトリの場合にはすぐにビルド時間を消費してしまう(masOSはビルド消費時間がubuntuの10倍のため)
- 同様の理由で、iOSのCDのテストをしようと思ったときにはactが使えないため、都度GitHub Actionsを実行する必要がある
これらの課題が解決または新たな課題が出てき次第更新していこうと思います。
最後まで読んでいただいてありがとうございました!
Discussion