Вносим вклад в Ruby on Rails

Это руководство раскрывает, как ты можешь стать частью продолжающейся разработки Ruby on Rails.

После прочтения этого руководства, вы узнаете:

  • Как использовать GitHub для сообщения о проблемах.
  • Как клонировать main и запустить тестовый набор.
  • Как помочь в решении существующих проблем.
  • Как внести вклад в документацию Ruby on Rails.
  • Как внести вклад в код Ruby on Rails.

Ruby on Rails — это не "чей-то там фреймворк". На протяжение лет тысячи людей вносили вклад в Ruby on Rails, от одиночного символа до огромных архитектурных изменений или значимой документации — все, чтобы сделать Ruby on Rails лучше для каждого. Даже если пока не готовы писать код или документацию, имеется ряд других способов, которыми можно внести вклад, от сообщений о проблемах до тестирования новых изменений.

Как упомянуто в Rails README, от каждого, участвующего в коде Rails и его подпроектах, системах отслеживания ошибок, чатах, форумах и списках рассылок, ожидается следование нормам поведения Rails.


1. Сообщение о проблеме

Ruby on Rails использует GitHub Issue Tracking для отслеживания проблем (в основном, программных ошибок и нового кода). Если вы нашли программную ошибку в Ruby on Rails, нужно начать отсюда. Чтобы сообщить о проблеме, прокомментировать ее или создавать пул-реквесты, необходимо создать аккаунт (бесплатный) на GitHub.

Программным ошибкам в самой последней версии Ruby on Rails будет уделяться наибольшее внимание. Кроме этого, основная команда Rails всегда заинтересована в обратной связи от тех, у кого есть время протестировать edge Rails (код версии Rails, которая разрабатывается в текущий момент). Позже в этом руководстве будет рассказано, как получить edge Rails для тестирования. Смотрите в нашей политике поддержки информацию о том, какие версии поддерживаются. Никогда не сообщайте об ошибке безопасности в трекере проблем GitHub.

1.1. Создание отчета о программной ошибке

Если вы обнаружили проблему в Ruby on Rails, не несущую риск безопасности, поищите в Issues на Github, о ней уже может быть сообщено. Если вы не смогли найти какую-либо открытую проблему на GitHub, посвященную ошибке, которую вы нашли, вашим следующим действием будет открыть новую проблему. (Смотрите следующий раздел, посвященный вопросам безопасности.)

Мы предоставили шаблон проблемы, чтобы, когда вы создаете отчет о проблеме, вы включили всю необходимую информацию, чтобы определить, есть ли ошибка во фреймворке. Каждый отчет о проблеме должен содержать заголовок и ясное описание проблемы. Убедитесь, что включили как можно больше релевантной информации, включая пример кода или падающий тест, демонстрирующих ожидаемое поведение, а также вашу конфигурацию системы. Вашей целью должно быть упрощение для себя — и для других — в воспроизведении программной ошибки и понимании, как ее починить.

Как только вы открыли отчет о проблеме, там как может, так и нет какая-то активность сразу, если только это не какая-то критическая программная ошибка. Это не означает, что нам все равно на вашу ошибку, просто есть много проблем и пул-реквестов для работы. Другие люди со схожей проблемой могут обнаружить вашу проблему и подтвердить ошибку, и могут обсудить с вами, как ее починить. Если вы знаете, как починить ошибку, сделайте это и откройте пул-реквест.

1.2. Создание исполняемого тестового случая

Наличие способа воспроизвести вашу проблему поможет людям подтвердить, исследовать и, в конечном счете, починить вашу проблему. Это можно сделать с помощью исполняемого тестового случая. Чтобы упростить этот процесс, мы подготовили для вас несколько шаблонов отчетов об ошибке, которые можно использовать в качестве отправной точки:

  • Шаблон для проблем с Active Record (модели, база данных): ссылка
  • Шаблон для проблем с Active Record (миграции): ссылка
  • Шаблон для проблем с Action Pack (контроллеры, роутинг): ссылка
  • Шаблон для проблем с Action View (вью, хелперы): ссылка
  • Шаблон для проблем с Active Job: ссылка
  • Шаблон для проблем с Active Storage: ссылка
  • Шаблон для проблем с Action Mailer: ссылка
  • Шаблон для проблем с Action Mailbox: ссылка
  • Шаблон для других проблем: ссылка

