DependabotをGHEのプロジェクトに適用する
Saturday, February 15, 2020 11:17:00 AM
昨今のWebアプリケーション開発では、多数のOSSライブラリに依存しています。 私たちが開発するアプリケーションの脆弱性対応はもちろんのこと、これらのライブラリもセキュリティアップデートやバグフィックスなどが行われていきます。
では、ライブラリのバージョンを最新に追従するにはどうしたら良いでしょうか?
- ライブラリのソースリポジトリをチェックする。GitHubのことが多いので、Watchしておけば通知が届きます。
- 依存関係をチェックしてくれるBotを入れて、Slackなどに通知する。たとえば npmcheck2slackのようなもの
- 依存関係をチェックしてPRを出してくれるツールを導入する。
3つ目のPRを出すツールに関しては、対応する言語ごとに様々なものがありますが、今回はGitHubに買収されたことでも有名になったDependabotを導入してみたので解説します。
でもDependabotって、普通にGitHubから使えるでしょ?
そうなんです。ただ今回はGitHubでもGitHub Enterpriseを利用している場合には(まだ?)Dependabotを利用することができないので、CIで実行できるようにしてみたよ!という記事です。
想定されるプロジェクト環境
- ソースコードリポジトリはGHE
- CIサーバーにDrone.ioをオンプレ利用
ですが、GHEやDroneでなくても、この記事を理解してもらえれば利用可能になると思います。
つまりリポジトリやらCIやらをオンプレしているプライベートな開発環境で、依存関係更新ツールを使ってみようろいうことです。
Dependabotをオンプレで動かす
DependabotにはDependabot Update Scriptというものがあり、オンプレ環境で動かせるようになっています。
READMEに書いてあるとおり設定すれば良いのですが、私たちのプロジェクトでは以下のようにしました。
dependabot-drone
というリポジトリをGHEに作成。これをDroneのdaily cronで実行してPRを日次で作成させる- Dependabot Update Scriptは
dependabot-drone
に git submodule で追加する - Dependabot Update Scriptの更新もチェックしたいので、
dependabot-drone
自身の更新もチェックする
これをDrone.ioで実行するには、以下のような .drone.yml
ファイルを記述します。
clone:
git:
image: plugins/git
recursive: true # 2のとおり submodule を使う場合指定
pipeline:
# READMEに書いてあるインストール手順を定義
install:
image: dependabot/dependabot-core
pull: true
commands:
- cd dependabot-script
- bundle install -j 3 --path vendor
when:
event: cron
# 3の自身をアップデートする定義
dependabot-drone:
image: dependabot/dependabot-core
environment:
- GITHUB_ACCESS_TOKEN=xxxxxxxxxxxxxxxxx
- GITHUB_ENTERPRISE_HOSTNAME=github.xxxxx.com
- GITHUB_ENTERPRISE_ACCESS_TOKEN=xxxxxxxxxxxxxxxxx
- PROJECT_PATH=xxxxxx/dependabot-drone
- PACKAGE_MANAGER=submodules
commands:
- cd dependabot-script
- bundle exec ruby ./generic-update-script.rb
when:
event: cron
Dependabotのコア機能は dependabot/dependabot-core
というDockerイメージで提供されているので、このイメージを使って dependabot-script
を実行するということです。
このときに環境変数を指定します。
- GITHUBACCESSTOKEN パッケージマネージャ(npmやcomposer, bundlerなど)が参照するリポジトリにGitHub APIを使ってアクセスするため、アクセストークンを設定しないとAPI上限に引っかかってしまいます。このため必ず設定しましょう。
- GITHUBENTERPRISEHOSTNAME GHEのホスト名を指定します
- GITHUBENTERPRISEACCESS_TOKEN GHEにアクセスするためのアクセストークンを設定します
- PROJECT_PATH GHEのプロジェクトパスを指定します
- PACKAGE_MANAGER ここではsubmodulesを指定しています。他の候補はREADMEに書いてあるとおりソースコードを参照します
アプリケーションリポジトリをチェックしていく
あとは、先ほど作った .drone.yml
ファイルにアプリケーションリポジトリを追加してくだけです。
たとえば frontend-app
というリポジトリをチェックしたい場合は、このようになります。
# 省略...
pipeline:
# 省略...
dependabot-drone:
# 省略...
frontend-app:
image: dependabot/dependabot-core
environment:
- GITHUB_ACCESS_TOKEN=xxxxxxxxxxxxxxxxx
- GITHUB_ENTERPRISE_HOSTNAME=github.xxxxx.com
- GITHUB_ENTERPRISE_ACCESS_TOKEN=xxxxxxxxxxxxxxxxx
- PROJECT_PATH=xxxx/frontend-app
- PACKAGE_MANAGER=npm_and_yarn
commands:
- cd dependabot-script
- bundle exec ruby ./generic-update-script.rb
when:
status: [success, failure]
event: cron
PROJECT_PATH
と PACKAGE_MANAGER
、パイプラインの名前が違うだけで他の定義はすべて一緒です。
status: [success, failure]
を入れているのは、複数リポジトリある場合に、途中で失敗しても継続したいための設定です。
PRがやってくる日々
daily cron に従って Dependabot からPRが送られてきます。
これでWatchしてPRしなくて良いし、とても便利ですよね。 PRのコメントに Changelog や Commit など変更のリンクがあるので、内容をチェックすることもできます。
プライベートでも依存関係の更新をちゃんとやれるよ!ということでした。