Androidアプリ開発でコードの品質を保つために、Kotlinの静的コード解析ツール Detekt を導入してみました。
GitHub Actionsと連携させることで、プルリクエスト時に自動でコード解析を実行し、問題があれば指摘してもらえるようになります。本記事では、その導入からGitHub Actionsでの連携までの手順を紹介します。
実際の設定例は以下のサンプルプロジェクトで確認できます:
example-detekt - DetektとGitHub Actionsの統合例
Detektとは?
DetektはKotlin用の静的コード解析ツールで、以下のような問題を検出できます:
- コードの複雑度が高い箇所
- 命名規則に従っていない変数・関数
- 未使用のコードや不要なimport
- 潜在的なバグにつながるコードパターン
- パフォーマンスに影響する可能性のあるコード
手元の環境
- Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1
- Kotlin 2.2.0
- Android Gradle Plugin 8.10.1
- Detekt 1.23.6
- Gradle 8.11.1
導入手順
1. gradle/libs.versions.toml に Detekt を追加
Version Catalogを使って依存関係を管理している場合は、gradle/libs.versions.toml
にDetektのバージョンを追加します。
[versions]
detekt = "1.23.6"
[plugins]
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
2. build.gradle.kts (プロジェクトルート) でプラグインを適用
plugins {
alias(libs.plugins.detekt) apply false
}
3. app/build.gradle.kts でDetektを設定
plugins {
alias(libs.plugins.detekt)
}
// Detekt設定
detekt {
config.setFrom(file("../detekt.yml"))
baseline = file("detekt-baseline.xml")
autoCorrect = true
}
// タスクレベルでレポート設定を行う(新しいAPI)
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
reports {
html.required.set(true)
xml.required.set(true)
sarif.required.set(true)
md.required.set(true)
}
}
4. Detekt設定ファイルの作成
プロジェクトルートに detekt.yml
を作成して、解析ルールをカスタマイズします。
初期設定ファイルを生成する場合は、以下のコマンドで作成できます:
./gradlew detektGenerateConfig
手元のプロジェクトでは、以下のような設定にしました:
build:
maxIssues: 0
excludeCorrectable: false
complexity:
active: true
LongMethod:
active: true
threshold: 60
CyclomaticComplexMethod:
active: true
threshold: 15
style:
active: true
MaxLineLength:
active: true
maxLineLength: 120
MagicNumber:
active: true
excludes: ['**/test/**', '**/androidTest/**']
ignoreNumbers:
- '-1'
- '0'
- '1'
- '2'
naming:
active: true
FunctionNaming:
active: true
excludes: ['**/test/**', '**/androidTest/**']
ignoreAnnotated: ['Composable']
5. ローカルでDetektを実行
設定が完了したら、ローカルでDetektを実行してみます:
./gradlew detekt
実行後、app/build/reports/detekt/
配下に以下のレポートが生成されます:
-
detekt.html
- ブラウザで見やすいHTML形式 -
detekt.xml
- CIツールで利用しやすいXML形式 -
detekt.sarif
- GitHub Security との連携用 -
detekt.md
- Markdown形式
GitHub Actions との連携
プルリクエスト時に自動でDetektを実行するために、GitHub Actionsのワークフローを設定します。
.github/workflows/detekt.yml
を作成:
name: Detekt Static Analysis
on:
pull_request:
branches: [ main, develop ]
paths:
- '**/*.kt'
- '**/*.kts'
- 'detekt.yml'
- 'app/build.gradle.kts'
- 'build.gradle.kts'
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
detekt:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
- name: Run Detekt
run: ./gradlew detekt
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: app/build/reports/detekt/detekt.sarif
- name: Comment PR with results
if: failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
try {
const report = fs.readFileSync('app/build/reports/detekt/detekt.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🔍 Detekt Static Analysis Results\n\n${report}`
});
} catch (error) {
console.log('No detekt report found or error reading file:', error.message);
}
このワークフローでは以下の処理を行います:
- Kotlinファイルが変更されたプルリクエストでトリガー
- Detektを実行
- 結果をSARIF形式でGitHub Securityタブにアップロード
- 問題が見つかった場合、プルリクエストにコメントで結果を投稿
実際の使用例
設定後にプルリクエストを作成すると、以下のようにDetektが自動実行されます:
> Task :app:detekt
Detekt found 5 code quality issues:
- ComplexMethod at MainActivity.kt:45:5
- LongParameterList at UserRepository.kt:12:5
- MagicNumber at Constants.kt:8:20
- UnusedImport at LoginActivity.kt:3:1
- MaxLineLength at DataProcessor.kt:67:1
問題が見つかった場合、プルリクエストにコメントが自動投稿され、どのファイルのどの行に問題があるかが分かります。
実際の動作例は以下のプルリクエストで確認できます:
PR #2: Add Qiita documentation articles - Detekt GitHub Actionsの実行結果
カスタマイズのポイント
テストコードの除外
テストコードでは多少ルールを緩めたい場合があるので、以下のように設定できます:
style:
MagicNumber:
active: true
excludes: ['**/test/**', '**/androidTest/**']
Jetpack Compose対応
Composable関数は関数名が大文字で始まることがあるので、除外設定を追加:
naming:
FunctionNaming:
active: true
ignoreAnnotated: ['Composable']
閾値の調整
プロジェクトの規模に応じて閾値を調整:
complexity:
LongMethod:
threshold: 60 # デフォルトは60行
CyclomaticComplexMethod:
threshold: 15 # デフォルトは15
まとめ
Detektを導入することで、コードレビュー前に機械的にチェックできる問題を自動検出できるようになりました。
特にチーム開発では、コーディング規約の統一やコード品質の底上げに効果的だと感じています。
最初は警告が大量に出るかもしれませんが、段階的にルールを調整していけば、プロジェクトに適した設定に調整できます。
参考リンク
- example-detekt - 今回の設定を適用したサンプルプロジェクト
- PR #2 - GitHub Actionsの実際の動作例
- Detekt公式ドキュメント - ルールの詳細や設定方法
- GitHub Actionsドキュメント - ワークフローの設定方法