Ruby on Rails に貢献する方法

本ガイドでは、Ruby on Railsの開発にあなたが参加する方法について説明します。

このガイドの内容:

  • GitHubでissueをレポートする方法
  • mainブランチをcloneしてテストスイートを実行する方法
  • 既存のissueを解決する方法
  • Ruby on Railsのドキュメントに貢献する方法
  • Ruby on Railsのコードに貢献する方法

Ruby on Railsは、「どこかで誰かがうまくやってくれているフレームワーク」ではありません。Ruby on Railsには、長年に渡って数千人もの開発者が貴重な貢献を行っています。貢献の内容は、わずか1文字の修正から、大規模なアーキテクチャ変更、重要なドキュメント作成まで多岐に渡ります。これらの作業はいずれも、Ruby on Railsをすべての人々にとってよりよいものにするためです。コードを書いたりドキュメントを作成したりする以外にも、issueの作成やパッチのテストなど、さまざまな方法で貢献できます(訳注: サンプルのコミットメッセージも日本語に翻訳していますが、実際のissueやコミットメッセージは英語で書きます )。

RailsのREADMEにも記載されているように、Railsのコードベースやサブプロジェクトのコードベースについて、issueトラッカーやチャットルームやメーリングリストでやり取りする方はすべて、Railsの行動規範に従うことが期待されます。

1 issueを作成する

Ruby on RailsではGitHubのIssueトラッキング機能でissueをトラッキングしています(issueは、主にバグや新しいコードの貢献に使われます)。Ruby on Railsでバグを見つけたら、そこから貢献を開始できます。GitHubへのissue送信、issueへのコメント、プルリクエストの作成を行うには、まずGitHubアカウント(無料)を作成する必要があります。

Ruby on Railsの最新リリースで見つけたバグは最も注目を集める可能性があります。Railsコアチームは、edge Rails(開発中のRailsのコード)でのテストに時間を割いてくれる方からのフィードバックも常に歓迎しています。テスティング用にedge Railsを入手する方法については後述します。

1.1 バグレポートを作成する

Ruby on Railsで何らかの問題を発見し、それがセキュリティ上の問題でなければ、まずGitHubのissueを検索して、既にレポートがあがっているかどうかを確認してみましょう。該当する問題がまだissuesにない場合は、新しいissueを作成します。セキュリティ上のissueをレポートする方法については次のセクションで説明します。

issueレポートには、少なくともタイトルとissueの明快な説明が必要です。できるだけ多くの関連情報を含めるようにしてください。また、問題を再現できるコードサンプルもできるだけ含めてください。期待される動作になっていないことを示す「失敗する」単体テストも含めてもらえるとさらに助かります。他の人たちにとっても自分自身にとっても、バグの再現と修正点の把握がやりやすくなることを目指してください。

そして、issueの扱いについて過度な期待を抱かないことも肝心です。地球滅亡レベルの重大な問題でもない限り、issueがひとりでに進捗したり、誰かがただちにバグ修正に名乗りを上げるという期待を持たないことです。issueを作成するのは、同じ問題を共有する他の人がバグを追いかけ、共同で修正できるようにするためです。

1.2 実行可能なテストケースを作成する

自分のissueを再現する手順を用意しておくと、他の開発者がissueを確認・調査・修正する上で大変役立ちます。そのための方法は、実行可能なテストケースを提供することです。この作業を少しでも楽にするために、Railsチームは以下のバグレポート用テンプレートを多数用意しているので、これを元に作業を開始できます。

  • Active Record(モデル、データベース)issue用テンプレート: gem / main
  • Active Record(マイグレーション)issue用テンプレート: gem / main
  • Action Pack(コントローラ、ルーティング)issue用テンプレート: gem / main
  • Active Job issue用テンプレート: gem / main
  • Active Storage issue用テンプレート: gem / main
  • Action Mailbox issue用テンプレート: gem / main
  • その他のissue用一般テンプレート: gem / main

テンプレートには「ボイラープレート(boilerplate)」と呼ばれる一種のひな形コードが含まれており、これを用いてRailsのリリースバージョン(*_gem.rb)やedge Rails(*_main.rb)に対するテストケースを設定できます。

該当するテンプレートの内容をコピーして.rbファイルに貼り付けて適宜変更を行い、issueを再現できるようにします。このコードを実行するには、ターミナルでruby the_file.rbを実行します。テストコードが正しく作成されていれば、このテストケースはバグがあることによって失敗する(failと表示される)はずです。

続いて、この実行可能テストケースをGitHubのgistで共有するか、issueの説明に貼り付けます。

