Installation eines git-basierten Gems aus einem Discourse-Plugin

Zunächst einmal bin ich brandneu bei Ruby on Rails und der Entwicklung von Discourse-Plugins. Wenn es also eine bessere Richtung gibt, wäre ich dankbar.

Übersicht

Ich habe eine interne Fork des Discourse-Plugins (discourse-ldap-auth), die ich über einen Git-Clone einbinde. Diese Plugin-Fork benötigt eine Gem-Fork (omniauth-ldap), die ich über die Gemfile einbinde, indem ich die gem-Anweisung mit einer internen Git-URL im Hook after_bundle_exec der App anhänge. Die App schlägt beim Wiederaufbau fehl, da sie die Gem nicht finden kann, obwohl die Gem früher im Wiederaufbau-Output erfolgreich installiert zu werden scheint.

Details

Wir haben eine langlaufende interne Discourse-Instanz, in der sich Benutzer mit ihrer Firmen-E-Mail-Adresse anmelden mussten. Wir haben kürzlich das discourse-ldap-auth-Plugin hinzugefügt, um die gleiche Anmeldung wie bei anderen Intranet-Seiten zu verwenden. Diese Konfiguration funktioniert, aber die Aufforderungen für Benutzer sind verwirrend. Die meisten anderen Intranet-Seiten verlangen einen Benutzernamen, aber unsere Discourse-Instanz verlangt eine E-Mail-Adresse, um sie mit vorhandenen Konten zu verknüpfen. Ich möchte die Felder ändern, um nach einer E-Mail-Adresse zu fragen.

omniauth-ldap, das anscheinend die Quelle für den Formulartext ist, unterstützt keine Anpassung von Feldern wie andere Discourse-Plugins. Ich habe dies (und discourse-ldap-auth) intern geforkt, um Aufrufe an i18n.t hinzuzufügen, in der Hoffnung, dass ich die Felder anpassen kann, da sie jetzt regionsspezifisch sind. Die Fork heißt omniauth-ldap-i18n. Ich habe dies zu meiner app.yml hinzugefügt, um die omniauth-ldap-Fork in die Gemfile zu bekommen:

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'

Innerhalb der Fork von discourse-ldap-auth’s plugin.rb:

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

Der Output beim Wiederaufbau der App:

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'

Der Fehler-Output, bevor er mit dem Start fehlschlägt:

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

Die Verwendung in der plugin.rb-Datei versucht immer, das Gem von Rubygems abzurufen – es wird nicht die lokal installierte Version verwendet. Ich denke, Ihre Optionen sind:

  1. Pushen Sie Ihre angepasste Version des Gems zu Rubygems, entfernen Sie den >> Gemfile-Hack und verwenden Sie die gem-API von plugin.rb, um es zu installieren.

  2. Entfernen Sie den >> Gemfile-Hack, richten Sie einen privaten Rubygems-Server ein und installieren Sie wie folgt:

    gem 'omniauth-ldap-i18n', '1.0.0', source: "https://mygemserver.example.com"
    
  3. Fügen Sie Git-Unterstützung zu unserem Plugin-Gem-Loader hinzu. Wenn Sie dies tun können, ohne die bestehende Funktionalität zu beeinträchtigen, wäre dies pr-welcome

  4. Entfernen Sie den gem-Methodenaufruf aus plugin.rb. Da Sie den >> Gemfile-Hack haben, sollte das Gem automatisch innerhalb von Discourse verfügbar sein. Aber ich möchte betonen, dass dies ein Hack ist – wir können nicht garantieren, dass das Überschreiben von Kern-Dateien auf diese Weise für immer perfekt funktioniert.

Vielen Dank! Da dies noch in der Entwicklung ist, werde ich mit dem privaten Rubygems-Server beginnen, bis ich beweisen kann, dass er funktioniert.

Ich bin neugierig, warum die >> Gemfile-Methode ein Hack ist. Sie wird in mehreren Dateien in templates/import/*.yml für Gems verwendet, die eine zusätzliche Einrichtung erfordern. Ist diese Vorgehensweise für reguläre Konfigurationen wie diese tabu?

Wenn Sie die Gemfile zur Laufzeit ändern, bedeutet dies, dass auch Dinge in der Gemfile.lock hinzugefügt/geändert werden. Das bedeutet, dass die Abhängigkeiten/Versionen, die Sie in der Produktion verwenden, nicht mit denen übereinstimmen, die wir bei Discourse testen.

Interessant – das war mir nicht bewusst. Ich nehme an, das Risiko ist für die ‘import’-Vorlagen viel geringer, da sie nur für kurze Zeit während einer Site-Migration verwendet werden. Dennoch würde ich die Verwendung dieser Technik in einer ‘production’-Vorlage nicht empfehlen – jede der anderen drei Optionen wäre sauberer.

Eine Sache noch: Ich bin ziemlich sicher, dass der Trick >> Gemfile Updates über die /admin/upgrade-Benutzeroberfläche unterbricht, sobald wir die Gemfile von Core ändern. (Die lokalen Änderungen verursachen einen Git-Konflikt, wenn versucht wird, das Update zu ziehen)