はじめに
チームでFlutterの開発をする中で、コードの品質やテストコードによる保護をするため、CIについて学びましたので記事にしたいと思います。
個人的な話になりますが、現在、携わっているプロジェクトでは、コードレビューはありますが、テストコードはほとんど無しで開発を進めています。
コードの品質を保つのはコードレビューで行っていますが、細かくみているとかなり時間を取られます。
スケジュールが厳しくなってくると、開発速度が優先になり、仕様を満たしているかだけが要点になってしまい、コードレビューで細かく見る時間がなくなってしまうことがありました。
本来は、スケジュールが厳しくなることを防ぎたいのですが、100%防ぐのは難しいですし、CIのサービスを使って、開発環境を整備していくのが良さそうだと思っています。
CI
CIとは
CIは「Continuous Integration」の略で、継続的インテグレーションと訳します。
コードの変更をmain(master)ブランチに統合するプロセスを指すようです。
そう説明されてもいまいちピンと来ませんでしたが、このプロセスの目的はソフトウェア開発プロセスの効率化と品質の向上です。
具体的には、任意のタイミングで、コードチェックを自動で行うことです。
任意のタイミングとは
任意のタイミングとは例えば下記になります。
- GitにPush時
- PR作成時
- 定期実行(毎日9時とか)
コードチェックとは
コードチェックとは例えば下記になります。
- 静的解析
- フォーマットチェック
- ビルドできるか確認
- テストコードの実行
CIを実行するためのサービスについて
CIを実行するために、CIサービスを使用する必要があります。
例えば、下記のようなサービスがあります。
- Jenkins
- Travis CI
- CircleCI
- GitHub Actions
Githubでコード管理しているので、Github Actionsが使いやすそうかなと思ったので、本記事ではGithub Actionsを使用しています。
各サービスの特徴や比較については行っていないので、最適な判断ではないと思います。
Github Actionsを使ったFlutterのCIの例
具体的にどういう手順で、どういうCIを実装したか例を書いていきます。
Github Actionsについて
Github Actionsは、CIとCDが実行できるサービスです。
CDとは、「Continuous Deployment」または「Continuous Delivery」の略で、継続的デプロイメントまたは継続的デリバリーを意味します。目的としては、ソフトウェアのリリースプロセスを自動化し、効率化することです。
CDについては、この記事では解説しませんが、また別の記事を書きたいと思っています。
Github Actionsをきちんと理解したい方には以下の本がおすすめです。
Kindle Unlimittedに入っていたら無料で読めます。
注意点
Github Actionsはpublicのブランチだと無料なのですが、privateのブランチだと有料になります。
とりあえず試してみたい方はpublicのブランチに対して行ってください。
導入手順
この記事の例では、PullRequest作成時にコードチェックを実行するように進めていきます。
この記事と全く同じように試される場合は、以下の手順はPRでベースにするブランチに対して行ってください。
ファイル作成
まず、Flutterのプロジェクトに.github/workflowsというフォルダを作成します。
.githubのフォルダはlibと同階層です。
そして、その中に、実行したい内容を記述したワークフローをYAMLで作成します。
作成したファイルをGitにPushすると有効になり、定義内容に応じて実行されます。
下記の画像のci.ymlがワークフローを定義したファイルです。
ファイルの内容
ymlファイルの内容は下記です。
name: Continuous Integration
on: pull_request
jobs:
CI:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Create flutter environment
uses: subosito/flutter-action@v2
with:
flutter-version: '3.13.9'
- name: Install packages
run: flutter pub get
- name: Check format
run: dart format lib --set-exit-if-changed -o none
- name: Analyze
run: flutter analyze
- name: Test
run: flutter test --update-goldens
ファイルの解説
実行タイミング
on: pull_request
でPullRequest作成時、更新時にワークフローを実行するようにしています。
on: push
にするとPush時に実行され、他にもトリガーできるイベントが定義されています。
実行環境
runs-on: ubuntu-latest
で、実行するOSを定義しています。
他にもmacosやwindowsも指定できます。
OSによって、料金が変わるみたいで、macosが1番高いみたいです。
実行する内容
stepsに何をするのかを定義しています。
- Checkout
対象のブランチのコードをチェックアウトします。
uses
を使うと、Marketplaceという場所に公開されている外部のワークフローを使用できます。 - Create flutter environment
Flutterの環境を構築します。 - Install packages
run: 〜
でコマンドを実行できます。
開発しているプロジェクトの依存パッケージをインストールします。 - Analyze
flutter analyze
で静的解析を実施します - Test
flutter test --update-goldens
でテストを実施します
テストコードには、GoldenTestを含んでいるのですが、実行環境の違いでエラーになってしまうので、--update-goldens
をつけて、エラーとならないようにしています。
本当はエラーを回避して、flutter test
を行うことがベストだと思います。
エラーを回避する方法は実行環境を合わせることみたいです。
例えば、macで開発しているなら、Github Actionsもruns-on: ubuntu-latest
ではなく、runs-on: macos-latest
とすると問題ないという記事を見ました。
ただ、私の方ではOSを同じにしてもテストに失敗しましたので、仕方なく--update-goldens
をつけることにしました。
GoldenTestは実行環境によって変わる?みたいなので、開発チームで開発PCが異なる場合(macとwindowsを使っている人がいるみたいな)は、どうやって運用しているのでしょうか?
さいごに
今回のコードは下記にあります。