Rails 업그레이드 지침

우리는 최신 Rails 릴리스를 사용하여 GitLab을 운영하고 성능 및 보안 업데이트 및 새로운 기능을 활용하기 위해 노력합니다.

Rails 업그레이드 접근 방식

  1. GitLab을 위한 MR(Merge Request) 준비.
  2. Gitaly를 위한 MR(Merge Request) 준비.
  3. 보안 패치를 위한 패치 릴리스 및 백포트 생성.

GitLab을 위한 MR(Merge Request) 준비

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

Gitaly를 위한 MR(Merge Request) 준비

  1. Gitaly Ruby의 Gemfile에서 activesupport gem 버전을 업데이트합니다.
  2. bundle update --conservative activesupport를 실행합니다.
  3. 이 변경 사항으로 MR(Merge Request)를 Gitaly 프로젝트에 생성합니다.
  4. 이 MR을 GitLab 프로젝트에서 생성된 MR에 종속되도록 만듭니다.
  5. 이 MR은 GitLab 프로젝트의 MR을 병합한 이후에만 병합합니다.

보안 패치를 위한 패치 릴리스 및 백포트 생성

만약 Rails 업그레이드가 중요한 보안 패치를 포함하는 패치 릴리스에 해당되고 있다면, 자체 관리 고객에게 해당 패치를 GitLab 패치 릴리스로 배포해야 합니다. 진행 방법은 릴리스 매니저들과 협의하세요.

더 이상 사용되지 않는 Logger

우리는 또한 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 Gemfilegem 'rails' 줄을 다음과 같이 변경합니다:

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

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

    git checkout -- Gemfile
    

추가 독서 자료