코드 소유자 개발 가이드

이 문서는 Code Owners의 코드 디자인을 이해하는 데 도움을 주기 위해 작성되었습니다. 이 기능의 코드를 변경하기 전에 이 문서를 읽어야 합니다.

이 문서는 코드가 자주 변경될 수 있기 때문에 코드가 어떻게 동작하는지에 대한 개요로 의도적으로 제한되어 있습니다. 특정 부분이 어떻게 동작하는지 이해하려면 코드와 스펙을 확인해야 합니다. 여기서의 세부 내용은 Code Owners 기능의 주요 컴포넌트가 어떻게 동작하는지 설명합니다.

note
이 문서는 이 문서에서 참조된 코드베이스의 일부가 업데이트되거나 제거되거나 새 부분이 추가될 때에 업데이트되어야 합니다.

비즈니스 로직

코드 소유자의 모든 비즈니스 로직은 Gitlab::CodeOwners 네임스페이스에 위치합니다. Code Owners는 EE 전용 기능이므로 파일은 ./ee 디렉터리에만 있습니다.

  • Gitlab::CodeOwners: 코드 소유자 규칙과 상호 작용하는 데 사용되는 주요 모듈입니다.
    • ./ee/lib/gitlab/code_owners.rb에 정의되어 있음.
  • Gitlab::CodeOwners::File: CODEOWNERS 파일을 래핑하고 클래스의 공개 메서드를 통해 데이터를 노출합니다.
    • ./ee/lib/gitlab/code_owners/file.rb에 정의되어 있음.
  • Gitlab::CodeOwners::Section: CODEOWNERS 파일에서 섹션 제목을 래핑하고 다른 부분을 구문 분석합니다.
    • ./ee/lib/gitlab/code_owners/section.rb에 정의되어 있음.
  • Gitlab::CodeOwners::Entry: CODEOWNERS 파일에서 항목 (패턴 및 소유자 라인)을 래핑하고 클래스의 공개 메서드를 통해 데이터를 노출합니다.
    • ./ee/lib/gitlab/code_owners/entry.rb에 정의되어 있음.
  • Gitlab::CodeOwners::Loader: 올바른 CODEOWNER 파일을 찾아 내용을 Gitlab::CodeOwners::File 인스턴스로 로드합니다.
    • ./ee/lib/gitlab/code_owners/loader.rb에 정의되어 있음.
  • Gitlab::CodeOwners::ReferenceExtractor: 텍스트에서 CODEOWNER 사용자, 그룹 및 이메일 참조를 추출합니다.
    • ./ee/lib/gitlab/code_owners/reference_extractor.rb에 정의되어 있음.
  • Gitlab::CodeOwners::UsersLoader: 올바른 CODEOWNER 파일을 찾아 내용을 Gitlab::CodeOwners::File 인스턴스로 로드합니다.
    • ./ee/lib/gitlab/code_owners/users_loader.rb에 정의되어 있음.
  • Gitlab::CodeOwners::GroupsLoader: 올바른 CODEOWNER 파일을 찾아 내용을 Gitlab::CodeOwners::File 인스턴스로 로드합니다.
    • ./ee/lib/gitlab/code_owners/groups_loader.rb에 정의되어 있음.
  • Gitlab::CodeOwners::Validator: require_code_owner_approval이 활성화된 보호된 브랜치로 사용자가 푸시할 때 CODEOWNERS 항목의 파일이 변경되지 않았는지 확인합니다.
    • ./ee/lib/gitlab/code_owners/validator.rb에 정의되어 있음.

Code Owners의 Git 액세스 확인 실행 순서

Gitlab::Checks::DiffCheck#file_paths_validations는 LFS가 활성화되어 있고 파일 잠금이 있는 경우 #lfs_file_locks_validation의 결과 중 하나인 빈 배열이거나 단일 멤버가 있는 배열을 반환합니다. 이 파일의 EE 버전의 #validate_code_owners의 반환 결과는 이 디렉터리의 맨 끝에 삽입됩니다. LFS 확인은 Code Owners 확인 전에 수행됩니다.

이 확인은 #validations_for_path에 나열된 확인 후에 실행되며, 이는 EE 버전에만 존재하며 #path_locks_validation#file_name_validation을 포함합니다. 따라서 경로 잠금의 확인은 코드 소유자의 확인에 앞서 진행됩니다.

EE에서의 확인 순서는 다음과 같습니다 (LFS를 제외한 기능만 존재하는 경우):

  • 경로 잠금
  • 파일 이름
    • id_rsa와 같은 시크릿을 포함하는 파일 차단
    • PushRule#file_name_regex와 일치하는 파일 차단
  • LFS 파일 잠금
  • 코드 소유자

관련 모델

ProtectedBranch

ProtectedBranch 모델은 app/models/protected_branch.rb에서 정의되며, ee/app/models/concerns/ee/protected_branch.rb에서 확장됩니다. EE 버전에는 require_code_owner_approval라는 열이 포함되어 있어, CODEOWNERS에 나열된 파일이 직접 보호된 브랜치로 푸시되는 것을 방지합니다.