Эти шаблоны включают шаблонный код для настройки тестового случая. Скопируйте содержимое подходящего шаблона в файл .rb и сделайте необходимые изменения, чтобы продемонстрировать проблему. Его можно запустить в терминале с помощью ruby the_file.rb. Если все получилось, вы должны увидеть, что ваш тестовый случай падает.

Затем можно поделиться своим исполняемым тестовым случаем через gist или вставить содержимое в описание issue.

1.3. Особая трактовка проблем безопасности

Пожалуйста, не сообщайте об уязвимостях в безопасности с помощью публичных отчетов о проблеме на GitHub. Страница о политике безопасности Rails подробно излагает процедуру для проблем безопасности.

1.4. Что насчет запросов о новой особенности?

Пожалуйста не складывайте "feature request" в GitHub Issues. Если имеется новая особенность, которую вы бы хотели видеть добавленной в Ruby on Rails, вам необходимо написать код самим, или убедить кого-то другого помочь вам с написанием кода. Позже в этом руководстве будут даны подробные инструкции по предложению патча в Ruby on Rails. Если вы опубликуете список пожеланий в GitHub Issues без кода, будьте уверены, он будет помечен "invalid", как только будет рассмотрен.

Иногда грань между 'программная ошибка' и 'особенность' трудно провести. Как правило, особенность — это все, что добавляет новое поведение, в то время как программная ошибка — это все, что вызывает неправильное поведение. Иногда команде Core приходиться делать очень непростой выбор. Тем не менее, различие, как правило, влияет лишь на то, с каким патчем ваше изменение будет выпущено; им нравится рассматривать особенности! Они просто не будут бэкпортировать в поддерживаемые ветки.

Если вы хотите получить обратную связь на идею особенности до того, как начнете работать над изменениями, начните обсуждение на форуме rails-core. Вы можете не получить откликов, что означает, что всем безразлично. Вы можете найти кого-то, кто так же заинтересован в создании этой особенности. Вы можете получить "This won't be accepted". Но это подходящее место для обсуждения новых идей. GitHub Issues являются не особо хорошим местом для проведения длительных и обширных обсуждений новых особенностей.

2. Помощь в разрешении существующих проблем

Кроме сообщения о проблемах, вы можете помочь основной команде разрешить существующие проблемы, предоставив обратную связь о них. Если вы новичок в разработке ядра Rails, предоставление обратной связи поможет вам познакомиться с кодовой базой и процессами.

Если посмотреть на список проблем в GitHub Issues, можно обнаружить множество проблем, требующих внимания прямо сейчас. Что можно с ними сделать? Фактически, немного:

2.1. Подтвердить сообщение о программной ошибке

Начинающие могут помочь только в подтверждении сообщений о программных ошибках. Сможете ли вы воспроизвести сообщенную проблему на своем компьютере? Если так, можете добавить комментарий к проблеме, что вы наблюдали то же самое.

Если проблема очень расплывчатая, сможете ли вы помочь сузить ее до чего-то конкретного? Может быть вы сможете предоставить дополнительную информацию для воспроизведения программной ошибки, или помочь в устранении ненужных шагов, не требуемых для демонстрации проблемы.

Если обнаружили сообщение о программной ошибке без теста, было бы полезным внести вклад, написав падающий тест. Это также отличный способ исследования исходного кода: глядя на существующие файлы тестов, научитесь как писать больше тестов. Новые тесты лучше всего вносить в виде изменений, как объяснено позже в разделе Вносим вклад в код Rails.

Все, что вы сможете сделать, чтобы отчеты о программной ошибке стали более краткими и более простыми для воспроизведения, поможет ребятам, пытающимся починить эти программные ошибки — независимо от того, дойдете вы до написания кода, или нет.

2.2. Протестировать изменения

Также можно помочь, изучая пул-реквесты, которые были отправлены в Ruby on Rails с помощью GitHub. Для того, чтобы применить чьи-то изменения, сначала создайте отдельную ветку:

$ git checkout -b testing_branch

Затем вы можете использовать их удаленную ветку для обновления кода в своей. Например, скажем, что на GitHub пользователь JohnSmith форкнул и запушил в ветку "orange", расположенную в https://github.com/JohnSmith/rails.

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

Альтернативой добавлению их удаленной ветки к своему контролю является использование инструмента GitHub CLI для контроля их пул-реквеста.

