Redmineのバグを修正する流れ


My Redmine

今週のブログ担当は石川です。 Redmineを日常的に利用していると、不審な挙動やちょっとしたバグに気付くことがあります。そんな時、ファーエンドテクノロジーの社員がどのように対応し、最終的にRedmineにパッチを送るのか、その流れをまとめてみました。 この記事は Redmine Advent Calendar 2024 の12月11日分です。

1. 不審な挙動の発見

ある日、社内Slackで次のようなつぶやきが投稿されました。

Redmineのバグの発見
Redmineのバグの発見

ファーエンドテクノロジーでは自分たちの業務に使う社内Redmineを開発中のバージョンのRedmineにしているため、開発担当以外の社員もバグを見つけてくれることが多いです。 Redmineのバグを見つけて改善できた話 - ファーエンドテクノロジー株式会社

2. 再現性の確認

次に行うのは、問題が再現できるかどうかの確認です。 このときは最初は問題を再現できなかったのですが、

のように前提条件を合わせれば再現できるとわかりました。

ブラウザの違い、Redmineのバージョンの違い、プラグインやテーマの違い、設定の違いなどで再現できないことも多いので、再現ができるかの確認は複数の環境で行うようにしています。

問題の再現方法を調べている様子
問題の再現方法を調べている様子

3. Redmine.orgにチケットを作成

再現方法が固まったら、次に Redmine.org にチケットを作成してバグを報告します。(場合によっては原因がわかってから、どう修正すれば良いかがわかってから作ることもあります。)

こういったバグの報告チケットはよく作成されるのですが、プラグインの影響と思われるものや個人の環境によるものだったりと、開発者が再現できないために対応できていないものも少なくありません。そのため、チケットを作成する際には言語が違う開発者にも伝わるように丁寧に再現手順を示す必要があります。

また、日本語では「チケット」と呼ばれる機能が英語では「Issue」であるように固有名詞に違いがあるので、なるべくRedmineの英語の名称を使って説明を書くように気をつけています。

実際に作ったチケット
実際に作ったチケット: https://www.redmine.org/issues/40210

4. 原因を調査

次は原因を調査します。

Railsのフォームヘルパーで生成したセレクトボックスで include_blank オプションが効いていないということで「Railsの機能をそのまま使っているはずなのに、なぜ問題が起きているのだろう」と一度行き詰まりました。そこで、心当たりのあるメンバーがいないか聞いてみたところ有力な情報をもらえました。

問題の再現方法を調べている様子
問題の再現方法を調べている様子

このとき、Redmineでは ActionView::Helpers::Tagsadd_options メソッドをオーバーライドして include_blank オプションの挙動を書き換えていたために、一般的な include_blank オプションの挙動と異なってしまっていたようです。

また、add_options の書き換え自体は以前から行われていたのになぜ急に動かなくなったかというと、Rails 7.1へのアップデートの際に行われたコードの書き換え( /trunk/config/initializers/10-patches.rb - Diff - Redmine )が影響しているため、ということもわかりました。

ファーエンドテクノロジーにはRedmineを熟知したプロフェッショナルが何人もいるので、こういった問題の調査時にはとても心強いです。

5. 簡単な回避策を見つける

原因がある程度分かったら、「ここをこうすれば直りそう」という簡単な回避策を試します。

まず最初に試したのは、 /trunk/config/initializers/10-patches.rb - Diff - Redmine によって書き換わっていた部分を元の構造に戻すことです。このコード変更以外にも原因がある場合はコードを元に戻すだけでは解決しない場合もありますが、このときはコードを元に戻すだけで挙動が元に戻ることを確認できました。

diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb
index 1d932eb1f..6146ddfbe 100644
--- a/config/initializers/10-patches.rb
+++ b/config/initializers/10-patches.rb
@@ -38,14 +38,17 @@ ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || '
 module ActionView
   module Helpers
     module Tags
-      SelectRenderer.prepend(Module.new do
+      module SelectRenderer
+        private
+        alias :add_options_without_non_empty_blank_option :add_options
         def add_options(option_tags, options, value = nil)
-          if options.delete(:include_blank)
-            options[:prompt] = ' '.html_safe
+          if options[:include_blank] == true
+            options = options.dup
+            options[:include_blank] = ' '.html_safe
           end
-          super
+          add_options_without_non_empty_blank_option(option_tags, options, value)
         end
-      end)
+      end
     end

     module FormHelper

6. よりよい解決方法を模索

簡単な回避策が見つかったため、その挙動と問題が起きているときの挙動を見比べたりしながら、Redmine全体への影響や将来的な保守性を考慮した上で、より良い修正方法を模索します。

特にこのときは、メソッドのオーバーライドによる影響を小さくする変更が行われていたため、シンプルに元のコードに戻すだけでなく、構造としては新しい形のまま一部修正して問題を解決する方法を探しました。