ApprovalMergeRequestRule

ApprovalMergeRequestRule 모델은 ee/app/models/approval_merge_request_rule.rb에서 정의됩니다. 이 모델은 Merge Request의 승인 규칙을 저장합니다. 여러 규칙 유형을 사용하며, code_owner 유형 규칙을 포함합니다.

컨트롤러 및 서비스

다음 컨트롤러 및 서비스는 승인 규칙 기능을 위해 사용됩니다:

Api::Internal::Base

/internal/allowed 엔드포인트는 사용자가 푸시할 수 있는지 확인하기 위해 GitLab에 푸시될 때 호출됩니다. /internal/allowed 엔드포인트는 Gitlab::Checks::DiffCheck를 수행합니다. EE에서는 코드 소유자 확인을 포함합니다.

lib/api/internal/base.rb에 정의되어 있음.

Repositories::GitHttpController

변경 내용이 HTTP를 통해 GitLab에 푸시되면 컨트롤러는 사용자가 푸시할 수 있는지 확인하기 위해 액세스 확인을 수행합니다. 확인은 Gitlab::Checks::DiffCheck를 수행합니다. EE에서는 코드 소유자 확인을 포함합니다.

app/controllers/repositories/git_http_controller.rb에 정의되어 있음.

EE::Gitlab::Checks::DiffCheck

이 모듈은 CE의 Gitlab::Checks::DiffChecks 클래스를 확장하고 코드 소유자 검증을 추가합니다. Gitlab::CodeOwner::Validator 클래스를 사용하여 사용자가 CODEOWNER 디렉터리에 나열된 파일을 보호된 브랜치로 직접 푸시하지 않도록 확인합니다.

MergeRequests::SyncCodeOwnerApprovalRules

이 서비스는 services/merge_requests/sync_code_owner_approval_rules.rb에 정의되어 있으며 다음을 위해 사용됩니다:

  • Merge Request에 새로운 변경 사항이 푸시될 때 오래된 코드 소유자 승인 규칙을 삭제합니다.
  • CODEOWNER 파일에 나열된 Merge Request의 각 변경된 파일에 코드 소유자 승인 규칙을 생성합니다.

플로우

다음 플로우 차트는 컨트롤러부터 모델까지의 플로우를 설명하는 데 도움이 될 것입니다.

Code Owners 구현 중 많은 부분이 클래스의 EE 변형에 존재함을 유의하십시오.

require_code_owner_approval가 활성화된 보호된 브랜치로 SSH를 통해 변경 사항을 푸시

%%{init: { "fontFamily": "GitLab Sans" }}%% graph TD Api::Internal::Base --> Gitlab::GitAccess Gitlab::GitAccess --> Gitlab::Checks::DiffCheck Gitlab::Checks::DiffCheck --> Gitlab::CodeOwners::Validator Gitlab::CodeOwners::Validator --> ProtectedBranch Gitlab::CodeOwners::Validator --> Gitlab::CodeOwners::Loader Gitlab::CodeOwners::Loader --> Gitlab::CodeOwners::Entry

require_code_owner_approval가 활성화된 보호된 브랜치로 HTTPS를 통해 변경 사항을 푸시

%%{init: { "fontFamily": "GitLab Sans" }}%% graph TD Repositories::GitHttpController --> Gitlab::GlRepository Gitlab::GlRepository --> Gitlab::GitAccessProject Gitlab::GitAccessProject --> Gitlab::Checks::DiffCheck Gitlab::Checks::DiffCheck --> Gitlab::CodeOwners::Validator Gitlab::CodeOwners::Validator --> ProtectedBranch Gitlab::CodeOwners::Validator --> Gitlab::CodeOwners::Loader Gitlab::CodeOwners::Loader --> Gitlab::CodeOwners::Entry

코드 소유자 규칙을 Merge Request 승인 규칙에 동기화

%%{init: { "fontFamily": "GitLab Sans" }}%% graph TD EE::ProtectedBranches::CreateService --> MergeRequest::SyncCodeOwnerApprovalRules EE::MergeRequestRefreshService --> MergeRequest::SyncCodeOwnerApprovalRules EE::MergeRequests::ReloadMergeHeadDiffService --> MergeRequest::SyncCodeOwnerApprovalRules EE::MergeRequests::CreateService --> MergeRequests::SyncCodeOwnerApprovalRulesWorker EE::MergeRequests::UpdateService --> MergeRequests::SyncCodeOwnerApprovalRulesWorker MergeRequests::SyncCodeOwnerApprovalRulesWorker --> MergeRequest::SyncCodeOwnerApprovalRules MergeRequest::SyncCodeOwnerApprovalRules --> id1{delete outdated code owner rules} MergeRequest::SyncCodeOwnerApprovalRules --> id2{create rule for each code owner entry}