После применения их ветки, протестируйте ее! Вот несколько вещей, о которых стоит подумать:

  • Работает ли фактически это изменение?
  • Довольны ли вы тестами? Сможете ли вы выполнить то, что они тестируют? Нет ли отсутствующих тестов?
  • Имеется ли достаточное покрытие документацией? Должна ли быть обновлена документация где-то еще?
  • Нравится ли вам реализация? Можете подумать о более красивом или быстром способе реализации части его изменений?

Как только вы будете довольны тем, что пул-реквест содержит хорошее изменение, прокомментируйте на GitHub, обозначив свои выводы. Ваш комментарий должен показать, что вам нравится изменение, и что вы думаете о нем. Что-то вроде:

I like the way you've restructured that code in generate_finder_sql - much nicer. The tests look good too.

Если ваш комментарий просто содержит "+1", есть шанс, что прочие ревьюверы не воспримут его серьезно. Покажите, что вы потратили время на обзор этого пул-реквеста.

3. Вносим вклад в документацию Rails

В Ruby on Rails имеется два главных набора документации: руководства, помогающие изучить Ruby on Rails, и API, также служащее в качестве эталона.

Вы можете помочь в улучшении руководств по Rails или описания API, сделав их более последовательными или читаемыми, добавив отсутствующую информацию, исправив имеющиеся ошибки, скорректировав описки или обновив их в соответствие крайней версии Rails.

Для этого внесите изменения в исходные файлы руководств Rails (расположенные на GitHub) или комментарии RDoc в исходном коде. Затем откройте пул-реквест, чтобы применить изменения к ветке main.

Чтобы избежать запуска сборки CI для изменений в документации, используйте [ci skip] в заголовке вашего пул реквеста.

Как только вы откроете PR, для удобного просмотра и совместной работы будет развернута предварительная версия документации. В нижней части страницы Pull Request вы должны увидеть список проверок статуса. Найдите buildkite/docs-preview и нажмите "details".

GitHub rails/rails Pull Request status checks

Это приведет вас на страницу сборки Buildkite. Если задание выполнено успешно, над списком заданий появится аннотация со ссылками на сгенерированные разделы API и руководств.

Buildkite rails/docs-preview annotation API & Guides links

При работе с документацией принимайте во внимание Рекомендации по документированию API и Рекомендации для руководств по Ruby on Rails.

4. Перевод руководств Rails

Мы счастливы, что находятся волонтеры, переводящие руководства Rails, просто следуйте этим шагам:

  • Сделайте форк https://github.com/rails/rails.
  • Добавьте папку исходников для вашего языка, например: guides/source/it-IT для итальянского.
  • Скопируйте содержимое guides/source в директорию для вашего языка и переведите их.
  • НЕ переводите файлы HTML, так как они генерируются автоматически.

Обратите внимание, что переводы не передаются в репозиторий Rails. Как подробно описано выше, ваша работа находится в форке. Это происходит из-за того, что на практике изменения в документацию вносятся только для английского языка.

Чтобы сгенерировать руководства в формате HTML, нужно установить зависимости для руководств, cd в директорию guides и запустите (например, для it-IT):

# установить только гемы, необходимые для руководств. Чтобы отменить, запустите: bundle config --delete without
$ bundle install --without job cable storage test db
$ cd guides/
$ bundle exec rake guides:generate:html GUIDES_LANGUAGE=it-IT

Это сгенерирует руководства в директории output.

Гем Redcarpet не работает с JRuby.

5. Вносим вклад в код Rails

5.1. Настраиваем среду разработки

Чтобы продвинуться от подтверждения программных ошибок к помощи в разрешении существующих проблем или внесения собственного кода в Ruby on Rails, вы должны уметь запускать его тестовый набор. В этом разделе руководства вы изучите, как настроить тесты на своем компьютере.

5.1.1. Использование GitHub Codespaces

Если вы член организации со включенными codespaces, можно сделать форк Rails в организацию и использовать codespaces на GitHub. Codespace будут инициализированы со всеми требуемыми зависимостями и позволят запускать все тесты.

5.1.2. Использование удаленных контейнеров VS Code

Если у вас есть установленные Visual Studio Code и Docker, можно использовать плагин для удаленных контейнеров VS Code. Плагин прочитает конфигурацию .devcontainer в репозитории и построит контейнер Docker локально.

5.1.3. Использование Dev Container CLI

В качестве альтернативы, при наличии установленных Docker и npm, вы можете использовать Dev Container CLI для работы с конфигурацией .devcontainer из командной строки.

