Code Owners 개발 가이드라인

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

이 문서는 코드가 자주 변경될 수 있기 때문에 코드의 개요로 의도적으로 제한되어 있습니다. 특정 기능이 작동하는 방법을 이해하려면 코드와 명세를 확인해야 합니다. 여기에 있는 세부 정보는 Code Owners 기능의 주요 구성 요소가 작동하는 방식을 설명합니다.

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

비즈니스 로직

Code Owners의 모든 비즈니스 로직은 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의 반환 결과는 EE::Gitlab::Checks::DiffCheck#file_paths_validations의 목록 끝에 삽입됩니다. LFS 확인은 Code Owners 확인 이전에 수행됩니다.

이러한 확인은 #validations_for_path에 나열된 확인 이후에 실행되며, 이는 EE 버전에만 존재하며 #path_locks_validation#file_name_validation을 포함합니다. 이는 경로 잠금의 확인이 Code Owners의 확인 이전에 진행된다는 것을 의미합니다.

EE의 확인 순서는 다음과 같습니다(EE 기능으로는 LFS만 존재함):

  • 경로 잠금
  • 파일 이름
    • 예를 들어 비밀을 포함하는 파일(예: id_rsa) 차단
    • PushRule#file_name_regex와 일치하는 파일 차단
  • LFS 파일 잠금
  • Code Owners

관련 모델

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에 정의되어 있습니다. 이 모델은 머지 요청에 대한 승인 규칙을 저장합니다. code_owner 유형의 규칙을 포함하여 여러 규칙 유형을 사용합니다.

컨트롤러 및 서비스

아래의 컨트롤러와 서비스는 승인 규칙 기능의 작동을 위해 사용됩니다.

Api::Internal::Base

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

lib/api/internal/base.rb에 정의됨.

Repositories::GitHttpController

GitLab으로 HTTP를 통해 변경사항을 푸시할 때 컨트롤러는 사용자가 푸시할 수 있는지 확인하기 위해 액세스 확인을 수행합니다. 이 확인은 Gitlab::Checks::DiffCheck를 수행합니다. EE에서는 Code Owner 확인이 포함됩니다.

app/controllers/repositories/git_http_controller.rb에 정의됨.

EE::Gitlab::Checks::DiffCheck

이 모듈은 CE Gitlab::Checks::DiffChecks 클래스를 확장하고 Code Owner 유효성 검사를 추가합니다. 이는 사용자가 보호된 브랜치로 CODEOWNER에 나열된 파일을 직접 푸시하지 않도록하는 데 Gitlab::CodeOwner::Validator 클래스를 사용합니다.

MergeRequests::SyncCodeOwnerApprovalRules

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

  • 변경 사항이 머지 요청에 푸시될 때 오래된 코드 소유자 승인 규칙을 삭제합니다.
  • CODEOWNER 파일에 나열된 머지 요청의 각 변경된 파일에 대해 코드 소유자 승인 규칙을 생성합니다.

Flow

이러한 플로우차트는 컨트롤러에서 모델로의 플로우를 설명하는 데 도움이 될 것입니다.

많은 Code Owners 구현은 클래스의 EE 변형에서 존재합니다.

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

%%{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

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

%%{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

코드 소유자 규칙을 병합 요청 승인 규칙으로 동기화합니다

%%{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}