GitLab CIで定期的にgemの更新を確認する方法

Tips
2020年02月28日 10:00

概要

私は普段、Railsを使って作ったWebアプリケーションを、GitLabを使って管理しています。

ここでは、私が行なっているRailsとGitLabの組み合わせで、定期的にgemの更新を確認する方法を説明します。

環境

  • Rails 6.0
  • GitLab 12.7

なぜ定期的に確認するのか

作成したWebアプリケーションでは、Rails自体を含め、たくさんのgemで構成されています。

そのため、gemに脆弱性やバグが含まれていた際には更新を必要があります。

手動で時々更新するというのもいいのですが、意外と後回しになったり忘れていたりして、更新しないまま結構な日にちが経っていたということもあります。

そこで、定期的に更新があるかを確認してIssueに登録してしまうという方法を採用することにしました。

確認方法

定期的に行うという動作は、GitLab CIを使うことで実現します。

GitLab CIを行うために、.gitlab-ci.ymlに次の内容を記述します。

check-outdated-gem:
  image: ruby:latest
  only:
    - schedules
  script:
    - gem install bundle_outdated_formatter
    - wget https://gitlab.com/snippets/xxxxxxx/raw -O check-outdated-gem.rb
    - ruby check-outdated-gem.rb
  variables:
    ACCESS_TOKEN: $ACCESS_TOKEN

onlyのschedulesは、後述するSchedulesからCIが実行された場合のみ実行するということを表しています。

今回、Issueの登録ではMarkdownの形で登録するため、bundle_outdated_formatterというgemを使用して、通常の出力を変換します。
そのため、最初にbundle_outdated_formatterをダウンロードしています。

ACCESS_TOKENという環境変数は、Issueを登録できるユーザのアクセストークンを設定しています。
アクセストークンの設定は、Gitに含めると危険なため、プロジェクトのSettings > Variablesで行なっています。

また、GitLab CIでは、GitLabのスニペットから次のようなソースコードをダウンロードして実行しています。
スニペットのURLは、各自でアップロードして設定してください。

require 'net/http'
require 'json'

project_id = ENV['CI_PROJECT_ID']
private_token = ENV['ACCESS_TOKEN']
title = "Outdated gems #{`date`}"

result = `bundle outdated | bof -f markdown`

uri = URI.parse("#{ENV['CI_SERVER_URL']}/api/v4/projects/#{project_id}/issues")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme === 'https'

params = { title: title, description: result }
headers = { 'PRIVATE-TOKEN' => private_token, 'Content-Type' => 'application/json' }
response = http.post(uri.path, params.to_json, headers)

gemの確認は、bundleコマンドで行っています。

Issueへの登録はGitLabのWebAPIを介して行なっています。

定期的な実行

定期的な実行は、GitLab CIのSchedulesという機能を使って行います。

Schedulesの設定は、プロジェクトのCi/CD > Schedulesから行います。

そこで、新しいScheduleを設定することで、あとは定期的に実行されます。

私は、月に1度実行するようにしました。

これで、全ての設定が終わり、Gemの更新を定期的に確認できるようになりました。

さいごに

GitLab CIは、使い方次第でいろいろなことができます。

今後もGitLab CIを使って、いろいろなことを自動化して日々の作業を楽にしていけたらと思っています。