代码所有者开发指南
本文档旨在帮助贡献者理解 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::Checks::Diffs::CodeOwnersCheck: 当用户推送到启用了require_code_owner_approval的受保护分支时,验证CODEOWNERS条目中的文件是否未被更改。- 定义在
./ee/lib/gitlab/checks/diffs/code_owners_check.rb中。
- 定义在
代码所有者在 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。这意味着在流程中,路径锁检查先于代码所有者检查。
在 EE 中的检查顺序如下(只有 LFS 作为非 EE 功能存在):
- 路径锁
- 文件名
- 阻止包含密钥的文件,例如
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 中。
该模型存储合并请求的批准规则。我们使用多种规则类型,包括 code_owner 类型的规则。
控制器和服务
以下控制器和服务用于使批准规则功能正常工作:
Api::Internal::Base
当推送到 GitLab 时,会调用此 /internal/allowed 端点以确保用户被允许推送。/internal/allowed 端点执行 Gitlab::Checks::DiffCheck。在 EE 中,这包括代码所有者检查。
定义在 lib/api/internal/base.rb 中。
Repositories::GitHttpController
当通过 HTTP 将更改推送到 GitLab 时,控制器执行访问检查以确保用户被允许推送。检查执行 Gitlab::Checks::DiffCheck。在 EE 中,这包括 Code Owner 检查。
定义在 app/controllers/repositories/git_http_controller.rb 中。
EE::Gitlab::Checks::DiffCheck
此模块扩展了 CE Gitlab::Checks::DiffChecks 类并添加了代码所有者验证。它使用 Gitlab::Checks::Diffs::CodeOwnersCheck 类来验证用户是否没有将列在 CODEOWNER 中的文件直接推送到需要代码所有者批准的受保护分支。
MergeRequests::SyncCodeOwnerApprovalRules
此服务定义在 services/merge_requests/sync_code_owner_approval_rules.rb 中,用于:
- 当新更改推送到合并请求时,删除过时的代码所有者批准规则。
- 为合并请求中每个已更改的文件创建代码所有者批准规则,这些文件也列在
CODEOWNER文件中。
流程
这些流程图应该有助于解释从控制器到不同功能模型的流程。
许多 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::Checks::Diffs::CodeOwnersCheck
Gitlab::Checks::Diffs::CodeOwnersCheck --> ProtectedBranch
Gitlab::Checks::Diffs::CodeOwnersCheck --> 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::Checks::Diffs::CodeOwnersCheck
Gitlab::Checks::Diffs::CodeOwnersCheck --> ProtectedBranch
Gitlab::Checks::Diffs::CodeOwnersCheck --> 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}