最終的には次のように書き換えることで、コードの構造は変えることなく問題を修正できることがわかりました。

diff --git a/config/initializers/10-patches.rb b/config/initializers/10-patches.rb
index 1d932eb1f..6024e8c8d 100644
--- a/config/initializers/10-patches.rb
+++ b/config/initializers/10-patches.rb
@@ -41,7 +41,7 @@ module ActionView
       SelectRenderer.prepend(Module.new do
         def add_options(option_tags, options, value = nil)
           if options.delete(:include_blank)
-            options[:prompt] = ' '.html_safe
+            options[:include_blank] = ' '.html_safe
           end
           super
         end

7. 修正パッチを添付

チケットに問題の修正方法を提示します。

問題の修正方法を共有
問題の修正方法を共有

8. フィードバックを受けて対応する

提示した修正方法に対して、他の方からフィードバックがあったらそれに対応します。

このときは、そもそもメソッドの上書き自体が現在のRedmineには不要なのでは、というフィードバックがあり、該当のオーバーライド処理をなくすことが提案されました。 私はその提案について確認した上で、同意のコメントをしています。

Redmineはオープンソースソフトウェアで最初のコミットから既に18年経過しているため、どういう経緯で現状のコードになっているかを追うのは難しいのですが、そこをしっかりと調査したレビューによってオーバーライドしている箇所を減らし、今後同様の問題が起こるリスクを減らせるような良い対応ができました。

Slackで対応方針について話している様子
Slackで対応方針について話している様子
Redmine.org側でも対応方針への同意を伝える
Redmine.org側でも対応方針への同意を伝える

9. 修正内容がコミットされて問題が解決する

修正内容はRedmineのコミッターやその他の開発者によってレビューを受け、問題なければRedmineの公式リポジトリにコミットされます。これにより、バグが正式に修正され、次のリリースから利用者に反映されます。

対応完了を伝える様子
対応完了を伝える様子

まとめ

社内で発見された不審な挙動から始まり、原因調査、修正、Redmine.orgへのパッチ提供という流れを経て問題を解決するプロセスを、実際の例を基にブログにしてみました。

今回のブログでは、チケットの報告から原因の調査、修正まで行っていますが、もちろんチケットの作成やバグ報告チケットに再現できたことを書き込むなどの部分的な作業でも大きな貢献です。今回のような経験談を共有することで、Redmineコミュニティへの参加や貢献を考えている方の参考になれば幸いです。

今後もRedmineの改善活動を頑張っていきます!

My Redmine

【スタッフ募集中】
弊社ではAWSを活用したソリューションの企画・設計・構築・運用や、Ruby on Rails・JavaScriptフレームワークなどを使用したアプリケーション開発を行うスタッフを募集しています。採用情報の詳細
弊社での勤務に関心をお持ちの方は、知り合いの弊社社員・関係者を通じてご連絡ください。


こちらの記事もオススメです!
RedmineプラグインのシステムテストをPlaywrightで動かす
RedmineプラグインのシステムテストをPlaywrightで動かす方法を紹介します。
Redmine 6.0で使えるようになる「部分引用機能」の紹介とその実装
Redmine 6.0ではチケットやフォーラムでメッセージの一部を引用して返信できるようになります。この新機能の紹介と、どのように実現されているかを説明します。
来るRedmine 6.0でのデフォルトテーマの改善状況:見やすく、読みやすく
来るRedmine 6.0ではデフォルトテーマが改善され見やすく、読みやすくなります。その改善内容を紹介します。
ruby/ruby.wasm を使って Redmine をブラウザ内で動かす話
Ruby on Rails アプリケーションである Redmine の Wasm 化を試しました。
Redmineとプラグインの開発を支える自作のツール
Redmineとプラグインの開発をしやすくするために作ったツールを二つ紹介。
ファーエンドテクノロジーからのお知らせ(2025/01/15更新)
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に弊社社員の呂 勝男が登壇
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に、ファーエンドテクノロジー社員の呂勝男が登壇いたします。
オープンソースカンファレンス2025 Osakaに弊社代表の前田が登壇(ブース出展あり)
2025年1月25日に開催されるオープンソースカンファレンス2025 Osakaで、弊社代表の前田によるセミナー発表とブース出展を行います。
プロジェクト管理ツール「RedMica」バージョン 3.1.0をリリース Redmine互換のオープンソースソフトウェア
ファーエンドテクノロジー株式会社は、2024年11月19日(日本時間)、Redmine互換のプロジェクト管理ソフトウェア「RedMica 3.1.0」をリリースしました。
プロジェクト管理ツールRedmineのクラウドサービス「My Redmine」の海外向けサービス「My Redmine Global Edition」の提供を開始
「My Redmine」の海外向けサービスとして、新たに「My Redmine Global Edition」の提供を開始しました。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け