1.3 セキュリティissueの特殊な取り扱い方法について

セキュリティ脆弱性に関する問題は、一般公開されているGitHubのissueレポート機能には「絶対に掲載しないでください」。セキュリティ関連のissueを扱う方法について詳しくは、Railsセキュリティポリシーページ(英語)を参照してください。

1.4 機能リクエストについて

GitHubのIssueは「機能リクエスト」の場ではありません。Ruby on Railsで欲しい機能があるなら、自分でコードを書くか、誰かにお願いしてコードを書いてもらってください(Ruby on Rails用のパッチを提案する方法については後述します)。GitHubのissueにこのような「欲しい機能リスト」をコードも添えずに書き込んでも、Issueをチェックした人によって早晩「無効」とマーキングされて終わるでしょう。

その一方、「バグ」と「機能」は簡単に線引きできないこともあります。一般に、「機能」はアプリケーションに新しい振る舞いを追加するものであり、「バグ」は既存の振る舞いが期待どおりでないことを示します。場合によってはコアチームがバグか機能かを審査する必要もあるでしょう。とはいうものの、バグか機能かの違いは、送られたパッチをどのリリースに反映するかという扱いの違いでしかないことがほとんどです(バグ修正は早めにリリースされ、機能追加はメジャーリリースで反映されるなど)。私たちは、修正パッチと同様に機能追加も大歓迎しています。送っていただいた機能追加をメンテナンス用ブランチに押し込めておしまいにすることはしません。

機能追加用のパッチを送信する前に自分のアイディアに意見を募りたい場合は、rails-coreメーリングリストにメールを送信してください。もし誰からも返信がなければ、自分のアイディアに誰も関心を持っていないということがわかります。あるいは、自分のアイディアに興味を示してくれる人が返信してくれるかもしれません。あるいは「悪いけど採用できそうにないかも」という返信があるかもしれません。しかしこのメーリングリストは、こうしたアイディアについて議論するために用意された場所です。逆にGitHubのissueは、こうした新しいアイディアで必要な議論(ときには長期かつ複雑になることもあるでしょう)を行うには向いていません。

2 既存のissueの解決を手伝う

issueをレポートする以外に、既存のissueにコメントすることでコアチームによるissue解決を手伝うことも可能です。Railsのコア開発経験が初めての方にとってはRailsのコードベースや問題解決の手順に慣れる機会にもなるので、issueへのコメント追加は貢献の第一歩を踏み出すにも最適でしょう。

GitHubのissueにあがっているissueのリストを見てみると、注目を集めているissueがたくさん見つかります。自分も何かissueに貢献できる方法はあるでしょうか。もちろんあります。しかもさまざまな方法があります。

2.1 バグレポートの確認

貢献の第一歩として、バグレポートを確認する作業も非常に有用です。issueを自分のコンピュータで再現できるかどうかを試してみましょう。問題をうまく再現できたら、そのことをissueのコメントに追加しましょう。

issueにあいまいな点があるなら、どこがわかりにくいかをコメントで伝えましょう。バグを再現するうえで有用な情報を追加したり、不要な手順を削除したりするのも重要な貢献です。

テストが添えられていないバグレポートを見かけたら貢献のチャンスです。「失敗する」テストを作成して貢献できますし、既存のテストファイルを詳しく読むことでテストの書き方も学べるので、Railsのソースコードを深く調べる絶好の機会となります。作成するテストは「パッチ」の形式で投稿するのがベストです。詳しくはRailsのコードに貢献するで後述します。

バグレポートは、とにかく簡潔でわかりやすく、そして現象をなるべく楽に再現できるように書きましょう。バグを修正する開発者にとって何よりありがたいのは、このような「よいバグレポート」です。たとえバグレポートを作成するあなたが最終的にコードを書かなくても、よいバグレポートはそれだけで大きな貢献になります。

2.2 パッチをテストする

GitHubからRuby on Railsに送信されたプルリクエスト(pull request、プルリクとも)をチェックしてくれる人もいると助かります。寄せられた修正を適用するには、まず以下のように専用のブランチを作成します。

$ git checkout -b testing_branch

続いて、このリモートブランチでローカルのコードベースを更新します。たとえばJohnSmithという名前のGitHubユーザーが、Railsをforkして https://github.com/JohnSmith/rails の"orange"というトピックブランチにpushする場合は、以下を実行します。

$ git remote add JohnSmith https://github.com/JohnSmith/rails.git
$ git pull JohnSmith orange

