メモ2ブログ

メモtoウェブログ。旧ブログはこちら。 http://sakebook.blogspot.jp/

Flutter for WebのプロジェクトをGitHub ActionsでFirebase Hostingにデプロイする

タイトルのまんまです。

FlutterとFirebaseのバージョンは次のとおりです。

$ flutter --version
Flutter 1.10.14 • channel dev • https://github.com/flutter/flutter.git
Framework • revision 1946fc4da0 (12 days ago) • 2019-10-07 15:23:31 -0700
Engine • revision 1d62160fdb
Tools • Dart 2.6.0 (build 2.6.0-dev.1.0 d6c6d12ebf)

$ firebase --version
7.0.1

Workflow

次のワークフローで基本的には動きます。ただし、一部実装依存の部分があるので後述します。

name: CI

on:
  push:
    branches:
      - master

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      - name: Build
        uses: subosito/flutter-action@v1
        with:
          channel: 'dev'
      - run: |
          flutter config --enable-web
          flutter pub get
          cat <<EOF > assets/secret.json
          ${{ secrets.CREDENTIAL_JSON }}
          EOF
          flutter build web
      - name: Archive Production Artifact
        uses: actions/upload-artifact@master
        with:
          name: web
          path: build/web
  deploy:
    name: Deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: web
          path: build/web
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          PROJECT_ID: ${{ secrets.PROJECT_ID }}
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

解説していきます。

Jobの流れ

BuildとDeployで分けてます。

Build

flutterコマンドを落としてきて、ビルドしたものをartifactに登録します。

GitHub Actionsでflutterを使うためのActionがいくつか用意されていたのですが、Dockerの方を使うとartifactのpathを調整する必要があったため、JavaScriptの方を選択しました。

github.com

Deploy

firebaseコマンドが使えるDockerコンテナを用意し、その中でartifactを落としてきて、Hostingにデプロイします。

こちらもActionが複数あったのですが、最もStarを集めてて使いやすそうなものを選びました。

github.com

Hosting以外のFirebaseの機能を利用している場合

今回の例にあたります。Firebase Config Objectを生成して、Firebase初期化時の引数に渡す必要があります。

この情報はpublicにしたくないものも含まれれるため、リポジトリには含めません。

今回のケースだと、 assets/secret.json というファイルに情報を詰めています。このファイル名もファイルパスも、渡し方も決まりはないので、プロジェクトごとに異なると思います。

このプロジェクトでは次のように初期化しています。

final secret = await rootBundle.loadStructuredData<Secret>("assets/secret.json",
      (jsonStr) async {
    final secret = Secret.fromJson(json.decode(jsonStr));
    return secret;
  });
initializeApp(
  apiKey: secret.apiKey,
  authDomain: secret.authDomain,
  databaseURL: secret.databaseURL,
  projectId: secret.projectId,
  storageBucket: secret.storageBucket,
);

秘匿情報の扱い方は以前まとめたものが参考になると思います。

sakebook.hatenablog.com

まとめ

Flutter for Webのプロジェクトをデプロイするだけなら簡単です。基本的にBuildのjobで必要なものは揃っているので、あとはどこにホスティングするにしても同じ感じで行けると思います。

一部実装依存になる部分が出てきたら調整が必要です。

今回作成したページはこちらです。

参考

Add Firebase to your JavaScript project  |  Firebase

Upload-artifact not working for steps running in containers · Issue #13 · actions/upload-artifact · GitHub