Ktlint × ReviewDogでPull Requestをレビューする
はじめに
このドキュメントではKtlintとReviewDogを組み合わせて、Ktlintが生成した静的解析レポートをReviewDogでPull Requestのレビューコメントとして記載する方法を解説します。
前提知識
Ktlintとは?
KtlintはKotlinのコードスタイルをチェックするツールです。Kotlinのコードが一貫したスタイルガイドに従っているかをチェックし、場合によっては自動修正することもできます。Ktlintを使うことでコードの品質を向上させることができます。
ReviewDogとは?
ReviewDogはLinter(コード解析ツール)が生成した静的解析レポートをPull Requestのレビューコメントとして自動的に記載するツールです。ReviewDogを使用することで静的解析に基づいたレビューを自動化し、コードの品質改善を効率化できます。
前提条件
プロジェクトの構造
近年のAndroidアプリ開発では、マルチモジュール構成が一般的です。そのため、今回使用するデモプロジェクトには、app
とlibrary
の2つのモジュールを含めることにします。
実装手順
Ktlint(ktlint-gradle)のセットアップ
Ktlintはコマンドラインツールなのですが、そのまま利用するとなると少々手間がかかります。今回はセットアップを簡単にするためktlint-gradleを使用してKtlintを利用可能にします。
plugins
セクションにktlint-gradle
の依存関係を追加するallprojects
セクションでktlint-gradle
を設定する
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.android.library) apply false
id("org.jlleitschuh.gradle.ktlint") version "12.1.1" apply false
}
// appとlibraryの2つのモジュールでktlint-gradleを有効化する
allprojects {
// ktlint-gradleのpluginを有効にする
apply(plugin = "org.jlleitschuh.gradle.ktlint")
configure<org.jlleitschuh.gradle.ktlint.KtlintExtension> {
// Ktlintのバージョンを指定する
version.set("1.3.1")
// Ktlintの実行結果をPLAIN・CHECKSTYLE・SARIFで出力する
reporters {
reporter(ReporterType.PLAIN)
reporter(ReporterType.CHECKSTYLE)
reporter(ReporterType.SARIF)
}
// Ktlintを実行して、警告・エラーがあり失敗しても、無視するようにする
ignoreFailures.set(true)
// Ktlintを実行する際に自動生成されたコードは無視する、kotlinディレクトリにあるコードを対象にする
filter {
exclude("**/generated/**")
include("**/kotlin/**")
}
}
}
Ktlint(ktlint-gradle)の動作チェック
ktlint-gradle
には以下のGradleタスクが用意されており、これらのGradleタスクでKtlintによる静的解析やフォーマットを実行できます。
Gradleタスク名称 | 内容 |
loadKtlintReporters | KtLint Reporters を事前ロードします。 |
runKtlintCheckOverKotlinScripts | プロジェクトの Kotlin スクリプトファイルに対して実際のリントチェックを実行します。 |
ktlintKotlinScriptCheck | 静的解析で見つかったエラーに基づいてレポートを生成し、Gradle コンソールに問題を出力します。このタスクの実行は、loadKtlintReporters と runKtlintCheckOverKotlinScripts のタスク実行結果に依存します。 |
runKtlintFormatOverKotlinScripts | プロジェクトの Kotlin スクリプトファイルをコードスタイルに従ってフォーマットしようとします。 |
ktlintKotlinScriptFormat | フォーマットできないエラーに基づいてレポートを生成し、Gradle コンソールに問題を出力します。このタスクの実行は、loadKtlintReporters と runKtlintFormatOverKotlinScripts のタスク実行結果に依存します。 |
ktlintCheck | すべての SourceSet およびプロジェクトの Kotlin スクリプトファイルをチェックします。 |
ktlintFormat | すべての SourceSet の Kotlin ファイルおよびプロジェクトの Kotlin スクリプトファイルをコードスタイルに従ってフォーマットしようとします。 |
この中でも特に利用頻度が高いGradleタスクはktlintCheck
とktlintFormat
になります。そのため下記のコマンドでktlintCheck
とktlintFormat
のGradleタスクが正常に実行されるか動作をチェックしておきます。
ktlintCheckの動作チェック
./gradlew ktlintCheck
を実行する- タスクが成功すること、
build/reports/ktlint
に各種レポートの生成を確認する
katz@macbookpro AndroidReviewdogDemo % ./gradlew ktlintCheck
BUILD SUCCESSFUL in 2s
13 actionable tasks: 11 executed, 2 up-to-date
ktlintFormatの動作チェック
./gradlew ktlintFormat
を実行する- タスクが成功すること、
build/reports/ktlint
に各種レポートの生成を確認する
BUILD SUCCESSFUL in 2s
13 actionable tasks: 11 executed, 2 up-to-date
katz@macbookpro AndroidReviewdogDemo % ./gradlew ktlintFormat
💡なぜktlint-gradleを利用するのか?
ktlint-gradle
を利用しない場合には、Ktlintのコマンドをインストールして、Ktlintのコマンドを利用して静的解析レポートを出力します。またはKtlintによる自動フォーマットを実行する場合にも、Gradleタスクを自前で用意する必要があり少々実装が面倒です。ktlint-gradle
ではよく使うユースケースのGradleタスクをあらかじめ定義してくれるのでKtlintの導入のハードルを下げることができます。またKtlintのバージョン設定やレポーター設定の変更も簡単にできるようになっており、利用することのメリットが大きいです。そのため今回はktlint-gradle
を利用してセットアップを進めました。
ReviewDog(GitHub Action)のセットアップ
ReviewDogはコマンドラインツールですが、今回はGitHub Actionで動作させようと思います。なので以下のようなGitHub Actionのyamlファイルを作成して、Pull Requestが更新されたタイミングでReviewDogが動作させ、Ktlintの静的解析結果からレビューコメントを作成するようにします。
actions/checkout@v4
を利用し、CI環境上に最新のプロジェクトをチェックアウトするactions/setup-java@v4
を利用し、CI環境上にJava環境をインストールするreviewdog/action-setup@v1
を利用し、CI環境上にReviewDogをインストールするktlint-gradle
のktlintCheck
をKtlintを実行して静的解析レポートをsarifファイルとして出力する- 生成したsarifファイルのパスを検索し、発見したsarifファイルをreviewdogに読み込む
name: Check pull request
on:
pull_request
permissions:
contents: write
jobs:
check:
runs-on: ubuntu-latest
name: Check pull request
permissions:
pull-requests: write
steps:
# 1. 最新のプロジェクトをチェックアウトする
- uses: actions/checkout@v4
# 2. プロジェクトのビルドを実行するために必要なJava環境をセットアップする
- uses: actions/setup-java@v4
with:
distribution: 'corretto'
java-version: 17
# 3. ReviewDogの公式が提供しているActionを利用して、ReviewDogをセットアップする
- name: Setup reviewdog
uses: reviewdog/action-setup@v1
with:
reviewdog_version: v0.18.0
# 4. ktlint-gradleが提供するktlintCheckタスクを実行して、Ktlintの静的解析レポートを生成する
- name: ktlint
run: ./gradlew ktlintCheck
# 5. Ktlintの静的解析レポートを検索して、順番にReviewDogに読み込ませて、Pull Requestコメントを生成する<strong>
- name: Run reviewdog for Ktlint
env:</strong>
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.REVIEW_DOG }}
# Reporterにはgithub-pr-checkを利用する場合はこちら、Files Changedのレビューコメントが記載される
run: |
find . -regex '^.*/build/reports/ktlint/ktlintMainSourceSetCheck/ktlintMainSourceSetCheck.sarif' -type f | while read file_path; do
cat "$file_path" | reviewdog -reporter=github-pr-check -f=sarif -fail-on-error
done
💡 ReviewDogのレポーターの種類
- Reviewdogではレポーターを指定することで、静的解析結果をどのような形式で表示するか指定することができます。
- GitHub上で利用できるレポーターには以下の3つの種類がありますが、今回は
github-pr-check
を利用してPull Requestのレビューコメントに静的解析結果を記載しています。
レポーターの種類 | 内容 |
github-check | 基本的にはgithub-pr-check と同じだが、Pull Requestだけでなくcommitでも動作する |
github-pr-check | github-pr-check レポーターはGitHub Checksに結果を報告する。 |
github-pr-review | github-pr-review 、GitHub Personal API Access Tokenを使ってGitHub PullRequestのレビューコメントに結果を報告する。 |
実行結果
Pull Requestを作成しGitHub Actionsのワークフローが動作すると、Ktlintが検出した警告・エラーをReviewDogにより自動でコメントします。
このようにReview Dogを利用するとKtlintの警告やエラーなどの問題がある箇所がレビュー時にわかるようになり品質向上が期待できます。こちらの動作確認にしたコードは以下に保存してありますので、詳しい内容は以下のコードを確認ください。
https://github.com/kaleidot725/AndroidReviewdogDemo
参考文献
- https://github.com/JLLeitschuh/ktlint-gradle
- https://github.com/reviewdog/reviewdog
- https://zenn.dev/yumemi_inc/articles/fae967dcaa89e7