$ npm install -g @devcontainers/cli
$ cd rails
$ devcontainer up --workspace-folder .
$ devcontainer exec --workspace-folder . bash
5.1.4. Использование rails-dev-box

Также возможно использовать rails-dev-box, чтобы получить готовую среду разработки. Однако, rails-dev-box использует Vagrant и Virtual Box, которые не работают на Mac с Apple silicon.

5.1.5. Локальная разработка

Когда вы не можете использовать GitHub Codespaces, смотрите это другое руководство о том, как настроить локальную разработку. Это рассматривается как сложный способ, так как установка зависимостей может быть специфичной для операционной системы.

5.2. Клонирование репозитория Rails

Чтобы вносить изменения в код, необходимо клонировать репозиторий Rails:

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

и создать отдельную ветку:

$ cd rails
$ git checkout -b my_new_branch

Не имеет значения, какое имя вы используете, так как эта ветка существует только на вашем локальном компьютере и вашем персональном репозитории на GitHub. Она не будет частью гит-репозитория Rails.

5.3. Bundle install

Установите требуемые гемы.

$ bundle install

5.4. Запуск приложения на вашей локальной ветке

Если вам нужно приложение Rails для тестирования изменений, флажок --dev для rails new создаст приложение, использующее вашу локальную ветку:

$ 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. Пишите свой код

Теперь пришло время написать некоторый код! При осуществлении изменений в Rails, есть несколько вещей, которые нужно иметь в виду:

  • Следуйте стилю и соглашениям Rails.
  • Используйте идиомы и хелперы Rails.
  • Включайте тесты, которые падают без вашего кода, и проходят с ним.
  • Обновляйте документацию, примеры и руководства: все, что было затронуто вашим вкладом.
  • Если изменения добавляют, убирают или изменяют особенность, убедитесь, что включили запись CHANGELOG. Если ваше изменение исправляет ошибку, запись CHANGELOG не обязательна.

Косметические изменения, не добавляющие ничего ощутимого в стабильность, функциональность или тестируемость Rails, обычно не принимаются (читайте подробнее об обосновании этого решения).

5.5.1. Следуйте соглашениям по программированию

Rails следует простому набору соглашений о стиле кода:

  • Два пробела, нет табуляции (для отступов).
  • Нет конечных пробелов. Пустые строчки не должны иметь пробелов.
  • Отступ без пустой строчки после private/protected.
  • Используйте синтаксис Ruby >= 1.9 для хэшей. Предпочитайте { a: :b } над { :a => :b }.
  • Предпочитайте &&/|| над and/or.
  • Предпочитайте class << self над self.method для методов класса.
  • Используйте my_method(my_arg), а не my_method( my_arg ) или my_method my_arg.
  • Используйте a = b, а не a=b.
  • Используйте методы assert_not вместо refute.
  • Предпочитайте method { do_stuff } вместо method{do_stuff} для однострочных блоков.
  • Следуйте соглашениям в исходном коде, которые вы уже видели.

Что касается вышеприведенных рекомендаций - пожалуйста, поступайте по своему усмотрению при использовании их.

Помимо этого у нас имеются определенные правила RuboCop для систематизации некоторых из наших соглашений по кодированию. Вы можете запустить RuboCop локально для файла, который вы изменили, до отправки пул реквеста:

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

1 file inspected, no offenses detected

5.6. Тестируйте производительность своего кода

Для изменений, способных повлиять на производительность, пожалуйста, тестируйте производительность вашего кода и измеряйте влияние. Пожалуйста, покажите используемый. Следует рассмотреть включение этой информации в сообщении вашего коммита, чтобы позволить будущим контрибьюторам с легкостью проверить ваши выводы и определить, являются ли они по прежнему уместными. (Например, будущие оптимизации в виртуальной машине Ruby могут привести к ненужности определенных оптимизаций.)

При оптимизации для нужного вам определенного сценария легко ухудшить быстродействие для других распространенных случаев. Следовательно, необходимо тестировать ваше изменение на списке репрезентативных сценариев, в идеале извлеченных из реальных приложений.

В качестве отправной точки можно использовать шаблон теста производительности. Он включает шаблонный код для настройки теста с помощью гема benchmark-ips. Шаблон разработан для тестирования относительно самодостаточных изменений, которые можно встроить в скрипт.

5.7. Запуск тестов

