代码所有者

代码所有者定义谁开发和维护功能,并拥有仓库中生成的文件或目录。

  • 当您浏览目录时,您定义为代码所有者的用户会显示在 UI 中。
  • 您可以设置合并请求,以便在合并前必须得到代码所有者的批准。
  • 您可以保护分支并仅允许代码所有者批准对分支的更改。

使用代码所有者、核准人以及批准规则,构建灵活的批准工作流程:

  • 使用 代码所有者,定义对仓库中的特定路径具有领域专业知识的用户。
  • 使用 核准人批准规则 来定义专业领域(例如安全团队),这些领域不限于仓库中的特定文件路径。
    • 核准人 定义用户。
    • 批准规则 定义这些用户何时可以批准工作,以及是否需要他们的批准。

例如:

类型 名称 范围 说明
批准规则 UX 所有文件 用户体验 (UX) 团队成员评审项目中所有更改的用户体验。
批准规则 Security 所有文件 安全团队成员评审所有更改是否存在漏洞。
代码所有者批准规则 Frontend: Code Style *.css 文件 前端工程师检查 CSS 文件更改是否符合项目样式标准。
代码所有者批准规则 Backend: Code Review *.rb 文件 后端工程师评审 Ruby 文件的逻辑和代码风格。

设置代码所有者

创建一个 CODEOWNERS 文件,指定负责仓库中特定文件和目录的用户或共享群组。每个仓库都可以有一个CODEOWNERS 文件。创建步骤:

  1. 选择要指定代码所有者的位置:
    • 在仓库的根目录中
    • .gitlab/ 目录中
    • docs/ 目录中
  2. 在那个位置,创建一个名为 CODEOWNERS 的文件。

  3. 在文件中,输入遵循以下模式之一的文本:

    # Code Owners for a file
    filename @username1 @username2
    
    # Code Owners for a directory
    directoryname/ @username1 @username2
    
    # All group members as Code Owners for a file
    filename @groupname
    
    # All group members as Code Owners for a directory
    directoryname/ @groupname
    

代码所有者现在显示在 UI 中。 它们仅适用于当前分支。

下一步:

note要获得批准,作为代码所有者的群组必须在项目中具有直接成员身份(非继承成员身份)。批准对于只有继承成员资格的群组为可选。代码所有者群组中的成员也必须是直接成员,并且不能从任何父组继承成员资格。

群组作为代码所有者

您可以将群组和子组的成员用作项目的代码所有者。

graph TD A[Parent group X] -->|owns| B[Project A] A -->|contains| C[Subgroup Y] C -->|owns| D[Project B] A-. inherits ownership .-> D

在示例中:

  • 父组 X (group-x) 拥有 项目 A
  • 父组 X 也包含子组,子组 Y (group-x/subgroup-y)。
  • 子组 Y 拥有 项目 B

符合条件的代码所有者是:

  • 项目 A:仅限 群组 X 的成员,因为 项目 A 不属于 子组 Y
  • 项目 B群组 X子组 Y 的成员。

您可以邀请 Subgroup YProject A,以便他们的成员也成为合格的代码所有者。

graph LR A[Parent group X] -->|owns| B[Project A] A -->|also contains| C[Subgroup Y] C -.->D{Invite Subgroup Y<br/>to Project A?} -.->|yes| F[Approvals can be<br/> required] -.-> B D{Invite Subgroup Y<br/>to Project A?} -.->|no| I[Subgroup Y cannot be<br /> an approver] -.-> B C -.->E{Add Subgroup Y<br/>as Code Owners<br/>to Project A?} -.->|yes| H[Approvals can only<br/>be optional] -.-> B

如果您不邀请 Subgroup Y 加入 Project A,而是让他们成为代码所有者,则他们对合并请求的批准变为可选。

不支持将 Subgroup Y 邀请到 Project A 的父组。要将 Subgroup Y 设置为代码所有者,请将该群组直接添加到项目本身。

添加群组作为代码所有者

将群组设置为代码所有者:

CODEOWNERS 文件中,输入遵循以下模式之一的文本:

# All group members as Code Owners for a file
file.md @group-x

# All subgroup members as Code Owners for a file
file.md @group-x/subgroup-y

# All group and subgroup members as Code Owners for a file
file.md @group-x @group-x/subgroup-y

当一个文件匹配多个CODEOWNERS条目时

当文件与 CODEOWNERS 文件中的多个条目匹配时,将使用与该文件匹配的最后一个 pattern 中的用户。

例如,在以下 CODEOWNERS 文件中:

