Help us learn about your current experience with the documentation. Take the survey.

文件的语法 CODEOWNERS

  • Tier: Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

CODEOWNERS 文件使用一种语法来定义所有权规则。 文件中的每一行代表一个规则,指定文件路径模式和一个或多个所有者。 关键要素包括:

  • 文件路径:特定文件、目录或通配符。
  • 代码所有者:使用 @mentions 来引用用户、组或角色。
  • 注释:以 # 开头的行会被忽略。不支持行内注释。 注释中列出的任何代码所有者都会被解析。
  • 区段:使用 [区段名称] 定义的规则的可选分组。

如果一个条目在区段中重复,将使用最后一个条目。文件中后面定义的规则优先于前面的规则。

以下是一些示例:

# 使用通配符为所有文件指定默认代码所有者:
* @default-owner

# 为特定文件指定多个代码所有者:
README.md @doc-team @tech-lead

# 为具有特定扩展名的所有文件指定代码所有者:
*.rb @ruby-owner

# 使用用户名或电子邮件地址指定代码所有者:
LICENSE @legal [email protected]

# 使用组名匹配组和嵌套组:
README @group @group/with-nested/subgroup

# 为目录及其所有内容指定代码所有者:
/docs/ @all-docs
/docs/* @root-docs
/docs/**/*.md @markdown-docs  # 匹配任何子目录中的特定文件类型
/db/**/index.md @index-docs   # 匹配任何子目录中的特定文件名

# 使用区段来分组相关规则:
[Documentation]
ee/docs    @docs
docs       @docs

# 将角色指定为代码所有者:
/config/ @@maintainer

区段

CODEOWNERS 文件中,区段是单独分析的区域,并且始终强制执行。在您定义区段之前,GitLab 将整个 CODEOWNERS 文件视为单个区段。 添加更多区段会改变 GitLab 评估文件的方式:

  • GitLab 将没有区段的条目(包括在第一个区段标题之前定义的规则)视为另一个未命名的区段。
  • 每个区段单独强制执行其规则。
  • 每个区段只有一个代码所有者模式与文件路径匹配。
  • 文件中后面定义的规则优先于前面的规则。

例如,在一个定义了 README 文件代码所有者的 CODEOWNERS 文件中:

* @admin

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

[README other owners]
README.md @user3
  • 根目录中 README.md 的代码所有者是:
    • 来自未命名区段的 @admin
    • 来自 [README Owners]@user1@user2
    • 来自 [README other owners]@user3
  • internal/README.md 的代码所有者是:
    • 来自未命名区段的 @admin
    • 来自 [README Owners] 最后一个条目的 @user4
    • 来自 [README other owners]@user3。([README Owners] 中的两行都匹配此文件名,但只保留区段中的最后一行。)

要向 CODEOWNERS 文件添加区段,请在方括号中输入区段名称,后跟文件或目录,以及用户、组或子组:

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

合并请求小部件中的每个代码所有者都列在标签下。 下图显示了 DefaultFrontendTechnical Writing 区段:

MR widget - Sectional Code Owners

有关更多区段配置选项,请参阅:

区段标题和名称

区段标题必须有一个名称。 区段名称不区分大小写,并且重复名称的区段会被合并。 仅对于受保护分支,它们可以:

示例:

# 必需区段
[Section name]

# 可选区段
^[Section name]

# 需要 5 个批准的区段
[Section name][5]

# 以 @username 为默认所有者的区段
[Section name] @username

# 以 @group 和 @subgroup 为默认所有者并需要 2 个批准的区段
[Section name][2] @group @subgroup

为区段设置默认代码所有者

如果区段内的多个文件路径共享相同的所有权,请为区段定义默认代码所有者。 该区段中的所有路径都继承此默认值,除非您在特定行上覆盖区段默认值。

当未为文件路径指定特定所有者时,应用默认所有者。 文件路径旁边定义的特定所有者会覆盖默认所有者。

例如:

[Documentation] @docs-team
docs/
README.md

[Database] @database-team @agarcia
model/db/
config/db/database-setup.md @docs-team

在此示例中:

  • @docs-team 拥有 Documentation 区段中的所有项目。
  • @database-team@agarcia 拥有 Database 区段中的所有项目,除了 config/db/database-setup.md,它有一个覆盖将其分配给 @docs-team

