Skip to main content

Code owners


Code owners enables companies to define individuals, teams, or groups that are responsible for code in a repository. This is useful in ensuring that pull/merge requests are reviewed and approved by a specific set of contributors, before the branch is merged into the base branch.

With that being said, moon does not implement a custom code owners solution, and instead builds upon the popular CODEOWNERS integration in VCS providers, like GitHub, GitLab, and Bitbucket.

Defining owners

With moon, you do not modify a CODEOWNERS file directly. Instead you define owners per project with moon.yml, or globally with .moon/workspace.yml. These owners are then aggregated and automatically synced to a CODEOWNERS file.


An owner is a user, team, or group unique to your VCS provider. Please refer to your provider's documentation for the correct format in which to define owners.


For projects, we support an owners setting in moon.yml that accepts file patterns/paths and their owners (contributors required to review), as well as operational settings for minimum required approvals, custom groups, and more.

Paths configured here are relative from the project root, and will be prefixed with the project source (path from workspace root to project root) when the file is synced.

requiredApprovals: 2
'src/': ['@frontend', '@design-system']
'*.config.js': ['@frontend-infra']
'*.json': ['@frontend-infra']

The configuration above would generate the following:

# components
/packages/components/src/ @frontend @design-system
/packages/components/*.config.js @frontend-infra
/packages/components/*.json @frontend-infra


Project scoped owners are great but sometimes you need to define owners for files that span across all projects, or files at any depth within the repository. With the codeowners.globalPaths setting in .moon/workspace.yml, you can do just that.

Paths configured here are used as-is, allowing for full control of what ownership is applied.

# All files
'*': ['@admins']
# Config folder at any depth
'config/': ['@app-platform']
# GitHub folder at the root
'/.github/': ['@infra']

The configuration above would generate the following at the top of the file (is the same for all providers):

# (workspace)
* @admins
config/ @app-platform
/.github/ @infra


Code owners is an opt-in feature, and as such, the CODEOWNERS file can be generated in a few ways. The first is manually, with the moon sync codeowners command.

$ moon sync codeowners

While this works, it is a manual process, and can easily be forgotten, resulting in an out-of-date file.

An alternative solution is the codeowners.syncOnRun setting in .moon/workspace.yml, that when enabled, moon will automatically generate a CODEOWNERS file when a target is ran.

syncOnRun: true

The format and location of the CODEOWNERS file is based on the vcs.provider setting.


What providers or formats are supported?

The following providers are supported, based on the vcs.provider setting.

Where does the CODEOWNERS file get created?

The location of the file is dependent on the configured provider.

  • GitHub -> .github/CODEOWNERS
  • GitLab -> .gitlab/CODEOWNERS
  • Everything else -> CODEOWNERS

Why are owners defined in moon.yml and not an alternative like OWNERS?

A very popular pattern for defining owners is through an OWNERS file, which can appear in any folder, at any depth, within the repository. All of these files are then aggregated into a single CODEOWNERS file.

While this is useful for viewing ownership of a folder at a glance, it incurs a massive performance hit as we'd have to constantly glob the entire repository to find all OWNERS files. We found it best to define owners in moon.yml instead for the following reasons:

  • No performance hit, as we're already loading and parsing these config files.
  • Co-locates owners with the rest of moon's configuration.
  • Ownership is now a part of the project graph, enabling future features.