ブランチを適用したらテストしてみます。次のような点に注意しながら進めましょう。

  • 修正は本当に有効か。
  • このテストでみんなが幸せになれるか。テストの内容を自分で理解できているか。足りないテストはないか。
  • ドキュメントの記載は適切か。ドキュメントも更新する必要があるか。
  • 自分の実装がよいと思えるか。同じ変更をもっと高速かつ素晴らしい方法で実装できないか。

プルリクエストの変更内容がよさそうだと思えたら、GitHubのissueに何らかの形で賛同するコメントを追加しましょう。コメントを追加するときは、最初に「この変更はよい」と書き、続いてどの変更点がよいと思うかについてもなるべく具体的に述べておきましょう。たとえば次のようにコメントします。

I like the way you've restructured that code in generate_finder_sql - much nicer.(generate_finder_sqlのコードが非常によい形で再構築されている点がよいと思います)The tests look good too.(テストもよく書けているようです)

単に「+1」だけのコメントを書く人をよく見かけますが、これでは他のレビュアーにほとんど注目されないでしょう。あなたが十分時間をかけてプルリクエストを読んだことが伝わるようにコメントを書きましょう。

3 Railsのドキュメントに貢献する

Ruby on Railsには2種類のドキュメントがあります。1つはこの「Railsガイド」であり、Ruby on Railsを学ぶためのドキュメントです。もう1つはAPIドキュメントであり、こちらはリファレンス用です。

Railsガイドの改善にはどなたでも貢献できます。Railsガイドに求められる改善とは、「一貫していること」「矛盾がないこと」「読みやすいこと」「情報の追加」「事実と異なっている部分の修正」「タイポの修正」「最新のedge Railsに追い付くこと」などです。

英語ドキュメントに貢献したい方は、Railsガイドの英語ソースファイルを変更してから、プルリクエストでmainブランチに変更の反映を依頼してください。

ドキュメント関連で貢献するときは、API ドキュメント作成のガイドラインRails ガイドのガイドラインに十分目を通しておいてください。

4 Railsガイドの翻訳に貢献する

Railsガイドを翻訳するボランティアも歓迎いたします。次の手順に沿って進めます。

  • https://github.com/rails/rails をforkする。
  • 翻訳先の言語名に対応するフォルダをsourceフォルダの下に追加する。たとえばイタリア語の場合はguides/source/it-ITフォルダを追加します。
  • guides/sourceに置かれているコンテンツファイルをそのフォルダ内にコピーして翻訳する。
  • HTMLファイルは翻訳しないでください(HTMLファイルは自動生成されます)。

翻訳の送り先はRailsリポジトリではないことにご注意ください。上述したように、翻訳はforkしたリポジトリで行います。ドキュメントのメンテナンスをパッチベースで行う場合、英語のみに統一しておかないと維持できないためです。

ガイドをHTML形式で生成するには、guidesディレクトリにcdして以下を実行します(言語がit-ITの場合)。

# ガイドで必要なgemだけをインストールすること
# (取り消すにはbundle config --delete withoutを実行)
$ bundle install --without job cable storage ujs test db
$ cd guides/
$ bundle exec rake guides:generate:html GUIDES_LANGUAGE=it-IT

これで、outputディレクトリにガイドが生成されます。

redcarpet gemはJRubyでは動きません。

現在把握されている翻訳プロジェクトは以下のとおりです(バージョンはそれぞれ異なっています)。

5 Railsのコードに貢献する

5.1 development環境を構築する

バグレポートを送信して既存の問題解決を手伝ったり、コードを書いてRuby on Railsに貢献したりするためには、ぜひともテストスイートを自分の環境で実行できるようにしておく必要があります。このセクションでは、自分のパソコン上でテスト用の環境を構築する方法について解説します。

5.1.1 楽な方法

rails-dev-boxにある作成済みのdevelopment環境を入手するのがおすすめです。

5.1.2 面倒な方法

Rails development boxを利用できない事情がある場合は、RailsガイドのRailsコア開発環境の構築方法を参照してください。

5.2 Railsリポジトリをクローンする

コードに貢献するには、最初にRailsリポジトリをクローンする必要があります。

$ git clone https://github.com/rails/rails.git

続いて、専用のブランチを作成します。

$ cd rails
$ git checkout -b my_new_branch

このブランチ名はローカルコンピュータの自分のリポジトリ上でしか使われないので、どんなブランチ名でも構いません。このブランチ名がRails Gitリポジトリにそのまま取り込まれることはありません。

5.3 Bundle install

必要なgemをインストールします。

$ bundle install

5.4 ローカルブランチでアプリケーションを実行する