В Rails не является необходимым запускать полный тестовый набор перед отправкой изменений. В частности, тестовый набор railties занимает много времени, и особенно долго, если исходный код монтирован в /vagrant, как происходит в рекомендованном рабочем процессе с помощью rails-dev-box.

В качестве компромисса, тестируйте то, на что ваш код явно влияет, и, если изменение не в railties, запускайте полный тестовый набор затронутого компонента. Если все тесты проходят, этого достаточно, чтобы предложить ваш вклад. У нас есть 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. Для определенной директории

Можно запускать тесты только для определенной директории определенного компонента (например, models в Active Storage). К примеру, для запуска тестов в /activestorage/test/models:

$ cd activestorage
$ bin/test models
5.7.4. Для определенного файла

Можно запустить тесты из определенного файла:

$ cd actionview
$ bin/test test/template/form_helper_test.rb
5.7.5. Запуск отдельного теста

Можно запустить отдельный тест по имени с помощью опции -n:

$ cd actionmailer
$ bin/test test/mail_layout_test.rb -n test_explicit_class_layout
5.7.6. Для конкретной строчки

Определить название теста не всегда просто, но если вы знаете номер строчки, с которой начинается ваш тест, этот вариант для вас:

$ cd railties
$ bin/test test/application/asset_debugging_test.rb:69
5.7.7. Запуск тестов с определенным порождающим элементом

Запуск тестов случайный с помощью порождающего элемента. Если вы испытываете случайные ошибки в тесте, можно более аккуратно воспроизвести сценарий падающего теста, установив порождающий элемент.

Запуск всех тестов для компонента:

$ cd actionmailer
$ SEED=15002 bin/test

Запуск отдельного тестового файла:

$ cd actionmailer
$ SEED=15002 bin/test test/mail_layout_test.rb
5.7.8. Запуск тестов последовательно

По умолчанию юнит-тесты Action Pack и Action View запускаются параллельно. Если вы испытываете случайные падающие тесты, можно установить порождающий элемент и позволить этим юнит-тестам запускаться последовательно, установив PARALLEL_WORKERS=1

$ cd actionview
$ PARALLEL_WORKERS=1 SEED=53708 bin/test test/template/test_case_test.rb
5.7.9. Тестирование 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 это необязательно.

Вот как можно запустить тестовый набор Active Record только для SQLite3:

$ cd activerecord
$ bundle exec rake test:sqlite3

Теперь вы можете запускать тесты, как вы делали для sqlite3. Соответствующие задачи:

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

Наконец,

$ bundle exec rake test

запустит все три по очереди.

Также можно запустить любой одиночный тест отдельно:

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

Чтобы запустить одиночный тест на всех адаптерах, используйте:

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

Также можно вызвать test_jdbcmysql, test_jdbcsqlite3 или test_jdbcpostgresql. Информацию по запуску нацеленных на базу данных тестов смотрите в файле activerecord/RUNNING_UNIT_TESTS.rdoc.

5.7.10. Использование отладчиков в тесте

Чтобы использовать внешний отладчик (pry, byebug и т.д.), установите отладчик и используйте его, как обычно. Если возникнут проблемы с отладчиком, запустите тесты последовательно, установив PARALLEL_WORKERS=1, или запустите отдельный тест с помощью -n test_long_test_name.

При запуске тестов для генераторов вам потребуется установить RAILS_LOG_TO_STDOUT=true для работы средств отладки.

RAILS_LOG_TO_STDOUT=true ./bin/test test/generators/actions_test.rb

5.8. Предупреждения

Тестовый набор запускается с включенными предупреждениями. В идеале, Ruby on Rails не должен выдавать предупреждения, но их может быть несколько, в том числе от сторонних библиотек. Пожалуйста, игнорируйте (или почините!) их, если имеются, и отправляйте изменения, не имеющих новых предупреждений.

Rails CI будет выдавать ошибку при появлении новых предупреждений. Чтобы добиться такого же поведения локально, установите RAILS_STRICT_WARNINGS=1 при запуске тестового набора.

5.9. Обновление документации

Руководства Ruby on Rails представляют высокоуровневый обзор особенностей Rails, в то время как документация API погружает в подробности.

Если ваш PR добавляет новую особенность или изменяет поведение существующую особенность, проверьте релевантную документацию, и обновите или добавьте к ней при необходимости.

