DEV Community

Ryosuke Hasebe
Ryosuke Hasebe

Posted on

Visualizing Gradle Dependency Differences! Introducing "gradle-dependency-diff-action"

I’d like to introduce my GitHub Actions, gradle-dependency-diff-action. With this Action, you can easily check how Gradle dependencies change due to a Pull Request.

Motivation

Because Gradle resolves library dependencies transitively, unintentional dependency changes sometimes occur.

For example, let’s say you update a library called tink, as shown below. At first glance, it looks like just a minor update. When you get a Pull Request with such a change, you might quickly approve it, assuming there’s no issue.

 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")
 }
Enter fullscreen mode Exit fullscreen mode

However, tink actually depends on protobuf-java, and because of this update, the dependency changes as follows:
protobuf-java quietly goes from 3.25.1 to 4.27.0. In Gradle, when there’s a conflict in dependency versions, it basically adopts the latest version.

-+--- 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
Enter fullscreen mode Exit fullscreen mode

In this way, there can be “hidden differences” that aren’t apparent just by looking at the code diffs in the Pull Request.

I created gradle-dependency-diff-action to visualize these hidden differences.

  • Side note 1
  • Side note 2
    • Recently, Gradle introduced something called “dependency locking,” which is somewhat like package-lock.json in npm. However, it doesn’t seem to be very popular. I tried it myself, and it felt somewhat inconvenient… (I won’t go into details here.)

What is gradle-dependency-diff-action?

This Action addresses the issue described above by doing the following for Pull Requests:

  • Detects any differences in the Gradle dependencies resulting from the Pull Request.
  • When differences are detected, you can choose how to be notified (configurable):
    • Describe the differences in GitHub Checks
    • Post a comment on the Pull Request
    • Add a label to the Pull Request
    • Upload the dependency differences to GitHub Actions Artifacts in both text and HTML format

The appearance of the PR:
ss1

The appearance of the Checks:
ss2

The HTML report generated in the actions artifact:
ss3

How to use

Apply the project-report plugin

Apply the project-report plugin to the project where you want to detect dependency differences.

plugins {
    //...
    `project-report` // HERE !
}
Enter fullscreen mode Exit fullscreen mode

Write a workflow

First, try writing a workflow like the one below. It’s very easy to get started.

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
Enter fullscreen mode Exit fullscreen mode

How does it get the dependency diff?

In short, by applying the project-report plugin, we can use the dependencyReport task. We run this task on both the base branch and the current branch, then take a diff of the outputs.

We use dependency-tree-diff to make the diff easier to understand.

Technically, we could have used the existing dependencies task instead of the dependencyReport task. However, the dependencies task doesn’t support multi-project setups, meaning we’d have to run it sequentially for each subproject, which would take a lot of time. Since the dependencyReport task supports multi-project setups, we chose to use it.

Summary

We introduced gradle-dependency-diff-action, a GitHub Action that visualizes unintended changes in Gradle dependencies.

Sometimes unexpected version updates can occur in Gradle, and those can lead to serious issues. By using this Action, you can easily check for dependency differences in each Pull Request, which will help during reviews.

Please give it a try!

Top comments (0)