Установка git-ориентированного гема из плагина Discourse

Прежде всего, я совсем новичок в Ruby on Rails и разработке плагинов для Discourse, поэтому буду признателен, если укажете более правильное направление.

Обзор

У меня есть форк внутреннего плагина Discourse (discourse-ldap-auth), который я подключаю через git clone. Этот форк плагина требует форк Gem-а (omniauth-ldap), который я добавляю через Gemfile, дописывая инструкцию gem с внутренним URL git в хуке after_bundle_exec приложения. Приложение не запускается во время пересборки, так как не может найти gem, хотя, судя по логу пересборки, gem устанавливается успешно на более раннем этапе.

Детали

У нас есть давно работающий внутренний экземпляр Discourse, где пользователям требовалось регистрироваться с помощью корпоративной почты. Недавно мы добавили плагин discourse-ldap-auth, чтобы использовать тот же вход, что и на других интранет-сайтах. Эта конфигурация работает, но подсказки для пользователей запутывают. На большинстве других интранет-сайтов требуется имя пользователя, но наш экземпляр Discourse требует адрес электронной почты для привязки к существующим учетным записям. Я хочу изменить поля ввода так, чтобы запрашивался адрес электронной почты.

Библиотека omniauth-ldap, откуда, похоже, берутся тексты формы, не поддерживает кастомизацию полей, как другие плагины Discourse. Я сделал внутренний форк этой библиотеки (и discourse-ldap-auth), чтобы добавить вызовы i18n.t, надеясь, что смогу кастомизировать поля, так как теперь они зависят от региона. Форк называется omniauth-ldap-i18n. Я добавил его в свой app.yml, чтобы подключить форк omniauth-ldap в Gemfile:

hooks:
  after_bundle_exec:
    - exec:
        cd: $home
        cmd:
          - echo "gem 'omniauth-ldap-i18n', git:'https://internal-git-service/omniauth-ldap-i18n.git'" >> Gemfile
          - su discourse -c 'bundle config unset deployment'
          - su discourse -c 'bundle install --no-deployment --path vendor/bundle --jobs 4 --without test development'

Внутри файла plugin.rb форка discourse-ldap-auth:

gem 'omniauth-ldap-i18n', '1.0.0'

Вывод при пересборке приложения:

Using omniauth-ldap-i18n 1.0.0 from https://internal-git-service/omniauth-ldap-i18n.git (at master@c3cb3ed)
Bundle complete! 127 Gemfile dependencies, 187 gems now installed.
Gems in the groups 'test' and 'development' were not installed.
Bundled gems are installed into `./vendor/bundle`

Вывод ошибки перед тем, как запуск завершается неудачей:

I, [2022-09-10T18:18:08.389538 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
ERROR:  Could not find a valid gem 'omniauth-ldap-i18n' (= 1.0.0) in any repository
ERROR:  Possible alternatives: omniauth-ldap-ifpe, omniauth-ldap, omniauth-ldap2, omniauth-aladin, omniauth-aliyun, omniauth-apihub, omniauth-learn, omniauth-lifen, omniauth-7digital, omniauth-aai
I, [2022-09-10T18:18:47.658658 #1]  INFO -- : gem install pyu-ruby-sasl -v 0.0.3.3 -i /var/www/discourse/plugins/discourse-ldap-auth/gems/2.7.6 --no-document --ignore-dependencies --no-user-install
Successfully installed pyu-ruby-sasl-0.0.3.3
1 gem installed
gem install rubyntlm -v 0.6.3 -i /var/www/discourse/plugins/discourse-ldap-auth/gems/2.7.6 --no-document --ignore-dependencies --no-user-install
Successfully installed rubyntlm-0.6.3
1 gem installed
gem install net-ldap -v 0.17.1 -i /var/www/discourse/plugins/discourse-ldap-auth/gems/2.7.6 --no-document --ignore-dependencies --no-user-install
Successfully installed net-ldap-0.17.1
1 gem installed
gem install omniauth-ldap-i18n -v 1.0.0 -i /var/www/discourse/plugins/discourse-ldap-auth/gems/2.7.6 --no-document --ignore-dependencies --no-user-install

You are specifying the gem omniauth-ldap-i18n in /var/www/discourse/plugins/discourse-ldap-auth/plugin.rb, however it does not exist!
Looked for: /var/www/discourse/plugins/discourse-ldap-auth/gems/2.7.6/specifications/omniauth-ldap-i18n-1.0.0.gemspec

Использование этого в файле plugin.rb всегда будет пытаться загрузить gem из Rubygems — локально установленная версия использоваться не будет. Думаю, у вас есть следующие варианты:

  1. Загрузите вашу кастомизированную версию gem в Rubygems, удалите взлом >> Gemfile и используйте API gem из plugin.rb для его установки.

  2. Удалите взлом >> Gemfile, настройте частный сервер Rubygems и установите следующим образом:

    gem 'omniauth-ldap-i18n', '1.0.0', source: "https://mygemserver.example.com"
    
  3. Добавьте поддержку Git в наш загрузчик плагинов-гемов. Если вы сможете сделать это, не затронув существующий функционал, это будет приветствоваться как #pr.

  4. Удалите вызов метода gem из plugin.rb. Поскольку у вас есть взлом >> Gemfile, gem должен автоматически стать доступным внутри Discourse. Однако я должен подчеркнуть, что это именно взлом — мы не можем гарантировать, что переопределение основных файлов таким образом будет работать безупречно вечно.

Спасибо! Поскольку это всё ещё находится в разработке, я начну с частного сервера RubyGems, пока не докажу, что это будет работать.

Меня интересует, почему метод >> Gemfile считается хаком. Он используется в нескольких файлах в templates/import/*.yml для гемов, требующих дополнительной настройки. Считается ли такой подход недопустимым для обычных конфигураций, подобных этой?

Когда вы изменяете Gemfile во время выполнения, это означает, что изменения также будут добавлены или внесены в Gemfile.lock. Это означает, что зависимости/версии, которые вы используете в продакшене, не совпадают с теми, против которых мы тестируем Discourse.

Интересно — я об этом не знал. Думаю, для шаблонов ‘import’ это гораздо менее рискованно, поскольку они используются лишь короткое время во время миграции сайта. Тем не менее, я всё же не рекомендую использовать этот метод в шаблоне ‘production’ — любой из трёх других вариантов был бы гораздо чище.

О, ещё один момент: я почти уверен, что трюк с >> Gemfile сломает обновления через интерфейс /admin/upgrade, когда мы будем менять Gemfile ядра. (Локальные изменения вызовут конфликт в Git при попытке получить обновление)