CodemagicでFlutter(iOS & Android)アプリを自動配信-全体設定編

Photo by Aron Visuals on Unsplash

Codemagicについての日本語記事はすでに良質なものがありますが、まだまだ他のCI/CDサービスと比べると量が少ないことや、個人的な備忘録としても書き残しておきます✍️

この記事では、以下の内容をスクリーンショット付きで解説していきます。

  • freezedを使用したFlutterアプリをiOS, Androidでビルド
  • iOS, Androidのコード署名(Code signing)
  • App Store Connectへの配信(アプリ公開とTestFlightが利用できる)
  • Google Play Consoleへの配信
  • Slackへの通知

Firebase(Auth, Firestore, RemoteConfig等)を使用していますが、Codemagic上では特に困ることはありませんでした。

なお、当記事では難所であろうFlavorを使用しないシンプルな設定となっています。
アプリをFlavorに対応した場合のCodemagic追加設定は別記事に書きました↓

アプリへのFlavor対応自体は特に mono さんの記事に詳しく書かれています。
その他、Codemagicを導入するにあたり全体的に参考にさせていただきました。ありがとうございます🙏

まずは各種アカウントの連携

User Settings画面のIntegrationsからGitプロバイダやSlack、Apple Developer Portalのアカウントと連携できます。Slackの連携にWebHookは不要で簡単です。

GitHub等のアカウントを連携すると、自分のリポジトリ候補が表示されるので、ビルドさせたいリポジトリを選択しましょう。

Store配信用のWorkflowを構築

ここでは、Default Workflowの名前を分かりやすく「Upload to Store」へ変更したとします。(好きな名前をつけましょう)

Duplicate workflowでWorkflowを複製できます。

Max build durationで設定した時間を超えると、タイムアウトでビルドが終了します。Firabaseを使用したiOSのビルドは思いの外時間がかかるので長めに設定しておきました。

Build triggers(ビルド実行条件)

ビルド対象にしたいブランチ名を文字列で指定。

Includeは含む、Excludeの場合は上で指定したブランチ名を除外する設定になります。

Source, Targetは、プルリクエスト用の設定です。対象ブランチが元・先どちらのブランチかを指定します。

ビルドが自動で開始される条件

  • Trigger on push: 対象ブランチにコミットがPushされた時
  • Trigger on pull request update: プルリクエストが開かれたり更新された時
  • Trigger on tag creation: タグが作成された時

Environment variables(環境変数)

今回は使用しません。

Dependency caching(依存のキャッシュ)

Enable dependency caching は、pubspec.yaml で指定したパッケージ等の依存物をキャッシュするかどうか。

Store配信用なので、今回は有効にはしませんでした。

頻繁に回すビルド用であれば、有効化することでビルド時間の短縮が狙えるのではないでしょうか

ちなみに、ドキュメントでは以下のキャッシュパスが例として提示されていました。

必要であればAddしてみましょう。

  • $FLUTTER_ROOT/.pub-cache : Dartのキャッシュ
  • $HOME/.gradle/caches : Gradleのキャッシュ
  • $HOME/Library/Caches/CocoaPods : CocoaPodsのキャッシュ

Pre-test script(テスト前に実行するスクリプト)

Dependency cachingとTestの間の「+」ボタンまたは歯車ボタンを押すことで編集できます。

freezed等のコードジェネレータを使用しており、かつ生成後のコード(*.freezed.dartや*.g.dartなど)をgitignoreしている場合に必要なスクリプトになります。

#!/bin/sh
set -e # エラーが出たら終了する
# Generate by freezed with JSON
flutter pub pub run build_runner build

このスクリプトを実行しない場合、ファイルが足りなくTestやBuildが失敗します。

Test(テストと解析)

Flutter analyzerとFlutter testを走らせられます。

Stop build if tests failをチェックすると、テスト失敗時はビルドを中断します。

テスト関連については疎く、以下日本語記事を参考に実装していきたいと思っています。

Flutterのテスト全体について

https://itome.team/blog/2019/12/flutter-advent-calendar-day20/

Flutter Driver testについて

https://qiita.com/sensuikan1973/items/c8b56dfaf780e61af567

Build(プラットフォームごとのビルド)

各種バージョンを直接指定するか、LatestやDefaultといったようにある程度任せることもできます。

  • 基本、こちらの設定をローカルの環境に合わせておく
  • Latestに設定しておき、ビルド成功したらローカルのversionをアップデートする

のどちらかかなと思いました。

今回は、Store申請用なので安全なローカルで使用しているバージョンに合わせて指定しています。

対象プラットフォームとビルドモード

対象となるプラットフォームを選択します。

Firebase等を使っているとiOSのビルドは長くなりがちなので、テスト時はAndroidとiOS片方だけでビルドテストした方が良いと思います。

Build Android App BundlesをチェックするとApp Bundlesが生成されます。
Google Play StoreではApp Bundlesが推奨されているのでチェックしておきましょう。

今回はStore配信用なのでMode: Release を選択しています。

Build argumentsではその他ビルド時の設定を追加できます。
-t lib/main.dart のように対象のmain.dartファイルのパスを指定できます。

ビルド番号のインクリメント

App Storeに配信するにあたり、同じバージョン・同じビルドナンバーのアプリはアップロードできません。

pubspec.yamlを手動で書き換えてpushし直すのは手間なので、自動でインクリメントされるように設定しておきます。