README.md @user1

# This line would also match the file README.md
*.md @user2

README.md 的代码所有者将是 @user2

如果您使用部分,则使用每个部分的最后一个用户。

每个文件路径只能匹配一个 CODEOWNERS pattern。

通过将代码所有者放入命名部分来组织代码所有者

您可以通过将代码所有者放入命名部分来组织代码所有者。

您可以将其用于共享目录,以便多个团队可以成为审核者。

要将命名部分添加到 CODEOWNERS 文件,请在括号中输入部分名称,后跟文件或目录,以及用户、群组或子组:

[README Owners]
README.md @user1 @user2
internal/README.md @user2

合并请求部件中的每个代码所有者都列在一个标记下。 下图显示了 群组文档 部分:

MR widget - Sectional Code Owners

具有重复名称的命名部分

如果多个命名部分具有相同的名称,则将它们合并。 此外,命名标题不区分大小写。例如:

[Documentation]
ee/docs/    @docs
docs/       @docs

[Database]
README.md  @database
model/db/   @database

[DOCUMENTATION]
README.md  @docs

此代码包含 Documentation 部分标题下的三个条目和 Database 下的两个条目。DocumentationDOCUMENTATION 部分下定义的条目使用第一个命名部分合并。

将代码所有者命名部分设为可选

  • 引入于专业版 13.8 版本,在功能标志后默认禁用。
  • 功能标志移除于 13.9 版本

您可以在代码所有者文件中指定可选部分。在节名称前面加上插入符号 ^,将整个部分视为可选。 可选部分使您能够为代码库的各个部分指定责任方,但不需要他们的批准。这种方法为经常更新但不需要严格审查的项目部分提供了更宽松的策略。

在这个例子中,[Go] 部分是可选的:

[Documentation]
*.md @root

[Ruby]
*.rb @root

^[Go]
*.go @root

可选的代码所有者部分显示在 批准规则 区域下的合并请求中:

MR widget - Optional Code Owners sections

如果文件中有一个命名部分重复,并且其中一个被标记为可选而另一个不是,则该部分是必需的。

仅当使用合并请求提交更改时,CODEOWNERS 文件中的可选部分才被视为可选部分。如果更改直接提交给受保护的分支,即使该部分被标记为可选,仍然需要代码所有者的批准。

允许推送

代码所有者批准和受保护分支功能不适用于允许推送的用户。

示例 CODEOWNERS 文件

# This is an example of a CODEOWNERS file.
# Lines that start with `#` are ignored.

# app/ @commented-rule

# Specify a default Code Owner by using a wildcard:
* @default-codeowner

# Specify multiple Code Owners by using a tab or space:
* @multiple @code @owners

# Rules defined later in the file take precedence over the rules
# defined before.
# For example, for all files with a filename ending in `.rb`:
*.rb @ruby-owner

# Files with a `#` can still be accessed by escaping the pound sign:
\#file_with_pound.rb @owner-file-with-pound

# Specify multiple Code Owners separated by spaces or tabs.
# In the following case the CODEOWNERS file from the root of the repo
# has 3 Code Owners (@multiple @code @owners):
CODEOWNERS @multiple @code @owners

# You can use both usernames or email addresses to match
# users. Everything else is ignored. For example, this code
# specifies the `@legal` and a user with email `janedoe@gitlab.com` as the
# owner for the LICENSE file:
LICENSE @legal this_does_not_match janedoe@gitlab.com

# Use group names to match groups, and nested groups to specify
# them as owners for a file:
README @group @group/with-nested/subgroup

# End a path in a `/` to specify the Code Owners for every file
# nested in that directory, on any level:
/docs/ @all-docs

# End a path in `/*` to specify Code Owners for every file in
# a directory, but not nested deeper. This code matches
# `docs/index.md` but not `docs/projects/index.md`:
/docs/* @root-docs

# Include `/**` to specify Code Owners for all subdirectories
# in a directory. This rule matches `docs/projects/index.md` or 
# `docs/development/index.md`
/docs/**/*.md @root-docs

# This code makes matches a `lib` directory nested anywhere in the repository:
lib/ @lib-owner

# This code match only a `config` directory in the root of the repository:
/config/ @config-owner

# If the path contains spaces, escape them like this:
path\ with\ spaces/ @space-owner

# Code Owners section:
[Documentation]
ee/docs    @docs
docs       @docs

[Database]
README.md  @database
model/db   @database

# This section is combined with the previously defined [Documentation] section:
[DOCUMENTATION]
README.md  @docs