LoginSignup
3
1

More than 3 years have passed since last update.

AndroidのCIとテストアプリ配信をサービスアカウントを使ったGithubActions+AppDistributionに載せ替える

Posted at

載せ替えた理由

CI

・BitriseにiOSとAndroidの両方を載せて回していたが、プロジェクト数も多くなり始め契約していたMAX2レーンのプランだとタイミングによって待つ必要が出てきていた。
・それぞれのプロジェクトで使っているBitriseのStepにばらつきが出ていたので、統一するタイミングが欲しかった。
・サーバーサイドがすでに一部載せ替えており、使いやすいし無料枠が余っていると言われていた。
・とりあえず新しい技術には触っておきたかった。

テストアプリ配信

・FabricのFirebase統合に伴い、Betaが利用できなくなる。
https://docs.fabric.io/apple/beta/overview.html

完成形

とりあえずGithubActions用のYAMLファイルを載せておきます

name: CI

on:
  push:
    branches:
      - develop

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Ruby 2.6
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.5
      - name: install bundler
        run: gem install bundler:2.0.2
      - uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: install firebase tools
        run: npm install -g firebase-tools
      - name: Set Google GOOGLE_APPLICATION_CREDENTIALS
        run: |
          cat << "EOF" > google_service_account_key.json
          ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
          EOF
      - name: exec fastlane
        run: |
          bundle install --path vendor/bundle
          bundle exec fastlane beta
        env:
          GOOGLE_APPLICATION_CREDENTIALS: ./google_service_account_key.json

解説

当初はFirebaseTokenを使って実装していたのですが、各プロジェクトの担当者がそれぞれtokenの認証通すのか?退社した場合どうするのか?みたいな問題があったため、サービスアカウントを使って実装する運びとなりました。
結構詰まりポイントがあったので、解説していきます。
(ほぼ社内のエンジニアの方に助けてもらってできたので、私はまとめているだけです。皆さんありがとうございました…)

AppDistributionサービスアカウント情報の格納

まず、サービスアカウントの情報はYAMLから秘匿された状態でGithubActionsから参照できるようにしなければなりません。
これを実現するためにはGithubのSecretsを利用すれば可能ですが、Secretsは以下の通りjson形式のファイル保存をさけるように言及しています。
https://help.github.com/ja/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets

シークレットの名前には、空白を含めることはできません。 GitHubがログのシークレットを確実に削除するよう、構造化データをシークレットの値として使用することは避けてください。 たとえば、JSONやエンコードされたGit blobを含むシークレットは作成しないでください。

何度か検証した結果、Secretに改行が含まれているものをYAMLで読み込むと、シェルスクリプトに改行を書いたと解釈されてしまうようです。
なので、Secretに格納する前に、サービスアカウントのjsonから改行を全て取り除きました。
また、サービスアカウントjson内の""などもシェルスクリプトの記法として解釈されるため、YAML上でヒアドキュメントを使って文字リテラルとして解釈させます。

加工したjsonをSecret内に格納した上で、以下のスクリプトでgoogle_service_account_key.jsonとして出力します。

- name: Set Google GOOGLE_APPLICATION_CREDENTIALS
  run: |
    cat << "EOF" > google_service_account_key.json
    ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
    EOF

AppDistributionの実行

実際にAppDistributionに配信させる部分は、fastlaneから実行します。
fastlaneから実行できるように、PluginFileに以下を記述します。
参考
https://github.com/fastlane/fastlane-plugin-firebase_app_distribution

gem 'fastlane-plugin-firebase_app_distribution'

fastlaneに先ほど生成したjsonのPathを渡します。
環境変数名GOOGLE_APPLICATION_CREDENTIALSにパスを入れて渡してやると、あとは勝手に解釈してくれるようです。
参考
https://firebase.google.com/docs/app-distribution/android/distribute-gradle

- name: exec fastlane
    run: |
      bundle install --path vendor/bundle
      bundle exec fastlane beta
    env:
      GOOGLE_APPLICATION_CREDENTIALS: ./google_service_account_key.json

既存のlaneのBeta配信だった部分を以下に置き換えます。
hogehogeの部分はFirebaseに登録しているアプリIDに差し替えてください。

firebase_app_distribution(
  app: "****************hogehoge****************",
  apk_path: apk_path,
  release_notes: "",
  groups: "GROUP"
)

これで準備は完了です。
あとはCIに設定したトリガに引っ掛けて動作させるだけです。

まとめ

結構Secret周りにクセがあって、Androidエンジニアとしての知識だけだと辛かったです。
いつもGit周りはSourceTreeを利用しているので、CUI周りの知識が乏しく、ヒアドキュメントとか聞いたこともない単語でした:innocent:
どこかで困っているAndroidエンジニアの助けになればと思います…

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1