Например, если вы изменяете анализатор изображений Active Storage, добавляя новое поле метаданных, следует обновить раздел Analyzing Files руководства по Active Storage, чтобы отразить это.

5.10. Обновление CHANGELOG

CHANGELOG — это важная часть каждого релиза. Он содержит список изменений для каждой версии Rails.

Вам следует добавить запись в самый верх CHANGELOG того фреймворка, который вы модифицировали, если вы добавили или убрали особенность, или добавили предупреждения об устаревании. Рефакторинг, исправление небольших программных ошибок и изменения документации обычно не идут в CHANGELOG.

Запись в CHANGELOG должна кратко описывать то, что было изменено, и заканчиваться именем автора. Можно использовать несколько строчек, если необходимо место, а также можно прикрепить примеры кода с отступом в 4 пробела. Если изменение относится к определенной проблеме, следует прикрепить номер проблемы. Вот пример записи в CHANGELOG:

*   Summary of a change that briefly describes what was changed. You can use multiple
    lines and wrap them at around 80 characters. Code examples are ok, too, if needed:

        class Foo
          def bar
            puts 'baz'
          end
        end

    You can continue after the code example and you can attach issue number.

    Fixes #1234.

    *Your Name*

5.11. Критические изменения

Любое изменение, которое может сломать существующие приложения, рассматривается как критическое изменение. Чтобы облегчить обновление приложений Rails, критические изменения требуют цикл устаревания.

5.11.1. Удаление поведения

Если ваше критическое изменение убирает существующее поведение, сперва нужно добавить предупреждение об устаревании, сохраняя существующее поведение.

В качестве примера допустим, что вы хотите убрать публичный метод из ActiveRecord::Base. Если ветка main указывает на невыпущенную версию 7.0, Rails 7.0 нужно показать предупреждение об устаревании. Это позволит убедиться, что каждый, обновляющийся на версию Rails 7.0, увидит предупреждение об устаревании. В Rails 7.1 метод можно удалить.

Можно добавить следующее предупреждение об устаревании:

def deprecated_method
  ActiveRecord.deprecator.warn(<<-MSG.squish)
    `ActiveRecord::Base.deprecated_method` is deprecated and will be removed in Rails 7.1.
  MSG
  # Существующее поведение
end
5.11.2. Изменение поведения

Если ваше критическое изменение изменяет существующее поведение, нужно добавить значение по умолчанию фреймворка. Значения по умолчанию фреймворка упрощают обновления Rails, позволяя приложениям переключиться на новые значения по умолчанию один за одним.

Чтобы реализовать новое значение по умолчанию фреймворка, сначала создайте конфигурацию, добавив метод акцессора в целевом фреймворке. Установите значение по умолчанию для существующего поведения, чтобы убедиться, что ничего не поломается в течение обновления.

module ActiveJob
  mattr_accessor :existing_behavior, default: true
end

Новая конфигурация позволяет условно реализовать новое поведение:

def changed_method
  if ActiveJob.existing_behavior
    # Существующее поведение
  else
    # Новое поведение
  end
end

Чтобы установить новое значение по умолчанию фреймворка, установите новое значение в Rails::Application::Configuration#load_defaults:

def load_defaults(target_version)
  case target_version.to_s
  when "7.1"
    # ...
    if respond_to?(:active_job)
      active_job.existing_behavior = false
    end
    # ...
  end
end

Чтобы упростить обновление, требуется добавить новое значение по умолчанию в шаблон new_framework_defaults. Добавьте закомментированный раздел, устанавливающее новое поведение:

# new_framework_defaults_7_2.rb.tt

# Rails.application.config.active_job.existing_behavior = false

И последним шагом добавьте новую конфигурацию в руководство по конфигурированию в configuration.md:

#### `config.active_job.existing_behavior

| Starting with version | The default value is |
| --------------------- | -------------------- |
| (original)            | `true`               |
| 7.1                   | `false`              |

5.12. Игнорирование файлов, создаваемых вашим редактором / IDE

Некоторые редакторы или IDE создадут скрытые файлы или папки внутри папки rails. Вместо ручного исключения их из каждого коммита или добавления их в .gitignore Rails, следует включить их в свой глобальный файл gitignore.

5.13. Апгрейд Gemfile.lock

Некоторые изменения требуют апгрейда зависимостей. В таких случаях убедитесь, что вы запустили bundle update, чтобы получить правильную версию зависимости и сделайте коммит с файлом Gemfile.lock со своими изменениями.