ダミーのRailsアプリケーションで変更をテストする必要がある場合は、rails new--devフラグを追加すると、ローカルブランチを使うアプリケーションが生成されます。

$ cd rails
$ bundle exec rails new ~/my-test-app --dev

~/my-test-appで生成されたアプリケーションはローカルブランチのコードを実行します。サーバーを再起動すると、設定の変更をアプリケーションで確認できます。

JavaScriptパッケージについては、以下のようにyarn linkを用いることで、生成されたアプリケーションでローカルブランチをソースにできます。

$ cd rails/activestorage
$ yarn link
$ cd ~/my-test-app
$ yarn link "@rails/activestorage"

5.5 コードを書く

準備が整ったら、早速コードを追加・編集しましょう。自分のブランチ上のコードは自由に書けます(念のためgit branch -aを実行して、現在使っているブランチが正しいことを確認しておきましょう)。自分が書いたコードをRailsに追加するときは、以下の点を心がけてください。

  • 正しいコードを書くこと。
  • Railsで広く使われている規約やヘルパーメソッドを用いること。
  • 自分が書いたコードがないと失敗し、あると成功するテストを書くこと。
  • 関連するドキュメント、実行例、ガイドなど、コードが影響する部分をすべて更新すること。

スタイルなどの表面的な変更や、Railsの安定性・機能・テストのしやすさについて根本部分が改善されない変更は受け付けられません。詳しくは#13771のコメント(英語)を参照してください。

5.5.1 Railsコーディングルールに従う

Railsのコーディングを行う場合は、以下のシンプルなスタイルガイドに従います。

  • インデントはスペース2個(タブ文字は使わない)。
  • 行末にスペースを置かないこと。空行に不要なスペースを置かないこと。
  • privateprotectedの直後の行は空行にせず、以降の行はインデントすること。
  • ハッシュの記法は Ruby 1.9 以降の書式を使うこと({ :a => :b }より{ a: :b }が望ましい)。
  • andorよりも&&||が望ましい。
  • クラスメソッドはself.methodよりもclass << selfが望ましい。
  • 引数はスペースなしの丸かっこmy_method(my_arg)で記述すること(丸かっこ+スペースmy_method( my_arg )や丸かっこなしmy_method my_argは使わない)。
  • =の前後にはスペースを置くこと(a=bではなくa = b)。
  • テストではrefuteではなくassert_notを使うこと。
  • 単一行ブロックはスペースなしmethod{do_stuff}よりもスペースありmethod { do_stuff }が望ましい。
  • その他、Railsのコードにある既存の書式に従うこと。

上はあくまでガイドラインであり、最適な方法については各自でご判断ください。

その他に、私たちのコーディング規約の一部をコード化するために定義されたRuboCopルールも用いています。プルリクエストを送信する前に、ローカルで変更したファイルで以下のようにRuboCopを実行してください。

$ bundle exec rubocop actionpack/lib/action_controller/metal/strong_parameters.rb
Inspecting 1 file
.

1 file inspected, no offenses detected

rails-ujsのCoffeeScriptやJavaScriptファイルについては、actionviewフォルダでnpm run lintを実行できます。

5.5.2 スペルチェック

Railsでは、GitHub Actionsmisspellを実行してスペルチェックを実施しています(misspellは主にGoで書かれています)。以下の要領でmisspellを実行して、よくあるスペルミスをその場で修正しておきましょう(misspellはカスタム辞書を使わない点が他のスペルチェッカーと異なります)。misspellは、ローカルであらゆるファイルに対して実行できます。

find . -type f | xargs ./misspell -i 'aircrafts, devels, invertions' -error

以下はmisspellで有用なオプションやフラグです。

  • -i 文字列: 修正したくない語のリストをカンマ区切りで渡す
  • -w: 修正をファイルに反映する(デフォルトは表示のみ)

また、GitHub Actionではcodespellも実行しています(codespellでは小さなカスタム辞書を用いています)。codespellはPythonで書かれており、以下のように実行できます。

codespell --ignore-words=codespell.txt

5.6 ベンチマークを実行する

パフォーマンスに影響する可能性のある変更では、コードのベンチマークを実施して影響の大きさを測定してください。その際、使ったベンチマークスクリプトも結果に添えてください。コミットメッセージにもその旨を明記し、今後別のコントリビューターが必要に応じてその結果をすぐ見つけて検証や決定を行えるようにしましょう(たとえば、今後Ruby VMの最適化が行われれば、現在の最適化の一部が不要になることも考えられます)。

特定のケースに限ってパフォーマンスを最適化すると、他の一般的なケースでパフォーマンスが低下することがよくあります。したがって、productionアプリケーションで実際に得られた代表的なケースをひととおり網羅したリストに対して変更をテストすべきです。

