병합 가능성 프레임워크

초기 작업은 더 잘 정의된 병합 가능성 프레임워크로 시작되었습니다.

원래 병합 가능성 지식은 백엔드와 프론트엔드 전반에 퍼져 있었습니다.

이 작업은 일부 병합 가능성 기준을 백엔드의 같은 위치로 통합하는 것이었습니다.

이렇게 하면 프론트엔드가 API를 간단히 사용하고 오류를 표시할 수 있습니다.

새로운 체크 추가

새로운 병합 체크를 추가할 때 몇 가지 선택을 해야 합니다:

  • 이 체크는 건너뛸 수 있으며 체크가 성공할 경우 병합 기능의 일부입니까?
  • 이 체크는 캐시할 수 있습니까?
    • 그렇다면 적절한 캐시 키는 무엇입니까?
  • 이 체크를 켜거나 끌 수 있는 설정이 있습니까?

이 질문에 답하면 새로운 체크를 생성할 수 있습니다.

병합 가능성 체크는 app/services/merge_requests/mergeability/에 있습니다.

  1. 새로운 체크를 생성하려면 다음을 기본으로 사용할 수 있습니다:

    # frozen_string_literal: true
    module MergeRequests
      module Mergeability
        class CheckCiStatusService < CheckBaseService
           identifier :ci_must_pass # 실패한 체크를 나타내는 데 사용되는 식별자
           description 'Checks whether CI has passed' # GraphQL을 통해 반환되는 체크 설명
    
          def execute
            # 병합 체크가 설정 뒤에 있다면, 설정이 거짓이면 비활성으로 반환합니다
            return inactive unless merge_request.only_allow_merge_if_pipeline_succeeds?
    
            if merge_request.mergeable_ci_state?
              success
            else
              failure
            end
          end
    
          def skip?
            # 여기서 매개변수를 확인하거나 건너뛸 수 없으면 false를 반환할 수 있습니다
            # MR의 건너뛰기 가능성은 체크가 성공할 경우 병합 기능과 관련이 있습니다
            params[:skip_ci_check].present?
          end
    
          # 여기서 true를 반환하면, cache_key 메소드를 생성하고 적절한 캐시 키를 제공해야 합니다
          def cacheable?
            false
          end
        end
      end
    end
    
  2. def mergeable_state_checks 메소드에서 새로운 체크를 추가합니다.

  3. 새로운 체크를 GraphQL 열거형 app/graphql/types/merge_requests/detailed_merge_status_enum.rb에 추가합니다.

  4. bundle exec rake gitlab:graphql:compile_docs로 GraphQL 문서를 업데이트합니다.

  5. doc/api/merge_requests.md에서 API 문서를 업데이트합니다.

  6. 새로운 메시지를 지원하기 위해 프론트엔드를 업데이트합니다: app/assets/javascripts/vue_merge_request_widget/components/checks/message.vue.

고려사항

  1. 건너뛸 수 있어야 합니까? 병합 시 체크가 성공하는 작업의 일부인 경우, 건너뛸 수 있는 체크를 추가해야 합니다. 그렇지 않으면 false를 반환해야 합니다.

  2. 성능: 이러한 병합 가능성 체크는 매우 자주 실행되며, 따라서 성능이 큰 고려 사항입니다. 새로운 병합 가능성 체크의 성능을 점검하는 것이 중요합니다. 일반적으로 약 10-20 ms 정도의 성능을 기대하고 있습니다.

  3. 캐싱도 옵션입니다. def cacheable? 메소드를 true를 반환하도록 설정할 수 있으며, 이 경우에는 특정 체크에 대한 캐시 키를 설정하기 위해 def cache_key라는 또 다른 메소드를 생성해야 합니다. 캐시 무효화는 종종 까다로울 수 있으며, 캐시 키의 모든 엣지 케이스를 고려해야 합니다. 시간이 약 10-20 ms 내에서 유지된다면 캐시는 필요하지 않습니다.

  4. 체크 시간을 측정합니다. app/services/merge_requests/mergeability/logger.rb 클래스를 통해 각 체크의 시간을 측정하며, 이는 Kibana에서 볼 수 있습니다.

클래스의 작동 원리

  1. 병합 가능성 프레임워크를 호출하는 주요 메서드는 def mergeable?DetailedMergeStatusService입니다.
  2. 이 메서드들은 병합 가능성 체크를 반복하고 캐싱 및 계측을 처리하는 RunChecksService 클래스를 호출합니다.

체크가 통과될 때 병합

Merge When Checks Pass 기능에 체크를 추가하고 싶을 때, 우리는:

  1. 클래스에서 체크를 건너뛸 수 있도록 허용해야 합니다.
  2. 메서드 skipped_mergeable_checks의 목록에 매개변수를 추가해야 합니다.

향후 작업

  1. 현재 승인 체크의 느린 성능이 주요 문제입니다. 우리는 이 체크를 캐시 가능하게 만들기 위해 노력했지만, 언제 무효가 될지를 고려해야 하는 많은 엣지 케이스가 있습니다.