将此行为与您同时使用常规条目和区段时进行比较, 当区段中的条目不覆盖无区段的条目时。

可选区段

您可以在代码所有者文件中指定可选区段。 可选区段使您能够为代码库的各个部分指定负责人,但不要求他们批准。这种方法为项目中经常更新但不需要严格审查的部分提供了更宽松的策略。

要将整个区段视为可选,请在区段名称前加上插入符号 ^ 字符。

在此示例中,[Go] 区段是可选的:

[Documentation]
*.md @root

[Ruby]
*.rb @root

^[Go]
*.go @root

可选代码所有者区段显示在合并请求描述下:

MR widget - Optional Code Owners sections

如果一个区段在文件中重复,并且其中一个标记为可选而另一个不是,则该区段是必需的。

CODEOWNERS 文件中的可选区段仅在通过合并请求提交更改时被视为可选。 如果更改直接提交到受保护分支,即使区段标记为可选,仍需要代码所有者的批准。

有资格的代码所有者

资格规则确定谁可以成为有效的代码所有者。根据 CODEOWNERS 文件中的引用方法(用户名、组或角色),适用特定规则。

用户资格

要通过用户名(@username)引用的用户有资格成为代码所有者,他们必须获得项目的授权。适用以下规则:

  • 项目和组可见性设置不影响资格。
  • 被组禁止的用户不能成为代码所有者。
  • 有资格的用户包括:
    • 具有开发人员角色或更高角色的直接项目成员。
    • 项目组的成员(直接或继承)。
    • 项目组的任何祖先的成员。
    • 被邀请到项目的组的直接或继承成员。
    • 被邀请到项目组的组的直接成员(非继承)。
    • 被邀请到项目组的祖先的组的直接成员(非继承)。

组资格

当使用组名(@group_name)或嵌套组名(@nested/group/names)引用组时,适用以下规则:

  • 组可见性设置不影响资格。
  • 只有引用组的直接成员有资格。不包括继承成员。
  • 有资格的组包括:
    • 项目的组。
    • 项目的组的祖先。
    • 以开发人员角色或更高角色被邀请到项目的组。

角色资格

当引用角色(@@role)时,适用以下规则:

  • 只有开发人员、维护者和所有者角色可以用作代码所有者。
  • 只有具有指定角色的直接项目成员有资格。
  • 角色不包括更高角色。例如,指定 @@developer 不包括 具有维护者或所有者角色的用户。

有关涉及组继承和资格的更复杂场景, 请参阅组继承和资格

将角色添加为代码所有者

您可以将直接项目成员的角色添加或设置为代码所有者:

  • 使用 @@ 前缀来设置角色。
  • 只有开发人员、维护者和所有者角色可用。
  • 角色不包括更高角色。例如,指定 @@developer 不包括具有维护者或所有者角色的用户。
  • 只有具有指定角色的直接项目成员有资格成为代码所有者。
  • 可以指定复数角色。例如,@@developers 是可接受的。

以下示例将所有具有开发人员或维护者角色的直接项目成员设置为 file.md 的代码所有者:

  1. 打开 CODEOWNERS 文件。

  2. 添加一行使用以下模式:

    file.md @@developer @@maintainer
  3. 保存文件。

  4. 提交并合并更改。

将组添加为代码所有者

您可以将组的直接成员或子组的直接成员设置为代码所有者。 有关组成员身份的更多信息,请参阅成员类型

先决条件:

要将组的直接成员或子组的直接成员设置为代码所有者:

  1. 打开 CODEOWNERS 文件。

  2. 输入以下模式之一的文本:

    # 将组的所有直接成员作为文件的代码所有者
    file.md @group-x
    
    # 将子组的所有直接成员作为文件的代码所有者
    file.md @group-x/subgroup-y
    
    # 将组的所有直接成员和子组的所有直接成员作为文件的代码所有者
    file.md @group-x @group-x/subgroup-y
  3. 保存文件。

  4. 提交并合并更改。

示例配置

[Maintainers]
* @gitlab-org/maintainers/group-name

在此示例中:

  • group-name 列在 [Maintainers] 区段下。

  • group-name 包含以下直接成员:

    组成员列表。

  • 在合并请求批准小部件中,相同的直接成员列为 Maintainers

    合并请求维护者。