5.14. Коммит ваших изменений

Когда вы довольны своим кодом на своем компьютере, необходимо отправить коммит с изменениями в Git:

$ git commit -a

Это должно запустить ваш редактор, чтобы написать сообщение для этого коммита. После завершения, сохраните и закройте его, чтобы продолжить.

Хорошо отформатированное и содержательное сообщение коммита очень полезно для остальных для понимания, зачем было сделано изменение, поэтому найдите время написать его.

Хорошее сообщение коммита должно выглядеть так:

Краткое содержание (в идеале до 50 символов)

Более детальное описание, если необходимо. Каждая строка должна
переноситься по 72 символа. Попытайтесь быть как можно более наглядным.
Даже если вы думаете, что содержание коммита очевидно, оно может быть
неочевидным для остальных. Добавьте любое описание, уже присутствующее
в соответствующих описаниях проблем; должно быть необязательным
посещение веб-страницы чтобы посмотреть историю.

Раздел описания может иметь несколько параграфов.

Можно встраивать примеры кода, отступив их на 4 пробелами:

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

Можно добавить маркированные списки:

- создав пункт списка, начав строчку с черточки (-) или звездочки (*)

- перенося длинные строчки по 72 символа и отступая дополнительные
  строчки на 2 символа для читаемости

Пожалуйста, склеивайте свои коммиты в один коммит, когда это уместно. Это упрощает будущий черри-пикинг и поддерживает чистоту лога.

5.15. Обновление вашей ветки

Очень вероятно, что были сделаны другие изменения в main, пока вы работали. Получите новые изменения в main:

$ git checkout main
$ git pull --rebase

Теперь можно применить ваш патч на последних изменениях:

$ git checkout my_new_branch
$ git rebase main

Нет конфликтов? Тесты все еще проходят? Изменения еще актуальны? Затем отправьте изменения после ребейза на GitHub:

$ git push --force-with-lease

Мы не разрешаем принудительную отправку в основной репозиторий rails/rails, но вы можете принудительно отправлять в свой форк. После ребейза это требуется, так как история изменяется.

5.16. Форк

Перейдите в репозиторий Rails на GitHub и нажмите "Fork" в верхнем правом углу.

Добавьте новый удаленный репозиторий к вашему локальному:

$ git remote add fork https://github.com/<your username>/rails.git

Возможно, у вас есть клонированный форк-репозиторий, и вы хотите добавить удаленным оригинальный репозиторий Rails, в этом случае вот что вам нужно сделать.

В директории, в которую вы клонировали свой форк:

Вы можете клонировать свой локальный репозиторий от rails/rails, или можете клонировать свой форк-репозиторий. Следующие команды git предполагают, что вы сделали удаленный репозиторий "rails", указывающий на rails/rails.

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

Скачать новые коммиты и ветки из официального репозитория:

$ git fetch rails

Слить новое содержимое:

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

Обновить ваш форк:

$ git push fork main
$ git push fork my_new_branch

5.17. Публикация пул-реквеста

