Gradleでライブラリのアップデート自動検知

この記事はAizu AdventCalendar 8日目の記事です。

adventar.org

はじめまして。元会津大学生のスルメです。
いまはDMMでAndroidエンジニアやってます。

はじめに

Gradleでマルチモジュールで開発しているとライブラリのバージョン管理を一か所でやりたくなります。 そのためversion.gradleといったようなファイルで一括管理をして各モジュールでそこで定義した変数から値を取得しるような実装をします。 このようにするとversion.gradleに使用ライブラリや言語のバージョンなどが集約されて変更が容易になります。 ただし、version.gradleはあくまで変数が書いてある場所でしかないのでIntellijやAndroidStudioなどでライブラリのアップデートを検知できません そのため今回はCI時にライブラリのアップデートを自動で検知す仕組みを導入したのでそれについて話していきます。

CIで自動検知

今回導入したものはこちらです。

github.com

こちらを導入するとgradle taskが新しく増えます

gradle dependencyUpdates
./gradlew dependencyUpdates

これだけでライブラリのアップデートを自動で検知してくれます。またデフォルトだっとtxtをはいてくれますがオプションを付けるとjson, xmlをはいてくれます。 これで準備は完了です。 あとは .circleci/config.yml でこのコマンドを実行すればライブラリのアップデートを自動で検知してくれます。 ただこの段階だと検知した物を外に投げる手段がありません。そのためDangerを用います。

github.com

あとはjsonで出力したものをdanger側のコードで解析してPRのコメントに流せば完成です!!!

./gradlew dependencyUpdates -Drevision=release -DoutputFormatter=json

f:id:slme9364:20191203083326p:plain

注意事項としてgradle-version-pluginsは初期設定だと最新版を検知するので設定を加えないとα, β, rcなども対象に含まれます。個人プロダクトの場合は問題ないかもしれませんが業務プロダクトだとそうもいかないのでrelease版のみを検知するようにしましょう。

公式docにも書いてありますが特定versionをrejectすると動きます。

def isNonStable = { String version ->
  return ['ALPHA', 'BETA', 'RC', 'EAP', 'DEV'].any { it -> version.toUpperCase().contains(it) }
}
dependencyUpdates {
  rejectVersionIf {
    isNonStable(it.candidate.version)
  }
}

ちなみにoutputしてきたjsonを解析して警告するとこのDangerfileの実装です。Ruby力は皆無なのでコードがクソなのは許してください

require 'json'
Dir.glob("**/dependencyUpdates/report.json").each { |report_file_path|
  results = File.open(report_file_path) do |io|
    JSON.load(io)
  end
  available_update_lib = results["outdated"]["dependencies"]
  available_update_lib.each { |lib|
    report = "#{lib["group"]}.#{lib["name"]}: #{lib["version"]} -> #{lib["available"]["release"]}"
    warn(report)
  }
}