승인 규칙 개발 가이드라인
GitLab v19.1이 문서는 머지 리퀘스트 승인 규칙과 관련된 모든 기능의 백엔드 설계 및 플로우를 설명합니다. 이 문서는 기여자들이 코드 설계를 더 쉽게 이해하고, 기능과 구현이 발전함에 따라 개선할 수 있는 부분을 파악하는 데 도움을 주기 위해 작성되었습니다.
이 문서는 머지 리퀘스트 승인 규칙과 관련된 모든 기능의 백엔드 설계 및 플로우를 설명합니다.
이 문서는 기여자들이 코드 설계를 더 쉽게 이해하고, 기능과 구현이 발전함에 따라 개선할 수 있는 부분을 파악하는 데 도움을 주기 위해 작성되었습니다.
구현 세부 사항이 너무 많이 포함되지 않도록 의도적으로 작성되었는데, 이는 세부 사항이 자주 변경될 수 있기 때문입니다. 코드 자체가 그런 내용을 더 잘 설명해 줍니다. 여기서 언급되는 컴포넌트들은 승인 규칙 기능이 동작하기 위한 애플리케이션의 주요 구성 요소입니다.
이 문서는 살아있는 문서로, 이 문서에서 다루는 코드베이스 부분이 변경되거나 제거되거나 새로운 컴포넌트가 추가될 때 그에 맞게 업데이트되어야 합니다.
데이터 모델#
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram accTitle: Approval rules data model accDescr: Entity relationship diagram of approval rules 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: " "
Project와 MergeRequest#
Project와 MergeRequest 모델은 ee/app/models/ee/project.rb와 ee/app/models/ee/merge_request.rb에 정의되어 있습니다. 승인 규칙이 EE 전용 기능이기 때문에 이 모델들은 EE가 아닌 버전을 확장합니다. 머지 리퀘스트 승인과 관련된 연관관계 및 기타 관련 내용이 여기에 정의되어 있습니다.
ApprovalState#
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram accTitle: ApprovalState accDescr: Entity relationship diagram between MergeRequest and ApprovalState MergeRequest ||--|| ApprovalState: " "
ApprovalState 클래스는 ee/app/models/approval_state.rb에 정의되어 있습니다. 이 클래스는 실제 ActiveRecord 모델이 아닙니다. 이 클래스는 특정 머지 리퀘스트에 대한 승인 상태와 관련된 모든 로직을 캡슐화합니다:
-
타깃 브랜치를 기반으로 머지 리퀘스트에 적용 가능한 승인 규칙 파악.
-
특정 타깃 브랜치에 적용 가능한 승인 규칙 파악.
-
모든 규칙이 승인되었는지 확인.
-
승인이 필요한지 확인.
-
부여된 승인 수 또는 아직 필요한 승인 수 파악.
프로젝트(ApprovalProjectRule) 또는 머지 리퀘스트(ApprovalMergeRequestRule)에서 승인 규칙 데이터를 가져와 ApprovalWrappedRule로 래핑합니다.
ApprovalProjectRule#
%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalProjectRule diagram accDescr: Entity relationship diagram between projects and 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 diagram accDescr: Entity relationship diagram between MergeRequest and ApprovalMergeRequestRule MergeRequest ||--o{ ApprovalMergeRequestRule: " " ApprovalMergeRequestRule }o--o{ User: " " ApprovalMergeRequestRule }o--o{ Group: " " ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "
ApprovalMergeRequestRule 모델은 ee/app/models/approval_merge_request_rule.rb에 정의되어 있습니다.
머지 리퀘스트 생성/편집 양식이나 단일 머지 리퀘스트 승인 API를 통해 규칙이 추가/편집/제거될 때 레코드가 생성/업데이트/삭제됩니다.
approval_project_rule은 기존 ApprovalProjectRule을 기반으로 할 때 설정됩니다.
ApprovalMergeRequestRule은 protected_branches를 직접 가지지 않으며, 덮어쓰이지 않은 경우 approval_project_rule에서 이를 상속받습니다.
ApprovalWrappedRule#
%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: ApprovalWrappedRule diagram accDescr: Entity relationship diagram between ApprovalState and ApprovalWrappedRule ApprovalState ||--o{ ApprovalWrappedRule: " "
ApprovalWrappedRule은 ee/app/modes/approval_wrapped_rule.rb에 정의되어 있으며 ActiveRecord 모델이 아닙니다. ApprovalProjectRule 또는 ApprovalMergeRequestRule을 공통 인터페이스로 래핑하는 데 사용됩니다. 또한 다음과 같은 하위 타입을 가지고 있습니다:
-
ApprovalWrappedAnyApprovalRule-any_approver규칙을 래핑하는 데 사용. -
ApprovalWrappedCodeOwnerRule-code_owner규칙을 래핑하는 데 사용.
이 클래스는 대부분의 책임을 래핑하는 승인 규칙에 위임하지만, 다음에 대한 책임도 가지고 있습니다:
-
승인 규칙이 승인되었는지 확인.
-
승인 규칙에 대해 부여된 승인 수 또는 아직 필요한 승인 수 파악.
이 정보는 승인 규칙과 머지 리퀘스트의 Approval 레코드로부터 가져옵니다.
Approval#
%%{init: { "fontFamily": "GitLab Sans" }}%% erDiagram accTitle: Approval diagram accDescr: Entity relationship diagram between MergeRequest and 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 액션은 머지 리퀘스트 편집 양식이 제출될 때 사용됩니다. Projects::MergeRequests::CreationsController와 유사하지만 MergeRequests::UpdateService를 실행한다는 점이 다릅니다.
API::MergeRequestApprovals#
이 API는 ee/lib/api/merge_request_approvals.rb에 정의되어 있습니다.
머지 리퀘스트 페이지가 로드될 때 승인 API 엔드포인트가 요청됩니다.
/projects/:id/merge_requests/:merge_request_iid/approval_settings는 다음 용도로 사용되는 비공개 API 엔드포인트입니다:
-
머지 리퀘스트 편집 양식에서 승인 규칙 목록 조회.
-
머지 리퀘스트 페이지에서 승인 규칙 목록 조회.
UI와 API를 통해 MR을 승인/취소할 때는 머지 리퀘스트 승인 API 엔드포인트나 머지 리퀘스트 승인 취소 API 엔드포인트가 요청됩니다. 각각 MergeRequests::ApprovalService와 MergeRequests::RemoveApprovalService를 실행합니다.
API::ProjectApprovalRules와 API::MergeRequestApprovalRules#
이 API들은 ee/lib/api/project_approval_rules.rb와 ee/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::CreateService와 MergeRequests::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를 참조하세요.
플로우#
다음 플로우차트는 다양한 기능에서 컨트롤러에서 모델로의 플로우를 설명합니다.
일부 CRUD API 엔드포인트는 매우 단순하기 때문에 의도적으로 생략되었습니다.
웹 UI를 통해 승인 규칙이 포함된 머지 리퀘스트 생성#
%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: Merge request creation in the UI accDescr: Flowchart of the creation of a merge request in the web UI, when the merge request contains approval rules Projects::MergeRequests::CreationsController --> MergeRequests::CreateService MergeRequests::CreateService --> ApprovalRules::ParamsFilteringService ApprovalRules::ParamsFilteringService --> MergeRequests::CreateService MergeRequests::CreateService --> MergeRequest MergeRequest --> db[(Database)] MergeRequest --> User MergeRequest --> Group MergeRequest --> ApprovalProjectRule User --> db[(Database)] Group --> db[(Database)] ApprovalProjectRule --> db[(Database)]
업데이트 시에는 동일한 플로우가 적용되지만 Projects::MergeRequestsController에서 시작하여 MergeRequests::UpdateService를 실행합니다.
MR 페이지에서 머지 리퀘스트 승인 규칙 보기#
%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: Viewing approval rules on a merge request accDescr: Flowchart of how the frontend retrieves, then displays, approval rule information on a merge request page API::MergeRequestApprovals --> MergeRequest MergeRequest --> ApprovalState ApprovalState --> id1{approval rules are overridden} id1{approval rules are overridden} --> |No| ApprovalProjectRule & ApprovalMergeRequestRule id1{approval rules are overridden} --> |Yes| ApprovalMergeRequestRule ApprovalState --> ApprovalWrappedRule ApprovalWrappedRule --> Approval
이 플로우는 프론트엔드 컴포넌트에 의해 시작됩니다. 반환된 데이터는 MR 위젯의 정보를 표시하는 데 사용됩니다.
머지 리퀘스트 승인#
%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR accTitle: Approval data flowchart accDescr: Flowchart of how an approval call to the API reaches the database API::MergeRequestApprovals --> MergeRequests::ApprovalService MergeRequests::ApprovalService --> Approval Approval --> db[(Database)]
승인 취소 시에는 동일한 플로우가 적용되지만 MergeRequests::RemoveApprovalService가 실행됩니다.
TODO#
-
code_owner및report_approver와 같은 다른 규칙 타입에 관한 정보 추가. -
머지 리퀘스트 승인/취소의 사이드 이펙트에 대한 정보 추가.