当启用全局 SAML 组成员身份锁定时,您不能将组或子组设置为代码所有者。更多信息,请参阅与全局 SAML 组成员身份锁定的不兼容性

如果您遇到问题,请参阅用户未显示为可能的批准者

路径匹配

路径可以是绝对路径、相对路径、目录路径、通配符路径或 globstar 路径, 并且与仓库根目录匹配。

绝对路径

/ 开头的路径从仓库根目录匹配:

# 仅匹配根目录中的 README.md。
/README.md

# 仅匹配 /docs 目录中的 README.md。
/docs/README.md

相对路径

没有前导 / 的路径被视为globstar 路径

# 匹配 /README.md、/internal/README.md、/app/lib/README.md
README.md @username

# 匹配 /internal/README.md、/docs/internal/README.md、/docs/api/internal/README.md
internal/README.md

使用 globstar 路径时,请注意意外匹配。 例如,没有前导 /README.md 匹配仓库中任何目录或子目录中的任何 README.md 文件。

目录路径

/ 结束路径以匹配目录及其子目录中的所有文件:

# 匹配 /docs/ 及其子目录中的所有文件
/docs/

通配符路径

使用 * 匹配多个字符:

# docs 目录中的任何 markdown 文件
/docs/*.md @username

# /docs/index 文件的任何文件类型
# 例如:/docs/index.md、/docs/index.html、/docs/index.xml
/docs/index.* @username

# docs 目录中名称包含 'spec' 的任何文件。
# 例如:/docs/qa_specs.rb、/docs/spec_helpers.rb、/docs/runtime.spec
/docs/*spec* @username

# docs 目录中一级深度的 README.md 文件
# 例如:/docs/api/README.md
/docs/*/README.md @username

Globstar 路径

使用 ** 匹配多个目录级别的文件或模式:

# 例如:/docs/index.md、/docs/api/index.md 和 /docs/api/graphql/index.md。
/docs/**/index.md

要匹配目录中的所有文件, 使用带有尾部斜杠(/)的目录路径

排除模式

在文件或路径前加上 ! 以免除或排除它们需要代码所有者批准。 排除在其区段中应用。在以下示例中:

  • pom.xml 排除适用于默认区段。
  • /config/**/*.rb 排除仅影响 Ruby 区段中的 Ruby 文件。
# 所有文件都需要 @username 的批准
* @username

# 除了 pom.xml 不需要批准
!pom.xml

[Ruby]
# 所有 ruby 文件都需要 ruby-team 的批准
*.rb @ruby-team

# 除了 config 目录中的 Ruby 文件
!/config/**/*.rb

以下指南解释了排除模式的行为:

  • 排除在其区段中按顺序评估。例如:

    * @default-owner
    !*.rb                      # 排除所有 Ruby 文件。
    /special/*.rb @ruby-owner  # 这不会生效,因为 *.rb 已被排除。
  • 在排除一个模式后,不能在同一区段中再次包含它:

    [Ruby]
    *.rb @ruby-team           # 所有 Ruby 文件都需要 Ruby 团队批准。
    !/config/**/*.rb          # config 中的 Ruby 文件不需要 Ruby 团队批准。
    /config/routes.rb @ops    # 这不会生效,因为 config Ruby 文件已被排除。
  • 匹配排除模式的文件不需要该区段的代码所有者批准。 如果您需要为不同所有者使用不同的排除,请使用多个区段:

    [Ruby]
    *.rb @ruby-team
    !/config/**/*.rb        # config Ruby 文件不需要 Ruby 团队批准。
    
    [Config]
    /config/ @ops-team      # config 文件仍然需要 ops-team 批准。
  • 对自动更新的文件使用排除:

    * @default-owner
    
    # 自动化更新的文件不需要批准。
    !package-lock.json
    !yarn.lock
    !**/generated/          # generated 目录中的任何文件。
    !.gitlab-ci.yml

条目所有者

条目必须有一个或多个所有者。这些可以是组、子组和用户。

/path/to/entry.rb @group
/path/to/entry.rb @group/subgroup
/path/to/entry.rb @user
/path/to/entry.rb @group @group/subgroup @user

有关将组添加为代码所有者的更多信息,请参阅将组添加为代码所有者

相关主题