okuzawatsの日記

モバイルアプリケーション開発の沼💀

GitHub ActionsでktlintとAndroid Lintを並列実行して、DangerでPRにまとめてコメントする🐝

書いている人

モバイルアプリケーションアーキテクトとして働いています。モバイルアプリケーションのアーキテクチャ、自動テスト、CI/CDに興味があります。


Androidアプリ開発での静的解析として広く使われているktlintとAndroid LintをGitHub Actions上で実行して、Dangerを使ってPRにコメントして欲しい、ということは良くあると思います。ktlintとAndroid Lintを直列に実行するのは簡単ですが、並列に実行できた方がCI待ちの時間が減って嬉しいですよね。そこまで難しくないのでやっていきます。

jobs.<job_id>.needs 構文

GitHub Actionsでは、ひとつのワークフロー(YAMLファイル単位で作成される)に複数のジョブを定義できます。ひとつのワークフローにktlint、Android Lint、Dangerのジョブをそれぞれ定義すれば良さそうですが、Dangerの実行はktlintとAndroid Lintの両方の実行完了を待たないといけません。

ここで使えるのが、 jobs.<job_id>.needs 構文です。

この構文を使って、

jobs:
  ktlint:
    # do ktlint
  androidLint:
    # do android lint
  danger:
    needs:
      - ktlint
      - androidLint
    # do danger

というように、ktlintのジョブ、Android Lintのジョブ、Dangerのジョブをそれぞれ定義しておき、Dangerのジョブの依存ジョブとしてktlintおよびAndroid Lintのジョブを指定すれば良いです。

Gemfile

Gemfileに必要なgemを追加しておきます。今回は、PRにktlintの指摘をコメントするために danger-checkstyle_format 、Android Lintの指摘をコメントするために danger-android_lint を使用します。

gem 'danger'
gem 'danger-checkstyle_format'
gem 'danger-android_lint'

Dangerfile

Dangerfileでは前述の danger-checkstyle_formatdanger-android_lint の設定を書いておきます。Android LintのGradleタスクは先にGitHub Actionsのジョブとして実行しておくので、 skip_gradle_task にtrueを設定しておきます。また、ファイルのパスはプロジェクトによって異なるパスとなっている可能性があるので、適宜修正します。

checkstyle_format.base_path = Dir.pwd
checkstyle_format.report 'app/build/ktlint.xml'

android_lint.report_file = 'app/build/reports/lint-results-debug.xml'
android_lint.skip_gradle_task = true
android_lint.lint

upload-artifact、download-artifact

GitHub Actionsのジョブ間では、それぞれのジョブ内で生成されたファイルは共有されません。そのため、ktlintとAndroid Lintの出力したレポートファイルを何らかの方法でDangerのジョブに渡す必要があります。

この問題を解決するための方法はいくつかあると思いますが、今回はupload-artifactアクション、およびdownload-artifactアクションを使用します。

ktlintのジョブとAndroid Lintのジョブの最後に、upload-artifactアクションを用いて、それぞれのレポートファイルをアップロードしておきます。こうしておくと、あとからレポートファイルを参照することもできるというメリットもあります。

- uses: actions/upload-artifact@v3
  with:
    name: ktlint-output
    path: 'app/build/ktlint.xml'
- uses: actions/upload-artifact@v3
  with:
    name: androidlint-output
    path: 'app/build/reports/lint-results-debug.xml'

Dangerのジョブでは、Dangerの実行前に、download-artifactアクションを用いてこれらのファイルをダウンロードしておきます。これで、Dangerのジョブの中でそれぞれのファイルを使用可能な状態となります。

- uses: actions/download-artifact@v3
  with:
    name: ktlint-output
    path: 'app/build/'
- uses: actions/download-artifact@v3
  with:
    name: androidlint-output
    path: 'app/build/reports/'

GitHub Actionsのワークフローを実行

ここまで来たら、GitHub Actionsのワークフローを実行できます。試しに実行してみると、以下のようにktlintとAndroid Lintの警告・エラーがGitHubのPRにコメントされました。

Fig-1 GitHubのPRへのコメント

PRへのコメントについてはdanger-actionを使用しました。

実際のYAMLファイルはGitHub上で参照可能ですので、見てみたい方は以下のリンクからどうぞ。

Related