💎

GemfileをRenovateで自動更新する時に気をつけること

に公開

TLDR

  • RenovateはGemfileにバージョン範囲の指定がないgemをデフォルトでは対象としない
  • Gemfile.lockでのみバージョン指定をしている運用の場合、 "rangeStrategy": "update-lockfile" を設定する必要がある
  • たまたまGemfileでバージョン指定しているgemがあると、そのgemについてはRenovateが動作してくれるため、設定ミスになかなか気づけなかった

Renovateを使ってnpmパッケージの自動更新をしている

VideoTouch社では、使用しているnpmパッケージをRenovateを使って定期的に更新しています。
Dependabotも併用しつつ、重大度の高いセキュリティアラートがあった場合は迅速にアップデートする体制を組んでいます。

Renovateの設定は公開リポジトリを使い共有することができます。
社内の複数のプロダクト・リポジトリを跨いで共通する設定はこちらに置いています。
https://github.com/Viibar/renovate-config

RubyGemsでも使い始めたが動作がおかしかった

VideoTouchはRuby on Railsで開発しているため、GemfileもRenovateで自動更新しようということになりました。

Renovateを当該リポジトリに対して有効化し、renovate.jsonを配置すればよいです。 "enabledManagers": ["bundler", ...] のように、bundlerでのRenovate実行を設定します。

renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["github>viibar/renovate-config"],
  "enabledManagers": ["bundler", "npm"],
  "packageRules": [
    // このリポジトリでのみまとめてアップデートしたいもののグルーピングなどのルール設定...
  ]
}

RubyGemsを扱う場合には設定を変える必要があった

しかし、設定してから暫く不可解な状況が続きました。
更新があるはずのほとんどのgemはRenovateの自動更新がされず、一部のgemでのみRenovateが動いてくれます。

改めて諸々調査したところ、弊社でのGemfileの運用と、RenovateのRuby Bundler更新のデフォルト挙動が異なっているため、問題が起きていると判明しました。

まず弊社の場合、下のGemfileの例の様に、一部の重要なものやクリティカルなもののみGemfileにバージョンを明示し、基本的にはGemfile.lockでバージョンを扱っているという運用です。

Gemfile
source "https://rubygems.org"

ruby "3.4.5"

gem "bundler", "~> 2.1.4"
gem "rails", "~> 7.2.0"

gem "active_model_serializers"
gem "dartsass-rails"
gem "faraday"
gem "kaminari"

group :development, :test do
  gem "rspec-rails"
end

しかし、Renovateのデフォルト挙動は「GemfileのSemantic Versioningに従う。バージョン範囲指定がなければ何もしない」です。弊社のようにGemfile.lockでバージョン指定している場合は "rangeStrategy": "update-lockfile" という設定が必要でした。[1]

https://docs.renovatebot.com/ruby/ より

Warnings
When using "rangeStrategy": "update-lockfile", all gems listed in the Gemfile will be updated, even if they do not have a version specified.

When using other rangeStrategy options, Renovate doesn't update dependencies without a version constraint.

というわけで、弊社のGemfileの運用の仕方の場合は "rangeStrategy": "update-lockfile" という設定が必要でした。
しかし、単にその設定を行なってしまうとnpmパッケージの自動更新にも影響してしまうため、gemを更新する場合にのみ設定したいです。

renovate.jsonでは、rangeStrategyなどの設定もpackageRulesでパッケージマネージャー別に設定することができます。
次の様にrenovate.jsonを更新して、問題を解消しました。

renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["github>viibar/renovate-config"],
  "enabledManagers": ["bundler", "npm"],
  "packageRules": [
    {
      "managers": ["bundler"],
      "rangeStrategy": "update-lockfile"
    },
    // その他のルール設定...
  ]
}

これで、npmパッケージとgemのRenovateによる自動更新体制を確立できました!🎉

宣伝

VideoTouch社では共にプロダクト開発をするエンジニアを募集中です。

https://findy-code.io/companies/2508/jobs

https://videotouch.co.jp/recruit

https://viibar.notion.site/Engineer-Entrance-Book-1df6279cc117804b9f1ffefdc0fde080

脚注
  1. 弊社の場合は更に"rangeStrategy": "bump"にしていたことも影響しているかもしれないが、そこは未検証。 ↩︎

Discussion