ベンチマーク用のテンプレートを元にベンチマークを作るとよいでしょう。このテンプレートには、benchmark-ips gemを用いてベンチマークを設定するコードテンプレートが含まれており、スクリプト内にインライン記述可能な、比較的自己完結的なテストを念頭に設計されています。

5.7 テストを実行する

Railsには、変更をプッシュするときにテストスイートをフル実行する規約はありません。特に、rails-dev-boxで推奨されているワークフーローを用いてソースコードを/vagrantにマウントすると、railtiesのテストに時間がかかります。

現実的な妥協案として、作成したコードによって影響が生じるかどうかをテストしましょう。railtiesで変更が発生していない場合は、影響を受けるコンポーネントのすべてのテストスイートを実行しましょう。すべてのテストがパスすれば、それだけで貢献を提案できます。Rails では、他の箇所で生じた予想外のエラーを検出するためにBuildkiteを利用しています。

5.7.1 Rails 全体のテストを実行する

すべてのテストを実行するには以下のようにします。

$ cd rails
$ bundle exec rake test
5.7.2 特定のコンポーネントのテストを実行する

Action Packなど、特定のコンポーネントのテストのみを実行することも可能です。たとえば、Action Mailerの場合は以下を実行します。

$ cd actionmailer
$ bin/test
5.7.3 特定のディレクトリのテストを実行する

特定のコンポーネントの特定のディレクトリ(例: Active Storageのmodelsディレクトリ)に対してのみテストを実行できます。たとえば、/activestorage/test/modelsディレクトリでテストを実行するには以下のようにします。

$ cd activestorage
$ bin/test models
5.7.4 特定ファイルのテストを実行する

以下のように特定のファイルを指定してテストを実行できます。

$ cd actionview
$ bin/test test/template/form_helper_test.rb
5.7.5 テストを1件だけ実行する

以下のように-nオプションでテスト名を指定すると、テストファイル内にある単一のテストを実行できます。

$ cd actionmailer
$ bin/test test/mail_layout_test.rb -n test_explicit_class_layout
5.7.6 seedを指定してテストを実行する

テストはseedによってランダムな順序で実行されます。ランダム化したテストが失敗する場合、seedを指定することで、失敗するテストをより正確に再現できます。

seedを指定して特定のコンポーネントのテストをすべて実行するには、以下のようにします。

$ cd actionmailer
$ SEED=15002 bin/test

seedを指定して特定のテストファイルを実行する場合は、以下のようにします。

$ cd actionmailer
$ SEED=15002 bin/test test/mail_layout_test.rb
5.7.7 テストの並列実行を止める

Action PackとAction Viewの単体テストは、デフォルトでは並列実行されます。ランダム化したテストが失敗する場合は、seedを指定したうえでPARALLEL_WORKERS=1を設定すると、単体テストが順に実行されるようになります。

$ cd actionview
$ PARALLEL_WORKERS=1 SEED=53708 bin/test test/template/test_case_test.rb
5.7.8 Active Recordをテストする

最初に、必要なデータベースを作成します。作成に必要なテーブル名、ユーザー名、パスワードはactiverecord/test/config.example.ymlにあります。

MySQLとPostgreSQLの場合は、以下のいずれかを実行するだけでデータベース作成が完了します。

$ cd activerecord
$ bundle exec rake db:mysql:build

または

$ cd activerecord
$ bundle exec rake db:postgresql:build

なおSQLite3ではデータベース作成は不要です。

SQLite3のみを対象にActive Recordのテストを実行する場合は、以下を行います。

$ cd activerecord
$ bundle exec rake test:sqlite3

MySQLやPostgreSQLを対象にテストを実行する場合は、sqlite3のときと同様に、それぞれ以下の手順でできます。

$ bundle exec rake test:mysql2
$ bundle exec rake test:postgresql

最後に以下を実行します。

$ bundle exec rake test

これで3つのデータベースについてテストが順に実行されます。

以下のように、単一のテストを個別に実行することもできます。

$ ARCONN=sqlite3 bundle exec ruby -Itest test/cases/associations/has_many_associations_test.rb

1つのテストをすべてのデータベースアダプタに対して実行するには以下のようにします。

$ bundle exec rake TEST=test/cases/associations/has_many_associations_test.rb

これでtest_jdbcmysqltest_jdbcsqlite3test_jdbcpostgresqlが順に呼び出されます。特定のデータベースを対象にテストを実行する方法について詳しくは、Railsリポジトリ内のactiverecord/RUNNING_UNIT_TESTS.rdocを参照してください。

