"Настройка __ не существует" при попытке запуска спецификаций для плагина poll

Привет,

Я создаю плагин и пытаюсь написать тесты, но при попытке запустить спецификации плагина poll через

bundle exec rake plugin:spec poll

как показано здесь, получаю эту ошибку:

Произошла ошибка при загрузке ./plugins/poll/spec/integration/poll_endpoints_spec.rb.
Failure/Error: raise ArgumentError.new(“No setting named ‘#{name}’ exists”)

ArgumentError:
  No setting named 'discourse_narrative_bot_enabled' exists
# ./lib/site_settings/defaults_provider.rb:58:in `set_regardless_of_locale'
# ./config/environments/test.rb:74:in `block (3 levels) in <main>'
# ./config/environments/test.rb:63:in `tap'
# ./config/environments/test.rb:63:in `block (2 levels) in <main>'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:68:in `block in execute_hook'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:61:in `with_execution_control'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:66:in `execute_hook'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:51:in `each'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/activesupport-6.1.3.2/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/application/finisher.rb:140:in `block in <module:Finisher>'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:32:in `instance_exec'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:32:in `run'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:61:in `block in run_initializers'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/initializable.rb:60:in `run_initializers'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/application.rb:384:in `initialize!'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/railtie.rb:207:in `public_send'
# /Users/myUser/.rvm/gems/ruby-2.7.0/gems/railties-6.1.3.2/lib/rails/railtie.rb:207:in `method_missing'
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:56:in `require'
# ./spec/rails_helper.rb:56:in `<top (required)>'
# ./plugins/poll/spec/integration/poll_endpoints_spec.rb:3:in `require'
# ./plugins/poll/spec/integration/poll_endpoints_spec.rb:3:in `<top (required)>'

Что я делаю не так при запуске тестов плагина poll? Почему именно эта настройка не загружается в локаль по умолчанию?

Спасибо.

Чтобы запустить только тесты для плагина poll, используйте команду: bundle exec rake "plugin:spec[poll]" (или более короткую: bin/rake "plugin:spec[poll]"), иначе будут выполнены тесты всех плагинов.

Что касается возникающей у вас ошибки, я не уверен. Мигрирована ли тестовая база данных? (bin/rails db:migrate RAILS_ENV=test)

Спасибо. Как вы и сказали, все спецификации плагинов действительно запустились, и я обошёл это, убрав другие плагины. Я ориентировался на этот пост, но оказалось, что скобки стояли не на своём месте.

Да, база данных мигрирована в тестовой среде. Я обошёл эту ошибку, закомментировав строку raise ArgumentError.new("No setting named '#{name}' exists") и заменив её на puts. Это показало, что только discourse_narrative_bot_enabled вызывает эту ошибку; все остальные настройки в порядке. Насколько я помню, мы ничего не делали с этим параметром. В любом случае, так как мои спецификации запустились корректно при игнорировании этой ошибки, я могу оставить этот обходной путь в своей локальной версии Discourse. Как только я выясню, что именно вызвало это, я обновлю этот пост.

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

Run bin/rake db:create
rake aborted!
ArgumentError: No setting named 'discourse_narrative_bot_enabled' exists
/home/runner/work/discourse-multilingual/discourse-multilingual/lib/site_settings/defaults_provider.rb:58:in `set_regardless_of_locale'
/home/runner/work/discourse-multilingual/discourse-multilingual/config/environments/test.rb:73:in `block (3 levels) in <main>'
/home/runner/work/discourse-multilingual/discourse-multilingual/config/environments/test.rb:63:in `tap'
/home/runner/work/discourse-multilingual/discourse-multilingual/config/environments/test.rb:63:in `block (2 levels) in <main>'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:79:in `block in execute_hook'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:72:in `with_execution_control'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:77:in `execute_hook'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:63:in `block in run_load_hooks'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:62:in `each'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/activesupport-7.0.3.1/lib/active_support/lazy_load_hooks.rb:62:in `run_load_hooks'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/application/finisher.rb:87:in `block in <module:Finisher>'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:32:in `instance_exec'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:32:in `run'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:61:in `block in run_initializers'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/initializable.rb:60:in `run_initializers'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/application.rb:372:in `initialize!'
/home/runner/work/discourse-multilingual/discourse-multilingual/config/environment.rb:7:in `<main>'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.6.0/lib/zeitwerk/kernel.rb:35:in `require'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/application.rb:348:in `require_environment!'
/home/runner/work/discourse-multilingual/discourse-multilingual/vendor/bundle/ruby/2.7.0/gems/railties-7.0.3.1/lib/rails/application.rb:511:in `block in run_tasks_blocks'
Tasks: TOP => db:migrate => db:load_config => environment
(See full trace by running task with --trace)
Error: Process completed with exit code 1.

Похоже, причина в этой строке в ядре:

Коллеги, это меня просто убивает.

Наш CI Our CI падает на этапе db:migrate из-за этого.

Он почти дословно копирует CI для плагина discourse-chat, но с добавлением расписания cron.

Наш CI работает для PR и коммитов, но при запуске по cron-заданию он каждый раз падает именно здесь.

Я смог воспроизвести это в консоли Rails похожим блоком:

[19] pry(main)> SiteSetting.defaults.tap do |s|
[19] pry(main)*   s.set_regardless_of_locale(:discourse_narrative_bot_enab, false)
[19] pry(main)* end
ArgumentError: No setting named 'discourse_narrative_bot_enab' exists

Это работает, если я добавлю:

[21] pry(main)> SiteSetting.defaults.tap do |s|
[21] pry(main)*   if s.has_setting? :discourse_narrative_bot_enab
[21] pry(main)*     s.set_regardless_of_locale(:discourse_narrative_bot_enab, false)
[21] pry(main)*   end
[21] pry(main)* end

И для проверки, это падает с:

[21] pry(main)> SiteSetting.defaults.tap do |s|
[21] pry(main)*   if s.has_setting? :discourse_narrative_bot_enabled
[21] pry(main)*     s.set_regardless_of_locale(:discourse_narrative_bot_enab, false)
[21] pry(main)*   end
[21] pry(main)* end

Поэтому я предлагаю следующее изменение в PR, который я с радостью отправлю:

 if ENV['LOAD_PLUGINS'] == '1' && s.has_setting? :discourse_narrative_bot_enabled

Непонятно, почему наличие плагина Narrative Bot не может быть гарантировано?

В этих примерах настройка сайта указана как discourse_narrative_bot_enab, а не discourse_narrative_bot_enabled. Я предполагаю, что после исправления это перестанет воспроизводиться?

Самое удивительное здесь:

Это указывает на различие в среде выполнения для запланированных запусков :thinking:

Просматривая один из логов с ошибкой, видно, что GitHub клонирует плагин multilingual напрямую в директорию plugins, а не в собственную директорию. Таким образом, он фактически «удаляет» все основные плагины (и не может корректно установить себя).

Я предполагаю, что для работы cron нам нужно заменить все вхождения github.event.repository.name на что-то другое:

https://github.com/paviliondev/discourse-multilingual/blob/main/.github/workflows/plugin-tests.yml#L40

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

cc @cvx — возможно, нам стоит использовать этот прием в CI для шаблонов плагинов/тем?

Это было сделано намеренно, чтобы вызвать ошибку (и обработать её).

О, боже, отличная находка, спасибо!

Объединено, большое спасибо @David, это было очень любезно с вашей стороны.

Если я когда-нибудь окажусь в вашем районе, обязательно угощу вас :beers:! :slight_smile:

К вашему сведению, тесты cron прошли успешно. Еще раз спасибо. :tada:

@cvx только что поделился со мной этой статьёй:

Так что обходной путь с именем репозитория больше не должен быть нужен для задач cron :tada: cc @merefield