Перейдите в репозиторий Rails, в который вы только что отправили код (т.е. https://github.com/your-user-name/rails) и нажмите на "Pull Requests" в верхней панели (прямо над кодом). На следующей странице нажмите "New pull request" в верхнем правом углу.

Нажмите на "Edit", если необходимо изменить сравниваемые ветки (по умолчанию он сравнивает "main") и нажмите "Click to create a pull request for this comparison". Пул-реквест должен быть нацелен на базовый репозиторий rails/railsи ветку main. Головным репозиторием будет ваш рабочий (your-user-name/rails), а веткой будет то имя, которое вы дали своей ветке. Нажмите "create pull request", когда будете готовы.

Убедитесь, что включены изменения, которые вы представили. Заполните некоторыми подробностями о вашем потенциальном патче, используя предоставленный шаблон пул-реквеста. Когда закончите, нажмите "Create pull request".

5.18. Получение обратной связи

Большая часть пул-реквестов пройдут через ряд итераций до того, как они будут слиты. У разных контрибьюторов иногда разные мнения, и часто изменения нуждаются в пересмотре до того, как их можно слить.

У некоторых контрибьюторов в Rails включены уведомления по email с GitHub, у некоторых нет. Более того, (почти) все, кто работает над Rails, являются добровольцами, поэтому может пройти несколько дней до того, как вы получите первую обратную связь на пул-реквест. Не отчаивайтесь! Иногда это быстро, иногда это медленно. Такова жизнь открытого ПО.

Если прошло больше недели, и никто не ответил, можно попытаться немного ускорить процесс. Для этого используйте канал contributions на сервере Ruby on Rails Discord или форум rubyonrails-core. Также можно оставить комментарий в своем пул-реквесте.

ПОка вы ждете обратную связь на свой пул-реквест, откройте несколько чужих пул-реквестов и дайте обратную связь кому-то еще! Они будут признательны за это не меньше, чем вы были бы признательны за обратную связь на ваши изменения.

Отметьте, что только командам Core и Committers разрешено мержить изменения кода. Если кто-то даст обратную связь и "одобрит" ваши изменения, у них нет возможности или последнего слова для мержа вашего изменения.

5.19. Повторение по необходимости

Очень вероятно, что полученная обратная связь предложит изменения. Не отчаивайтесь: весь смысл вклада в активный проект с открытым кодом заключается в том, чтобы использовать знания сообщества. Если люди призывают подправить ваш код, то стоит внести правки и отправить заново. Если обратная связь говорит, что ваш код не будет смержен, вы можете подумать о выпуске его в качестве гема.

5.19.1. Склеивание коммитов

Одной из вещей, которая может быть попрошена, является "squash your commits", которая объединит все ваши коммиты в один. Мы предпочитаем пул-реквесты с одним коммитом. Это упрощает бэкпортирование в стабильные ветки, склеивание (squashing) позволяет легко откатывать плохие коммиты, слежение за историей git. Rails — это большой проект, и ряд множество сторонних коммитов может добавить много шума.

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

< Выберите 'squash' для всех ваших коммитов, кроме первого. >
< Отредактируйте сообщение коммита, чтобы оно было осмысленным, и опишите все свои изменения. >

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

Далее вам необходимо обновить пул-реквест на GitHub и посмотреть, что он был изменен.

5.19.2. Обновление пул-реквеста

Иногда вас попросят внести некоторые изменения в код, который уже был закоммичен. Это может включать исправление существующих коммитов. В этом случае Git не позволит отправить изменения, так как удаленная и локальная ветки не соответствуют друг другу. Вместо открытия нового пул-реквеста, можно принудить отправку в вашу ветку на GitHub, как описано ранее в разделе про склеивание коммитов:

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

Это позволит обновить ветку и пул-реквест на GitHub вашим новым кодом. Принудительно отправив с помощью --force-with-lease, git более безопасно обновит удаленный репозиторий, чем с помощью обычного -f, который может стереть работу с удаленного репозитория, которой у вас уже нет.

5.20. Старшие версии Ruby on Rails

Если вы хотите добавить исправление в версии Ruby on Rails, старше чем следующий релиз, необходимо настроить и переключить свою локальную отслеживаемую ветку. Вот пример, как переключиться на ветку 7-0-stable:

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

Перед работой над старшими версиями, проверьте политику поддержки. Изменения не будут приняты в версии, которые достигли конец поддержки.

5.20.1. Бэкпортирование

Изменения, слитые в main, предназначены для следующего главного релиза Rails. Иногда полезно, распространить ваши изменения на поддерживаемые релизы для стабильных веток. Как правило, хорошими кандидатами для бэкпортирования являются исправления безопасности и исправления программных ошибок, в то время как новые особенности и исправления, изменяющие поведение, не будут приняты. Когда сомневаетесь, лучше всего проконсультироваться с членом основной команды Rails до бэкпортирования ваших изменений, чтобы избежать потери времени.

Сначала убедитесь, что ваша ветка main актуальна:

$ git checkout main
$ git pull --rebase

Перейдите в ветку, которую вы бэкпортируете, например, 7-0-stable, и убедитесь, что она актуальна:

$ git checkout 7-0-stable
$ git reset --hard origin/7-0-stable
$ git checkout -b my-backport-branch

Если вы бэкпортируете смерженный пул-реквест, найдите коммит для мержа, и вытащите его:

$ git cherry-pick -m1 MERGE_SHA

Почините все конфликты, случающиеся при вытаскивании, отправьте ваши изменения, затем откройте PR, указывающий на стабильную ветку, в которую вы бэкпортируете. Если у вас более сложный набор изменений, документация по cherry-pick может помочь.

6. Авторы Rails

Все внесшие вклад восхваляются в Rails Contributors.