--build-number=$BUILD_NUMBER とすると、Workflowのビルド番号(初回は#1)が反映されるようになります。

Xcodeでいう Build です。

後からCodemagicを採用したときなどは、現在のビルド番号とWorkflowのビルド番号が乖離していることもあるかと思います。

その場合は下記のように現在のビルド番号を足せば良いかと。

--build-number=$(($BUILD_NUMBER + 100))

https://docs.codemagic.io/building/build-versioning/

Publish(配信・通知)

最後に、各Storeへのアプリ配信やSlackへの通知を設定します。

Android code signing

生成したkey.jksファイルをアップロード、
生成時に設定したKeystore passwordを入力

Key aliasはデフォルトで key です。

iOS code signing

iOSの署名設定。

個人開発等は、理由がなければAutomaticを選択するのが簡単で良いと思います。

今回はStore申請用なので Provisioning profile type: App store を選択しています。

Bundle identifierは未入力でも大丈夫だとは思いますが、環境によってBundle identifierが変わる場合等は入力が必要かと思います。

AutomaticではなくManualを選択した場合は以下のファイルをアップロードする必要があります。

  • Certificate
  • Provisioning profiles

各ファイルはAppleのDeveloperサイトで作成します。
https://developer.apple.com/account/resources/certificates/list

Slack

デフォルトでEmail通知が有効化されています。

冒頭でSlack連携を済ませていれば、Slack通知は簡単です。

  • 投稿先となるChannelを選ぶ
  • ビルド開始時に通知してほしければ Notify when build starts にチェックを入れます。
  • ビルド失敗時にもAPKã‚„IPAファイルなどの成果物を配信させたい時は Publish artifacts even if tests fail にチェック
Slackではこのようにメッセージが投稿されます。

Google Play

AndroidアプリをGoogle Play Storeにアップロードするために有効化します。

Credentials (.json)

Google Play Store経由で取得したJSONファイルをアップロードします。

手順がちょっと分かりにくいです。

  1. 設定>APIアクセス>サービスアカウントを作成>「Google API コンソール」リンクをクリックするとGoogle Cloud Platformのページがひらk
  2. 「サービスアカウントの作成」ボタンから「権限:サービスアカウント→サービスアカウントユーザー」を選択して進みます。
  3. 鍵の種類は「JSON」、秘密鍵の提供にチェックして進みます。
  4. 作成したJSON認証情報ファイルをダウンロードします。
  5. Google Play Consoleに戻利、「完了」ボタンを押します。
  6. アクセス権限を承認するボタンをクリックし、役割プルダウンから「リリースマネージャー」を選択します。
  7. CodemagicでJSONファイルをアップロードすればOKです。

Codemagic公式ドキュメント
https://docs.codemagic.io/publishing/publishing-to-google-play/

トラックの選択

  • 内部テスト(Internal)
  • クローズド(Alpha)
  • オープン(Beta)
  • 製品版(Production)

別途テスト配信する必要がないのであれば、Production(製品版)を選択しておけばすぐに公開に取り掛かることができます。

なお、「※Codemagicでの配信前に一度手動でアプリをGoogle Play Storeにアップロードする必要があります」と書かれていたので、僕はあらかじめApp Bundleを一度手動でアップロードしておきました。

トラック作成にはプライバシーポリシーの設定も必要なので済ませておきます。(アプリのコンテンツ>プライバシーポリシー)

App Store Connect

App Storeへアプリを公開したり、TestFlightを使用するために設定します。

App-specific passwordは Apple IDのパスワードではなく、Apple IDのアカウント管理画面で発行したものを使用します。
https://appleid.apple.com/account/manage

App IDも若干紛らわしいのですが、Bundle IDのことではありません。

App Store Connectでアプリを作成した後、App情報から確認できる「Apple ID」を入力してください。

README等にバッジを表示する

ビルド状況(passed, failed等)のバッジを表示できます。

Badge markdownのリンクをコピーしてREADMEに貼り付けるだけなので簡単です。

ビルド状況により自動で表示が切り替わります。

無料なのは500分/月

Mac miniでビルドされますが、無料でビルドできる時間は500分となります。

クレジットカードを登録すれば500分を超えた分を有料でビルドしたり、Mac Proでのビルドが利用できます。

2020年7月1日現在の価格は以下のようになっています。

  • Mac mini: $0.038/分(10分で約40円)
  • Mac Pro: $0.095/分(10分で約100円)

Mac Proでのビルドはどのくらいビルド時間が短縮されるのか気になるところですね🧐

ビルド機であるMac mini, Mac Pro, Xcode等の詳しい情報はこちら:
https://docs.codemagic.io/releases-and-versions/versions/

以上、僕の環境ではビルドが実行できアプリを各ストアにアップロードすることができました!

分かりにくい点、間違っている点などありましたらコメントかTwitter(@Riscait)からご連絡いただけると大変嬉しいです🙏

他にもCodemagicについての素晴らしい日本語記事がありましたのでリンクを貼らせていただきます。

ご閲覧ありがとうございました!

少しでもお役に立てたのならば、Clap👏いただけたら嬉しいです!

--

--

村松 龍之介@riscait (MURAMATSU Ryunosuke)
村松 龍之介@riscait (MURAMATSU Ryunosuke)

Written by 村松 龍之介@riscait (MURAMATSU Ryunosuke)

I’m App Developer. Flutter (iOS, Android, Web) and Firebase. Tesla Model 3.

Responses (1)