GitHub Actions で Flutter プロジェクトを Firebase にデプロイしたい

## はじめに

数ヶ月前に構築した Flutter 用の CI / CD 環境が使われることなく眠っているので供養のためにも記事にしておきます。
困っている方の参考になれば嬉しいです。

GitHub Actions についてはこちら
https://github.co.jp/features/actions

## ワークフローの概説

### 前提条件

プロジェクトのシークレットに下記 8 項目をセットする必要があります。

```md
- CERTIFICATES_P12             // p12 (Base64)
- CERTIFICATES_P12_PASSWORD    // p12 のパスワード
- FIREBASE_APP_ID_ANDROID      // Android の Firebase AppID
- FIREBASE_APP_ID_IOS          // iOS の Firebase AppID
- FIREBASE_TOKEN               // Firebase のトークン
- PROVISIONING_PROFILE         // mobileprovision (Base64)
- SLACK_WEBHOOK                // Slack のトークン
- TEAM_ID                      // Apple Developer Program の TEAM ID
```

https://github.com/muhiro12/flutter-deploy-workflow/blob/master/README.md

### テスト & モジュール作成

```yaml
  build:
    # iOS の ipa を生成したいので 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/decoded.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 }}

    # Flutter コマンド！
    - name: Flutter action
      uses: subosito/flutter-action@v1.3.0
    - run: flutter pub get
    - run: flutter test
    - run: flutter build ios
    - run: flutter build apk    # この時点で Android モジュールは作成完了

    # Xcode で Archive
    - 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: iOS Distribution
        team-id: ${{ secrets.TEAM_ID }}
        workspace-path: ios/Runner.xcworkspace
        export-method: development
        certificate-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
        output-path: app-release.ipa

    # デプロイは Ubuntu で行うため、一度モジュールをアップロードする
    - name: Upload artifact
      uses: actions/upload-artifact@v1.0.0
      with:
        name: ios
        path: app-release.ipa

    - name: Upload artifact
      uses: actions/upload-artifact@v1.0.0
      with:
        name: android
        path: build/app/outputs/apk/release/app-release.apk
```

- [checkout](https://github.com/marketplace/actions/checkout)
- [import-codesign-certs](https://github.com/marketplace/actions/import-code-signing-certificates)
- [flutter-action](https://github.com/marketplace/actions/flutter-action)
- [ios-build-action](https://github.com/marketplace/actions/ios-build-action)
- [upload-artifact](https://github.com/marketplace/actions/upload-a-build-artifact)

### Firebase にデプロイする

```yaml
  deploy:
    needs: [build]
    # 2020/04 時点
    # Firebase-Distribution-Github-Action が macOS 未対応のため Ubuntu で実行する
    runs-on: ubuntu-latest
    steps:

    - uses: actions/checkout@v2

    # モジュールをダウンロードする
    - name: Download artifact
      uses: actions/download-artifact@v1.0.0
      with:
        name: ios

    - 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_IOS}}
        token: ${{secrets.FIREBASE_TOKEN}}
        groups: testers
        file: ios/app-release.ipa

    - 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
```

- [download-artifact](https://github.com/marketplace/actions/download-a-build-artifact)
- [Firebase-Distribution-Github-Action](https://github.com/marketplace/actions/firebase-app-distribution)

### Slack に通知する

```yaml
  notify:
    needs: [build, deploy]
    runs-on: ubuntu-latest
    steps:

    - name: Slack Notification
      uses: rtCamp/action-slack-notify@v2.0.0
      env:
        SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
        SLACK_COLOR: '#171515'
        SLACK_ICON: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
        SLACK_USERNAME: ${{ github.repository }}
        SLACK_TITLE: Now Available
        SLACK_MESSAGE: https://appdistribution.firebase.dev/app_distro/projects
```

- [action-slack-notify](https://github.com/marketplace/actions/slack-notify)

## おわりに

ポイントは、 macOS で生成したモジュールを upload / download で Ubuntu に渡すところです。
全体的に結構苦労した覚えがありますが、自分のスキル的にも、環境的にも、今はもっと最適化できる気がしています。

ちなみに今は Bitrise を利用していますが、圧倒的に簡単に環境構築できます。
無料期間、無料枠などあるのでそちらも是非お試しください。

yaml ファイルの全容はこちら
https://github.com/muhiro12/flutter-deploy-workflow/blob/master/.github/workflows/main.yml