Gradle 依存関係の差分を可視化!「gradle-dependency-diff-action」のご紹介
自分が作成したGitHub Actions「gradle-dependency-diff-action」についてご紹介します。このActionsを使うことで、Pull RequestによってGradle依存関係にどのような差分が生じるかを簡単に確認できるようになります。
Motivation
Gradleは推移的(?)にライブラリの依存を解決していくため、しばしば意図せぬ依存の変更が発生することがあります。
例えば、以下のようにtinkというライブラリをアップデートしたとします。一見すると、ただのマイナーアップデートですよね。
こういった変更のPull Requestのレビュー依頼がきたら、特に問題ないと判断してすぐにApproveをつけてしまうかもしれません。
dependencies {
- implementation("com.google.crypto.tink:tink:1.13.0")
+ implementation("com.google.crypto.tink:tink:1.14.0")
implementation("com.google.protobuf:protobuf-java:3.25.1")
}
しかし実は、tinkはprotobuf-javaに依存しており、この変更によって依存関係は次のように変化します。
protobuf-javaがしれっと3.25.1から4.27.0にあがります。Gradleでは同じ依存がある場合、基本的には最新のバージョンを採用するからです。
-+--- com.google.crypto.tink:tink:1.13.0
++--- com.google.crypto.tink:tink:1.14.0
| +--- com.google.code.findbugs:jsr305:3.0.2
| +--- com.google.code.gson:gson:2.10.1
| +--- com.google.errorprone:error_prone_annotations:2.22.0
-| \--- com.google.protobuf:protobuf-java:3.25.1
-\--- com.google.protobuf:protobuf-java:3.25.1
+| \--- com.google.protobuf:protobuf-java:4.27.0
+\--- com.google.protobuf:protobuf-java:3.25.1 -> 4.27.0
このように、Pull Request上のコード差分からは見えない "隠れた差分" が潜んでいる可能性があります。
こういった隠れた差分を可視化するために、gradle-dependency-diff-action を作りました。
gradle-dependency-diff-action とは?
前述した課題を解決するために、Pull Requestに対して以下のようなことをしてくれます。
- Pull Requestの結果発生する依存関係の差分を検出します
- 依存関係の差分が検出された場合、以下のように報告されます(設定で選択可能)
- GitHub Checksに差分の内容を記述
- Pull Requestコメントとして通知
- Pull Requestにラベルを追加
- 依存関係の差分をテキスト及びHTML形式でGitHub Actions Artifactsにアップロード
Pull Requestの概観:
GitHub Checksの概観:
GitHub Actions Artifactsに生成されるHTMLレポート:
使い方
project-reportプラグインを適用する
依存関係の差分を取得したいプロジェクトに、project-report
プラグインを適用してください。
plugins {
//...
`project-report` // HERE !
}
workflowを書く
まずは、以下のようなworkflowを書いてみてください。とても簡単に始められます。
name: CI
on:
pull_request:
jobs:
dependencies-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- uses: be-hase/gradle-dependency-diff-action@v1
どうやって依存の差分をとっているのか
ざっくりいうと、project-reportプラグインを適用することで使えるdependencyReportタスクをbaseブランチとカレントブランチの両方で実行し、そのdiffをとっています。
このとき、dependency-tree-diff を使うことで、よりわかりやすいdiffをとれるようにしています。
なお、dependencyReportタスクではなく元々あるdependenciesタスクを使ってdiffをとることもできます。しかし、残念ながらdependenciesタスクはmulti projectに対応しておらず、それぞれのprojectに対して順次dependenciesタスクを実行していかなくてはなりません。これをすると多くの時間を要するため、multi project対応がされているdependencyReportタスクを採用しています。
まとめ
Gradleの依存関係の意図しない変更を可視化するためのGitHub Actions「gradle-dependency-diff-action」について紹介しました。
Gradleでは、予期しないバージョンの更新が発生することがあり、それが重大な問題につながるケースもあります。本Actionsを利用することで、Pull Requestごとの依存関係の差分を簡単に確認でき、レビューの助けとなるはずです。
ぜひ試してみてください!
Discussion