5.8 警告の扱いについて

テストスイートの実行では、警告表示がオンになります。Ruby on Railsのテストで警告が1つも表示されないのが理想ですが、サードパーティのものも含めて若干の警告が表示される可能性があります。これらの警告は無視してください(でなければ修正しましょう)。可能であれば、新しい警告を表示しないようにするパッチの送信もお願いします。

5.9 ドキュメントの更新

RailsガイドはRailsの機能を大まかに解説するドキュメントであり、APIドキュメントは機能を具体的に解説するドキュメントです。

プルリクで新機能を追加する場合や、既存機能の振る舞いを変更する場合は、関連するドキュメントもチェックして適宜追加または更新してください。

たとえば、Active Storageの画像アナライザに新しいメタデータフィールドを追加する場合は、対応するActive StorageガイドのAnalyzing Filesセクションにも反映します。

5.10 CHANGELOGの更新

CHANGELOGファイルはすべてのリリースで重要な位置を占めます。Railsの各バージョンの変更内容はここに記録します。

機能の追加や削除、バグ修正のコミット、非推奨通知の追加を行ったら、必ず修正したフレームワークでCHANGELOGファイルのその時点の冒頭にエントリを追加してください。リファクタリングやドキュメント変更の場合はCHANGELOGを変更しないでください。

CHANGELOGのエントリには変更内容の適切な要約を記入し、最後に作者の名前を書きます。必要であれば複数行にわたってエントリを記入することも、スペース4つのインデントを置いたコード例を記入することもできます。変更が特定のissueに関連する場合は、issue番号も記入してください。CHANGELOGエントリの例を以下に示します(訳注: 実際は英語で書きます)。

