Rails 업그레이드 지침

우리는 최신 Rails 릴리스를 사용하여 GitLab을 실행하여 성능, 보안 업데이트 및 새로운 기능을 활용하고자 노력하고 있습니다.

Rails 업그레이드 접근 방식

  1. GitLab을 위한 MR 준비.
  2. Gitaly를 위한 MR 준비.
  3. 보안 패치용 패치 릴리스 및 백포트 작성.

GitLab을 위한 MR 준비

  1. Ruby on Rails 업그레이드 가이드를 확인하고 애플리케이션을 다가오는 변경 사항에 대비시킵니다.
  2. Gemfile에서 rails 젬 버전을 업데이트합니다.
  3. bundle update rails를 실행합니다.
  4. 업데이트 작업인 rake rails:update를 실행합니다.
  5. qa/Gemfile에서 activesupport 버전을 업데이트합니다.
  6. qa 폴더에서 bundle update --conservative activesupport를 실행합니다.
  7. Bundler 충돌을 해결합니다.
  8. @rails/ujs@rails/actioncable npm 패키지가 package.json에서 새로운 rails 버전과 일치하는지 확인합니다.
  9. 업데이트 후 로컬 패치 파일 버전이 일치하도록 yarn patch-package @rails/ujs를 실행합니다.
  10. pipeline:run-all-rspec 라벨이 있는 MR을 만들고 파이프라인이 실패하는지 확인합니다.
  11. git bisect를 사용하여 rails 리포지터리에 대한 특이점을 해결하고 디버깅합니다. 아래의 디버깅 섹션을 참조하세요.
  12. 두 버전 간의 젬 차이에 대한 링크를 Merge Request 설명에 포함합니다. 예를 들어, activesupport 6.1.3.2에서 6.1.4.1로의 젬 차이입니다.

Gitaly를 위한 MR 준비

  1. Gitaly Ruby의 Gemfile에서 activesupport 젬 버전을 업데이트합니다.
  2. bundle update --conservative activesupport를 실행합니다.
  3. Gitaly 프로젝트에 대한 MR을 이러한 변경 사항과 함께 만듭니다.
  4. 이 MR을 GitLab 프로젝트에서 만든 MR에 의존성을 둡니다.
  5. GitLab 프로젝트의 MR을 Merge한 이후에만 해당 MR을 Merge합니다.

보안 패치용 패치 릴리스 및 백포트 작성

만약 Rails 업그레이드가 패치 릴리스를 거쳐 중요한 보안 수정 사항을 포함한다면, 해당 내용은 Self-Managed형 고객에게 릴리스되어야 합니다. 진행 방법에 대해 릴리스 매니저와 협의하세요.

사용중지 로거

우리는 Ruby 및 Rails 사용중지 경고를 log/deprecation_json.log 파일에 로깅합니다. 이것은 테스트에서 충분히 커버되지 않은 코드가 있을 때 징후를 제공하며, 이때 DeprecationToolkitEnv를 우회하게 됩니다.

GitLab SaaS의 경우, GitLab 팀원은 Kibana(https://log.gprd.gitlab.net/goto/f7cebf1ff05038d901ba2c45925c7e01)에서 이러한 로그 이벤트를 검토할 수 있습니다.

Rails에 대한 Git bisect

일반적으로, 어떤 Rails 변경 사항이 스펙에 실패를 유발했는지 알고 있다면, 추가적인 컨텍스트를 제공하고, 해당 실패에 대한 해결책을 찾는 데 도움이 됩니다. Rails 변경 사항이 스펙 실패를 유발시킨 것을 효과적이고 빠르게 찾으려면 git bisect 명령을 사용할 수 있습니다.

  1. 선택한 폴더에 rails 프로젝트를 복제합니다. 예를 들어, GDK 루트 디렉터리일 수 있습니다:

    cd <GDK_FOLDER>
    git clone https://github.com/rails/rails.git
    
  2. GitLab의 Gemfile에서 gem 'rails' 줄을 다음과 같이 대체합니다:

    gem 'rails', ENV['RAILS_VERSION'], path: ENV['RAILS_FOLDER']
    
  3. RAILS_FOLDER 환경 변수를 RAILS_FOLDER를 클론한 폴더로 설정합니다:

    export RAILS_FOLDER="<GDK_FOLDER>/rails"
    
  4. 디렉터리를 RAILS_FOLDER로 변경하고 git bisect 명령에 대한 범위를 설정합니다:

    cd $RAILS_FOLDER
    git bisect start <NEW_VERSION_TAG> <OLD_VERSION_TAG>
    

    여기서 <NEW_VERSION_TAG>는 스펙이 실패한 태그이고, <OLD_VERSION_TAG>는 성공한 스펙이 있는 태그입니다. 예를 들어, 우리가 6.1.3.2 버전에서 6.1.4.1 버전으로 업그레이드하는 경우 git bisect start v6.1.4.1 v6.1.3.2로 대체합니다. 출력에서 어느 정도의 스텝이 걸리는지 확인할 수 있습니다.

  5. git bisect 프로세스를 시작하고 scripts/rails-update-bisect에 스펙 파일 이름을 인수로 전달합니다. 전체 스펙 파일 대신 하나의 예시만 선택하는 것이 빠를 수 있습니다.

    git bisect run <GDK_FOLDER>/gitlab/scripts/rails-update-bisect spec/models/ability_spec.rb
    # OR
    git bisect run <GDK_FOLDER>/gitlab/scripts/rails-update-bisect spec/models/ability_spec.rb:7
    
  6. 프로세스가 완료되면 git bisect는 커밋 해시를 출력하여 해당 커밋에 대응하는 해당 MR을 찾을 수 있습니다.
  7. git bisect reset를 실행하여 bisect 모드를 종료합니다.
  8. Gemfile의 변경 사항을 되돌립니다:

    git checkout -- Gemfile
    

후속 독서 자료