Discourse 플러그인에서 git 기반 gem 설치

우선 저는 Ruby on Rails와 Discourse 플러그인 개발에 완전한 초보이므로, 더 나은 방향이 있다면 알려주시면 감사하겠습니다.

개요

저는 내부 Discourse 플러그인 포크(discourse-ldap-auth)를 가지고 있으며, 이를 git 클론을 통해 가져오고 있습니다. 이 플러그인 포크는 Gem 포크(omniauth-ldap)를 필요로 하는데, 앱의 after_bundle_exec 훅에서 gem 문장에 내부 git URL을 추가하여 Gemfile을 통해 이를 가져오고 있습니다. 그러나 재빌드 중 더早些에 해당 gem이 성공적으로 설치된 것처럼 보임에도 불구하고, gem을 찾을 수 없어 앱이 시작되지 않습니다.

상세 내용

우리는 사용자가 기업 이메일로 가입하도록 요구해 온 장기간 운영되는 내부 Discourse 인스턴스를 보유하고 있습니다. 최근에는 다른 인트라넷 사이트와 동일한 로그인을 사용하기 위해 discourse-ldap-auth 플러그인을 추가했습니다. 이 구성은 작동하지만, 사용자에게 표시되는 프롬프트가 혼란스럽습니다. 대부분의 다른 인트라넷 사이트는 사용자 이름을 요구하지만, 우리의 Discourse 인스턴스는 기존 계정과 연결하기 위해 이메일 주소를 요구합니다. 저는 이메일 주소를 입력하도록 프롬프트를 표시하는 필드를 변경하고 싶습니다.

omniauth-ldap는 다른 Discourse 플러그인들과 달리 필드를 커스터마이징하는 기능이 없는 것으로 보이며, 폼 텍스트가 여기서 비롯되는 것 같습니다. 저는 이 부분(그리고 discourse-ldap-auth)을 내부적으로 포크하여 i18n.t 호출을 추가했습니다. 이제 필드가 지역적으로 특정되었으므로 필드를 커스터마이징할 수 있기를 희망합니다. 이 포크의 이름은 omniauth-ldap-i18n입니다. omniauth-ldap 포크를 Gemfile에 포함시키기 위해 app.yml에 다음과 같이 추가했습니다:

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'

discourse-ldap-auth 포크의 plugin.rb 내부:

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 파일에서 이 코드를 사용하면 항상 Rubygems에서 해당 지엄을 가져오려고 시도하며, 로컬에 설치된 버전을 사용하지 않습니다. 가능한 선택지는 다음과 같습니다:

  1. 커스터마이징한 지엄 버전을 rubygems에 푸시하고, >> Gemfile 해킹을 제거한 후 plugin.rb의 gem API를 사용하여 설치합니다.

  2. >> Gemfile 해킹을 제거하고, 사설 rubygems 서버를 설정한 후 다음과 같이 설치합니다:

    gem 'omniauth-ldap-i18n', '1.0.0', source: "https://mygemserver.example.com"
    
  3. 플러그인 지엄 로더에 Git 지원을 추가합니다. 기존 기능에 영향을 주지 않고 수행할 수 있다면, 이는 pr-welcome 대상이 됩니다.

  4. plugin.rb에서 gem 메서드 호출을 제거합니다. >> Gemfile 해킹이 있으므로, 지엄은 Discourse 내에서 자동으로 사용 가능해야 합니다. 하지만 이것이 해킹이라는 점을 강조하고 싶습니다. 핵심 파일들을 이 방식으로 오버라이드하는 것이 영원히 완벽하게 작동한다고 보장할 수 없습니다.

감사합니다! 아직 개발 중이므로, 제대로 동작하는지 확인할 때까지는 우선 비공개 rubygems 서버를 사용하겠습니다.

>> Gemfile 방식이 왜 해킹(hack)으로 여겨지는지 궁금합니다. templates/import/*.yml 파일 중 일부에서 추가 설정이 필요한 gems에 이 방식을 사용하고 있습니다. 이 방법은 이 같은 일반적인 구성에서는 사용이 금지된 건가요?

런타임에서 Gemfile을 수정하면 Gemfile.lock에도 항목이 추가되거나 변경됩니다. 이는 프로덕션에서 사용하는 의존성/버전이 Discourse를 테스트할 때 사용하는 것과 일치하지 않게 된다는 뜻입니다.

흥미롭네요. 그 사실을 몰랐습니다. ‘import’ 템플릿은 사이트 마이그레이션 중에 짧은 기간 동안만 사용되므로 위험성이 훨씬 낮을 것 같습니다. 그럼에도 불구하고, ‘production’ 템플릿에서는 이 기법을 사용하지 않는 것을 권장합니다. 다른 세 가지 옵션 중 어느 것을 사용하더라도 훨씬 깔끔합니다.

아, 한 가지 더: 코어의 Gemfile를 변경할 때마다 /admin/upgrade UI를 통한 업데이트가 >> Gemfile 트릭 때문에 깨질 것 같습니다. (로컬 변경 사항으로 인해 업데이트를 pull하려고 할 때 git 충돌이 발생합니다)