7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GitLab CIとRenovateでGoパッケージを自動更新する

Last updated at Posted at 2021-06-06

概要

Webアプリケーション開発のソースコードは、その特性上、多くの外部ライブラリに依存します。
使用者が多いパッケージほど更新頻度が高いため、追従するためには外部パッケージの定期的なアップデートが必要になります。

外部パッケージを定期的に更新していないと、

  • アップデート時の差分が大きくなり、リスクが高くなる

  • 使用中のバージョンのサポートが打ち切られる

  • 古いバージョンにロックインしてしまう

などの問題が発生し、事業インパクトを与える問題に発展しかねません。
ただ、人力での外部パッケージの定期更新作業は面倒です。また、施策を回すための開発より優先度が低くなるため、必要に駆られるまでは後回しにされやすい。

本記事は、外部パッケージのメジャーアップデート検知&更新の自動化を扱った内容となります。

筆者は、業務ではバージョン管理ツールとしてGitLabを使用しています。本記事では外部パッケージのメジャーアップデート検知にRenovate、定期実行ツールとしてGitLab CIを使ったgoパッケージの自動更新のセットアップ方法を扱います。

Renovateとは

パッケージの依存関係の更新を自動で検知し、対象ブランチにmerge or pull requestしてくれるツールです。
対象はgo modulesの他にも、

  • npmパッケージ
  • Gem
  • pip

など、他にもさまざまな言語のパッケージ管理ツールをサポートしています。

似たようなものに、Dependabotがあります。こちらは2019年、GitHubに買収されたこともあり、現在はGitHub公式機能になっているため、こちらの方が知名度は高いかもしれません。

筆者は当初、このDependabotを使用する予定だったのですが、こちらをGitLabと組み合わせるには設定が何やら面倒そうでした。

Renovateの方はDockerHubの方に公式イメージがあるので、こちらをGitLabのCIツールであるgitlab-ciでビルドし、Renovateのスクリプトを実行するだけで済みます。この手軽さから、今回はGitLab CI × Renovateの構成を選択しています。

環境

手順

を参考にさせていただき、以下の手順で行いました。

  • RenovateコンテナからGitLabリポジトリにアクセスできるように、 access tokenを発行
  • Renovateの設定
  • GitLab CIの設定

GitLab側の設定(アクセストークンの発行)

Renovateの設定(Renovate.json)

renovate.jsonに、Renovatebotの設定を書き込みます。

renovate.json
{
  "extends": [
    "config:base"
  ],
  "timezone": "Asia/Tokyo"
}

基本的に標準の設定をそのまま用いています。

今回は自動マージの設定はしておりませんが、その設定も行うことができます。
他にも、様々なオプションを設定できるので、詳しい情報は以下をご参照ください。

GitLab CIの設定(gitlab-ci.yml, schedular)

gitlab-ci.ymlに、実行するジョブの設定を記述します。

gitlab-ci.yml
stages:
  - check_version
renovate:
  stage: check_version
  image:
    name: renovate/renovate:latest
    entrypoint: [""]

  script:
    - node /usr/src/app/dist/renovate.js --platform gitlab --token {$先ほど作成したアクセストークン} --endpoint https://gitlab.com/api/v4 $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME

  only:
    variables:
      - $renovate
    refs:
      - master
image:
    name: renovate/renovate:latest

の部分で、renovateのDocker imageのlatestタグを指定しています。
また、

only:
  variables:
    - $renovate
  refs:
    - master

onlyで、ジョブが作成される条件を制御できます。
variablesrefキーワードで、後で設定する$renovateという変数が有効になっているmasterブランチのイベントに対して、ジョブを作成するよう設定しています。

この設定がないと、リポジトリでのあらゆるイベントに対してジョブが作成されてしまいます。

この時点でのディレクトリは以下のようになっています。

$ tree
.
├── gitlab-ci.yml
└── renovate.json

テスト用にgitlab-ciを手動実行してみる

設定が終わったところで、リモート上で動作確認してみます。
リモートへ上げずに、ローカルのDockerコンテナでrenovateを動作させる方法は以下になります。

docker run --rm renovate/renovate --platform gitlab --token {先ほど作成したtoken} --endpoint https://gitlab.com/api/v4 {リポジトリ名}

テスト用go.modの作成

動作を確認するため、サンプル用のgo modを作成します。

$ go mod init

テスト用に、わざとバージョンが低いパッケージを取得します。今回はginを対象にしています。

$ go get github.com/gin-gonic/gin@v1.6.1

最終的なディレクトリ構成は以下になります。

$ tree
.
├── go.mod
├── go.sum
└── renovate.json

ここまででリモートにpushします。

スケジューラの登録

GitLabで[CI/CD]→[Schedules]→[New schedule]と進み、ジョブのスケジューラを登録します。
スクリーンショット 2021-06-06 10.45.48.png

実行は一週間に1回の頻度を指定しています。また、Variablerenovateという変数を有効化します。
この変数は、先ほど設定したgitlab-ci.ymlでジョブの制限条件で使用するものとなります。

スケジュールのテスト実行

GitLabで[CI/CD]→[Schedules]→[▶︎]を押すと、ジョブを手動実行できます。
スクリーンショット 2021-06-06 11.13.29.png

パッケージのメジャーアップデートがあることを検知しており、masterブランチに対してバージョンアップ用merge requestが作成されていることが確認できます。

スクリーンショット 2021-06-06 11.23.30.png

マージリクエストの中身をみてみると、go.modgo.sumの依存パッケージが更新されていることがわかります。
スクリーンショット 2021-06-06 11.15.54.png

おわりに

RenovateをGitLab CIで動かし、メジャーアップデートを検知する仕組みを行いました。人力による外部パッケージのメジャーアップデート追従は厳しいものがあるので、できることなら自動化しておきたいです。

また、業務に導入する際には、そのままだとMerge Requestが放置されたり一部の人に対応が集中したり、などの新たな課題が考えられます。こちらの記事を参考に、マージリクエストをランダムにメンバーにアサインさせるなどの工夫が必要かなと思います。

参考資料

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?