*  (変更内容の要約をここに記入)

   (複数行のエントリを記入する場合は80文字目で折り返す)

   (必要に応じてコード例をスペースインデント4個で追加してもよい)
        class Foo
          def bar
            puts 'baz'
          end
        end

    (コード例の後にエントリの続きを書いてもよい)(issue番号は「Fixes #1234」などと書く)

    *自分の名前*

コード例や複数行エントリを使わない場合、名前はエントリの最後に続けて記入してエントリが1行に収まるようにします。その他の場合は、最後の行に名前だけを記入します。

5.11 エディタやIDEが作成するファイルをコミットに含めないようにする

エディタやIDEによっては、railsフォルダ内に独自の隠しファイルや隠しディレクトリを作成するものもあります。これらはコミットに含めないようにする必要がありますが、その場合は、コミットのたびに手動で取り除いたりRailsの.gitignoreに追加したりするのではなく、自分の環境のグローバルなgitignoreファイルに追加してください。

5.12 Gemfile.lockを更新する

変更内容によっては、gem依存関係のアップグレードも必要になることがあります。そのような場合は、bundle update を実行して正しい依存関係バージョンを反映し、変更のGemfile.lockファイルにコミットしてください。

5.13 変更をコミットする

自分のコードが問題なく動くようになったら、変更をローカルのGitにコミットします。

$ git commit -a

上を実行すると、コミットメッセージ作成用のエディタが開きます。メッセージの作成が終わったら、保存して次に進みます。

コミットメッセージを書くときは、書式を整えてわかりやすく記述すると、他の開発者が変更内容を理解するうえで大変助かります。十分時間をかけてコミットメッセージを書きましょう。

よいコミットメッセージは以下のような感じになります。

短い要約文(理想は50文字以下)

もちろん必要に応じて詳しく書いても構いません。
メッセージは72文字目で改行すること。
メッセージはできるだけ詳しく書くこと。
コミット内容が自明に思えても、他の人にとってそうとは限りません。
関連するissueで言及されている記述もすべて引用して、
履歴を探さなくても済むようにしましょう。

パラグラフを複数にすることも可能です。

コード例を記述に埋め込むときは、以下のようにスペース4個でインデントします。

    class ArticlesController
      def index
        render json: Article.limit(10)
      end
    end

箇条書きも追加できます。

- 箇条書きはダッシュ (-)かアスタリスク (*) で始めること

- 箇条書きの行は72文字目で折り返し、読みやすさのために
  追加行の冒頭にスペース2つを置いてインデントします

コミットが複数ある場合は、スカッシュ(squash)を実行して1個のコミットにまとめてください。そうすることで今後のcherry pickがやりやすくなり、Gitのログもシンプルになります。

5.14 ブランチを更新する

ローカルで作業している間に、リポジトリのmainブランチが更新されていることがよくあります。リポジトリのmainブランチの更新をローカルに取り込むには以下を実行します。

$ git checkout main
$ git pull --rebase

続いて、最新の変更のトップにパッチを再度適用します。

$ git checkout my_new_branch
$ git rebase main

「コンフリクトが生じていないか」「テストにパスしたか」「変更内容を十分吟味したか」を確認してから次に進みましょう。

5.15 fork

RailsのGitHubリポジトリをブラウザで開いて、右上隅の「Fork」をクリックします。

以下を実行して、ローカルPC上にあるローカルリポジトリに新しい"fork"リモートを追加します。

$ git remote add fork https://github.com/<自分のユーザー名>/rails.git

ローカルリポジトリは、オリジナルのrails/railsリポジトリからローカルリポジトリにcloneして作ることも、自分のリポジトリにforkしたものをローカルリポジトリにcloneして作ることも可能です。なお、以下のgitコマンドはオリジナルのrails/railsを指すrailsリモートを作成した場合を前提としています。

$ git remote add rails https://github.com/rails/rails.git

以下を実行して、Railsの公式リポジトリから新しいコミットとブランチをダウンロードします。

$ git fetch rails

以下を実行して、ダウンロードした新しいコンテンツを自分のブランチにマージします。

$ git checkout main
$ git rebase rails/main
$ git checkout my_new_branch
$ git rebase rails/main

以下を実行して、"fork"リモートを更新します。

$ git push fork main
$ git push fork my_new_branch

5.16 プルリクエストを発行する

プッシュしたRailsアプリケーションのリポジトリをブラウザで開いて(ここではhttps://github.com/自分のユーザー名/railsにリポジトリがあるとします)、画面上部の「Pull Requests」タブをクリックします。次のページで右上隅の「New pull request」ボタンをクリックします。

プルリクのベースリポジトリ(プルリク送信先)には、rails/railsとそのmainブランチを指定してください。 プルリクのヘッドリポジトリ(プルリク送信元)には、自分のリポジトリ(自分のユーザー名/railsなど)と、自分が作成したブランチ名を指定してください。 十分確認したら、「create pull request」ボタン をクリックします。

プルリクメッセージ画面が開いたら、まず自分が行った変更が過不足なく含まれていることを確認します。Rails用のプルリクメッセージテンプレートに沿って、送信したいパッチの詳細をプルリクメッセージに記入し、内容がひと目でわかるタイトルを付けます。以上の作業が終わったら「Send pull request」をクリックします。送信したプルリクエストはRailsコアチームに通知されます。

5.17 フィードバックを受け取る

ほとんどの場合、送信したプルリクエストがマージされるまでに何回か再挑戦することになるでしょう。あなたのプルリクエストに対して別の意見を持つコントリビュータがいるかもしれません。多くの場合、プルリクエストがマージされるまでにパッチを何度か更新する必要もあるでしょう。

GitHubのメール通知機能をオンにしているRailsコントリビュータもいますが、そうとは限りません。Railsに携わっている人のほとんどはボランティアなので、プルリクエストに返信をもらうまでに数日かかることもざらにあります。どうかめげずにプルリクエストをどしどし送信してください。おどろくほど早く反応がもらえることもあれば、そうでないこともあります。それがオープンソースというものです。

一週間経っても何の音沙汰もないようなら、rubyonrails-coreメーリングリストで少しつっついてみてもよいでしょう。プルリクエストに自分でコメントを追加してみてもよいでしょう。

よい機会なので、自分のプルリクエストへの反応を待っている間に、他の人のプルリクエストを開いてコメントを追加してみましょう。きっとその人たちも、あなたが自分のパッチに返信をもらったときと同じぐらい喜んでくれるでしょう。

なお、あなたのプルリクを「承認(approved)」してくれた人が実際にRailsへのマージ権限を持っているとは限りません。コアチームやコアコミッターが承認するまでに、さらに変更が必要になることもあるでしょう。混乱を避けるため、他の人のプルリクエストにコメントするときは「Approved」という言葉を使わないようお願いします。

5.18 必要なら何度でもトライする

「そのプルリクエストはここを変えた方がよいのではないか」といったフィードバックを受けることもあるでしょう。そういうことがあっても、どうか落ち込まないでください。オープンソースプロジェクトに貢献するうえで肝心なのは、遠慮せずにコミュニティの知恵を借りることです。コミュニティのメンバーがあなたのコードの調整を求めているのであれば、そのとおりにする価値は十分あります。仮に「そのコードはRailsのコアにおくべきではない」というフィードバックを受けたとしても、gemの形でリリースすることを検討する手もあります。

5.18.1 コミットをスカッシュする

あなたのコミットに対してスカッシュ(squash: 複数のコミットを1つにまとめること)を求められることもあります。プルリクエストは、1つのコミットにまとめておくことが望まれます。コミットを1つにまとめることで、新しい変更を安定版ブランチにバックポートしやすくなり、よくないコミットを取り消しやすくなり、Gitの履歴も多少追いやすくなります。Railsは巨大プロジェクトであり、不要なコミットが増えすぎると膨大なノイズが生じる可能性があります。

$ git fetch rails
$ git checkout my_new_branch
$ git rebase -i rails/main

< Choose 'squash' for all of your commits except the first one. >
< Edit the commit message to make sense, and describe all your changes. >

$ git push fork my_new_branch --force-with-lease

スカッシュしたコミットを用いてGitHub上のプルリクエストをリフレッシュすると、実際に更新されたことを確認できるようになります。

5.18.2 プルリクエストを更新する

あなたがコミットしたコードに対して後追いで変更を求められたり、場合によっては既存のコミットそのものの修正を求められることもあります。ただし、Gitでは既存のコミットをさかのぼって変更したものをプッシュすることは許されていません(既にプッシュされたブランチとローカルのブランチが一致しなくなるため)。このような場合は、新しいプルリクエストを作成する代わりに、上で説明したコミットのスカッシュを利用して、GitHub上の自分のブランチに強制的にプッシュする方法も考えられます。

$ git push fork my_new_branch --force-with-lease

これにより、GitHub上のブランチとプルリクエストが新しいコードで更新されます。強制プッシュするときに--force-with-leaseオプションを指定すると、通常の-fによる強制プッシュよりも安全にリモートを更新できまます。

5.19 旧バージョンのRuby on Rails

以前のバージョンのRuby on Railsに修正パッチを当てたい場合は、設定を行ってローカルのトラッキングブランチに切り替える必要があります。たとえば4-0-stableブランチに切り替える場合は以下のようにします。

$ git branch --track 4-0-stable rails/4-0-stable
$ git checkout 4-0-stable

シェルのプロンプトにGitブランチ名を表示すると、今どのバージョンで作業しているかがその場で確認できるので便利です。

旧バージョンのRailsで作業する前に、メンテナンスポリシーでサポート期限を確認してください。

5.19.1 バックポート

mainブランチにマージされた変更は、Railsの次期メジャーリリースに取り入れられます。場合によっては、メンテナンスのために過去の安定版にも変更をバックポートするのがよいこともあります。一般に、セキュリティ修正とバグ修正は、バックポートの候補になります。新機能や動作変更用パッチはバックポートの候補になりません。自分の変更がどちらに該当するかわからない場合は、不要な作業を避けるためにも、変更をバックポートする前にRailsチームのメンバーに相談しましょう。

単純な修正をバックポートする最も簡単な方法は、mainと自分の変更のdiffをとって対象ブランチに適用することです。

最初に、mainブランチと自分の変更のdiff以外に差分がないことを確認します。

$ git log main..HEAD

次にdiffを展開します。

$ git format-patch main --stdout > ~/my_changes.patch

対象ブランチに切り替えて変更を適用します。

$ git checkout -b my_backport_branch 4-2-stable
$ git apply ~/my_changes.patch

単純な変更であればこれで十分バックポートできます。しかし、変更内容が複雑な場合や、mainブランチと対象ブランチの差が大きくなっている場合は、追加の作業が必要になる可能性もあります。バックポートの難易度は場合によって大きく異なることもあれば、バックポートの労力に見合わないこともあります。

コンフリクトをすべて解消してすべてのテストがパスすることを確認できたら、変更をプッシュして、バックポート用のプルリクエストを別途作成します。 なお、古いブランチではビルドのターゲットがmainブランチと異なる可能性があるのでご注意ください。 できれば、対象となるブランチのrails.gemspecで許されているRubyバージョンのうち、最も古いRubyを用いてバックポートをローカルでテストしてからプルリクエストを送信するとよいでしょう。

解説は以上です。さて、次はどんな貢献をしましょうか。

6 Railsコントリビュータ

Railsに貢献したすべての開発者はRailsコントリビュータにクレジットが掲載されます。

フィードバックについて

Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。

原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨

本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。よろしくお願いします。

YassLab 株式会社
https://yasslab.jp/

支援・協賛

Railsガイドは下記のサポーターから継続的な支援を受けています。Railsガイドへの支援・協賛にご興味あれば info@yasslab.jp までお問い合わせください。

  1. Star
  2. このエントリーをはてなブックマークに追加