승인 규칙 개발 지침

이 문서는 병합 요청 승인 규칙에 대한 모든 관련 기능의 백엔드 설계 및 흐름을 설명합니다.

이는 기여자가 코드 설계를 더 쉽게 이해하고 기능 및 구현이 발전함에 따라 개선할 부분이 있는지 확인하는 데 도움이 될 것입니다.

구현 세부 정보는 자주 변경될 수 있으므로 의도적으로 너무 많은 구현 세부 정보를 포함하지 않았습니다. 코드가 이러한 사항을 더 잘 설명해야 합니다. 여기에서 언급된 구성 요소는 승인 규칙 기능이 작동하는 주요 애플리케이션 부분입니다.

참고:
이 문서는 살아있는 문서로, 이 문서에서 언급된 코드베이스의 일부가 변경되거나 제거되거나 새로운 구성 요소가 추가될 때마다 업데이트해야 합니다.

데이터 모델

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: 승인 규칙 데이터 모델 accDescr: 승인 규칙의 엔터티 관계 다이어그램 Project ||--o{ MergeRequest: " " Project ||--o{ ApprovalProjectRule: " " ApprovalProjectRule }o--o{ User: " " ApprovalProjectRule }o--o{ Group: " " ApprovalProjectRule }o--o{ ProtectedBranch: " " MergeRequest ||--|| ApprovalState: " " ApprovalState ||--o{ ApprovalWrappedRule: " " MergeRequest ||--o{ Approval: " " MergeRequest ||--o{ ApprovalMergeRequestRule: " " ApprovalMergeRequestRule }o--o{ User: " " ApprovalMergeRequestRule }o--o{ Group: " " ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "

ProjectMergeRequest

ProjectMergeRequest 모델은 ee/app/models/ee/project.rbee/app/models/ee/merge_request.rb에 정의되어 있습니다. 이들은 비-EE 버전을 확장하며, 승인 규칙은 EE 전용 기능입니다. 병합 요청 승인을 위한 연관 관계 및 기타 관련 사항이 여기에서 정의됩니다.

ApprovalState

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalState accDescr: 병합 요청과 승인 상태 간의 엔터티 관계 다이어그램 MergeRequest ||--|| ApprovalState: " "

ApprovalState 클래스는 ee/app/models/approval_state.rb에 정의되어 있습니다. 실제 ActiveRecord 모델이 아닙니다. 이 클래스는 특정 병합 요청에 대한 승인 상태와 관련된 모든 논리를 캡슐화합니다.

  • 해당 대상 브랜치를 기반으로 병합 요청에 적용할 수 있는 승인 규칙을 파악합니다.
  • 특정 대상 브랜치에 적용할 수 있는 승인 규칙을 파악합니다.
  • 모든 규칙이 승인되었는지 확인합니다.
  • 승인이 필요한지 확인합니다.
  • 승인된 수 또는 여전히 필요한 수를 파악합니다.

이 클래스는 프로젝트(ApprovalProjectRule) 또는 병합 요청(ApprovalMergeRequestRule)에서 승인 규칙 데이터를 가져와 ApprovalWrappedRule로 래핑합니다.

ApprovalProjectRule

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalProjectRule 다이어그램 accDescr: 프로젝트와 ApprovalProjectRule 간의 엔터티 관계 다이어그램 Project ||--o{ ApprovalProjectRule: " " ApprovalProjectRule }o--o{ User: " " ApprovalProjectRule }o--o{ Group: " " ApprovalProjectRule }o--o{ ProtectedBranch: " "

ApprovalProjectRule 모델은 ee/app/models/approval_project_rule.rb에 정의되어 있습니다.

승인 규칙이 프로젝트 설정을 통해 추가/편집/제거될 때 레코드가 생성/업데이트/삭제됩니다. 프로젝트 수준 승인 API를 통해 이루어집니다. 승인 규칙이 덮어쓰기 되지 않을 때 ApprovalState 모델은 이러한 레코드를 가져옵니다.

protected_branches 속성은 규칙이 보호된 브랜치에 범위가 설정될 때 설정되고 사용됩니다. 기능에 대한 자세한 내용은 보호된 브랜치에 대한 승인에서 확인하십시오.

ApprovalMergeRequestRule

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalMergeRequestRule 다이어그램 accDescr: MergeRequest와 ApprovalMergeRequestRule 간의 엔터티 관계 다이어그램 MergeRequest ||--o{ ApprovalMergeRequestRule: " " ApprovalMergeRequestRule }o--o{ User: " " ApprovalMergeRequestRule }o--o{ Group: " " ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "

ApprovalMergeRequestRule 모델은 ee/app/models/approval_merge_request_rule.rb에 정의되어 있습니다.

규칙이 병합 요청 생성/편집 양식을 통해 추가/편집/제거될 때 레코드가 생성/업데이트/삭제됩니다.

또는 merge request level approvals API를 사용하여 처리됩니다.

approval_project_rule은 기존 ApprovalProjectRule에서 파생되었을 때 설정됩니다.

ApprovalMergeRequestRuleprotected_branches를 가지지 않으며, 만약 재정의되지 않는다면 approval_project_rule에서 상속됩니다.

ApprovalWrappedRule

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalWrappedRule 다이어그램 accDescr: ApprovalState와 ApprovalWrappedRule 간의 엔터티 관계 다이어그램 ApprovalState ||--o{ ApprovalWrappedRule: " "

ApprovalWrappedRuleee/app/modes/approval_wrapped_rule.rb에 정의되어 있으며,

ActiveRecord 모델이 아닙니다. ApprovalProjectRule 또는 ApprovalMergeRequestRule을 래핑하여 공통 인터페이스에서 사용됩니다.

또한 다음과 같은 하위 유형이 있습니다:

  • ApprovalWrappedAnyApprovalRule - any_approver 규칙을 래핑하기 위해.
  • ApprovalWrappedCodeOwnerRule - code_owner 규칙을 래핑하기 위해.

이 클래스는 래핑된 승인 규칙에 대한 대부분의 책임을 위임하지만, 다음에 대한 책임도 있습니다:

  • 승인 규칙이 승인되었는지 확인하기.
  • 승인 규칙에 대해 얼마나 많은 승인이 주어졌는지 또는 여전히 필요한지 알기.

이 정보는 승인 규칙 및 병합 요청에서 Approval 레코드를 통해 얻습니다.

Approval

%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: Approval 다이어그램 accDescr: MergeRequest와 Approval 간의 엔터티 관계 다이어그램 MergeRequest ||--o{ Approval: " "

Approval 모델은 ee/app/models/approval.rb에 정의되어 있습니다. 이 모델은 병합 요청에서 이루어진 승인에 대한 정보를 저장하는 역할을 합니다.

승인이 주어지거나 취소될 때마다 레코드가 생성되거나 삭제됩니다.

컨트롤러와 서비스

다음 컨트롤러와 서비스는 승인 규칙 기능이 작동하는 데 사용됩니다.

API::ProjectApprovalSettings

이 비공식 API는 ee/lib/api/project_approval_settings.rb에 정의되어 있습니다.

다음 용도로 사용됩니다:

  • 프로젝트 설정에서 승인 규칙 나열하기.
  • 프로젝트 설정에서 규칙 생성/업데이트/삭제하기.
  • 병합 요청 생성 양식에서 승인 규칙 나열하기.

Projects::MergeRequests::CreationsController

이 컨트롤러는 app/controllers/projects/merge_requests/creations_controller.rb에 정의되어 있습니다.

이 컨트롤러의 create 작업은 병합 요청 생성 양식이 제출될 때 사용됩니다.

ApprovalMergeRequestRule 레코드를 생성/업데이트/삭제하기 위해 approval_rules_attributes 매개변수를 받습니다.

이 매개변수는 MergeRequests::CreateService를 실행할 때 함께 전달됩니다.

Projects::MergeRequestsController

이 컨트롤러는 app/controllers/projects/merge_requests_controller.rb에 정의되어 있습니다.

이 컨트롤러의 update 액션은 병합 요청(form) 수정 양식이 제출될 때 사용됩니다.

Projects::MergeRequests::CreationsController와 유사하지만, MergeRequests::UpdateService를 실행합니다.

API::MergeRequestApprovals

이 API는 ee/lib/api/merge_request_approvals.rb에 정의되어 있습니다.

병합 요청 페이지가 로드될 때 Approvals API 엔드포인트가 요청됩니다.

/projects/:id/merge_requests/:merge_request_iid/approval_settings는 다음을 위해 사용되는 비공식 API 엔드포인트입니다:

  • 병합 요청 수정 양식에서 승인 규칙 나열하기.
  • 병합 요청 페이지에서 승인 규칙 나열하기.

UI와 API를 통해 MR을 승인/비승인할 때, Approve Merge Request API 엔드포인트 또는 Unapprove Merge Request API 엔드포인트가 요청됩니다. 이들은 각각 MergeRequests::ApprovalServiceMergeRequests::RemoveApprovalService를 실행합니다.

API::ProjectApprovalRulesAPI::MergeRequestApprovalRules

이 APIs는 ee/lib/api/project_approval_rules.rbee/lib/api/merge_request_approval_rules.rb에 정의되어 있습니다.

병합 요청 승인 API를 통해 프로젝트 및 병합 요청 수준의 규칙을 나열/생성/수정/삭제하는 데 사용됩니다.

각각 ApprovalRules::CreateService, ApprovalRules::UpdateService, ApprovalRules::ProjectRuleDestroyService, 및 ApprovalRules::MergeRequestRuleDestroyService를 실행합니다.

ApprovalRules::ParamsFilteringService

이 서비스는 ee/app/services/approval_rules/params_filtering_service.rb에 정의되어 있습니다.

이 서비스는 MergeRequests::CreateServiceMergeRequests::UpdateService가 실행될 때만 호출됩니다.

approval_rules_attributes 파라미터를 구문 분석하는 역할을 합니다:

  • 사용자가 승인 규칙을 업데이트할 수 없는 경우 제거합니다.
  • 사용자 ID가 프로젝트의 구성원인지 여부를 필터링합니다.
  • 그룹 ID가 사용자에게 보이는지 여부를 필터링합니다.
  • any_approver 규칙을 식별합니다.
  • 지정할 경우 숨겨진 그룹을 추가합니다.
  • 병합 요청의 대상 브랜치에 적용되지 않는 사용자 정의 불가능한 승인 규칙을 추가합니다.

ApprovalRules::CreateService

이 서비스는 ee/app/services/approval_rules/create_service.rb에 정의되어 있습니다.

병합 요청 또는 프로젝트 수준에서 승인 규칙을 생성하는 역할을 합니다.

이 서비스는 다음과 같이 호출됩니다:

  • UI를 통해 프로젝트 수준에서 승인 규칙을 생성할 때.
  • API::ProjectApprovalRules /projects/:id/approval_rules 엔드포인트를 통해 프로젝트 수준에서 승인 규칙을 생성할 때.
  • API::MergeRequestApprovalRules /projects/:id/merge_requests/:merge_request_iid/approval_rules 엔드포인트를 통해 병합 요청 수준 규칙을 생성할 때.

UI를 통해 생성된 병합 요청 수준 규칙은 이 서비스를 사용하지 않습니다. Projects::MergeRequests::CreationsController를 참조하세요.

Flow

이 플로우차트는 컨트롤러에서 모델로의 다양한 기능 흐름을 설명하는 데 도움이 됩니다.

일부 CRUD API 엔드포인트는 꽤 직관적이기 때문에 의도적으로 생략되었습니다.

웹 UI를 통한 승인 규칙이 있는 병합 요청 생성

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: UI에서의 병합 요청 생성 accDescr: 승인 규칙이 포함된 병합 요청을 웹 UI에서 생성하는 과정 흐름도 Projects::MergeRequests::CreationsController --> MergeRequests::CreateService MergeRequests::CreateService --> ApprovalRules::ParamsFilteringService ApprovalRules::ParamsFilteringService --> MergeRequests::CreateService MergeRequests::CreateService --> MergeRequest MergeRequest --> db[(데이터베이스)] MergeRequest --> User MergeRequest --> Group MergeRequest --> ApprovalProjectRule User --> db[(데이터베이스)] Group --> db[(데이터베이스)] ApprovalProjectRule --> db[(데이터베이스)]

업데이트 시에는 같은 흐름이 유지되지만 Projects::MergeRequestsController에서 시작하여 MergeRequests::UpdateService를 실행합니다.

MR 페이지에서 병합 요청 승인 규칙 보기

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: 병합 요청에서 승인 규칙 보기 accDescr: 병합 요청 페이지에서 프론트엔드가 승인 규칙 정보를 조회한 후 표시하는 과정 흐름도 API::MergeRequestApprovals --> MergeRequest MergeRequest --> ApprovalState ApprovalState --> id1{승인 규칙이 재정의됨} id1{승인 규칙이 재정의됨} --> |아니오| ApprovalProjectRule & ApprovalMergeRequestRule id1{승인 규칙이 재정의됨} --> |네| ApprovalMergeRequestRule ApprovalState --> ApprovalWrappedRule ApprovalWrappedRule --> Approval

이 흐름은 프론트엔드 컴포넌트에 의해 시작됩니다. 반환된 데이터는 MR 위젯에 정보를 표시하는 데 사용됩니다.

병합 요청 승인하기

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: 승인 데이터 흐름도 accDescr: 승인 호출이 API를 통해 데이터베이스에 도달하는 과정을 나타내는 흐름도 API::MergeRequestApprovals --> MergeRequests::ApprovalService MergeRequests::ApprovalService --> Approval Approval --> db[(데이터베이스)]

비승인할 때는 같은 흐름이 유지되지만 MergeRequests::RemoveApprovalService가 대신 실행됩니다.

TODO

  1. code_ownerreport_approver와 같은 다른 규칙 유형과 관련된 정보를 추가합니다.

  2. 병합 요청을 승인/비승인할 때의 부작용에 대한 정보를 추가합니다.