Codeowners is a fast, Rust-based CLI for generating and validating GitHub CODEOWNERS
files in large repositories. It supports conventions for Ruby and JavaScript projects, and is a high-performance reimplementation of the original Ruby CLI.
The most common workflow is to generate and validate your CODEOWNERS file in a single step:
codeowners gv
- This command will:
- Generate a fresh
CODEOWNERS
file (by default at.github/CODEOWNERS
) - Validate that all files are properly owned and that the file is up to date
- Exit with a nonzero code and detailed errors if validation fails
- Generate a fresh
Why use this tool?
On large projects, codeowners gv
is over 10x faster than the legacy Ruby implementation:
$ hyperfine 'codeownership validate' 'codeowners validate'
Benchmark 1: codeownership validate (ruby gem)
Time (mean ± σ): 47.991 s ± 1.220 s
Benchmark 2: codeowners gv (this repo)
Time (mean ± σ): 4.263 s ± 0.025 s
Summary
codeowners gv ran 11.26 ± 0.29 times faster than codeownership validate
- Quick Start: Generate & Validate
- Getting Started
- Declaring Ownership
- Other CLI Commands
- Validation
- Development
- Configuration
-
Install DotSlash
Install DotSlash
Releases include a DotSlash text file that will automatically download and run the correct binary for your system. -
Download the Latest DotSlash Text File
Releases contain a DotSlash text file. Example: codeowners release v0.2.4.
Running this file with DotSlash installed will executecodeowners
. -
Configure Ownership
Create aconfig/code_ownership.yml
file. Example:owned_globs: - '{app,components,config,frontend,lib,packs,spec}/**/*.{rb,rake,js,jsx,ts,tsx}' js_package_paths: [] unowned_globs: - db/**/* - app/services/some_file1.rb - frontend/javascripts/**/__generated__/**/*
-
Declare Teams
Example:config/teams/operations.yml
name: Operations github: team: '@my-org/operations-team'
-
Run the Main Workflow
codeowners gv
You can declare code ownership in several ways:
Add a .codeowner
file to a directory with the team name as its contents:
TeamName
Add an annotation at the top of a file:
# @team MyTeam
In package.yml
(for Ruby Packwerk):
owner: TeamName
In your team's YML:
owned_globs:
- app/services/my_team/**/*
unowned_globs:
- app/services/my_team/legacy/*
unowned_globs
"subtracts" from owned_globs
In package.json
:
{
"metadata": {
"owner": "My Team"
}
}
Configure search paths in code_ownership.yml
:
js_package_paths:
- frontend/javascripts/packages/*
While codeowners gv
is the main workflow, the CLI also supports:
Usage: codeowners [OPTIONS] <COMMAND>
Commands:
for-file Finds the owner of a given file. [aliases: f]
for-team Finds code ownership information for a given team [aliases: t]
generate Generate the CODEOWNERS file [aliases: g]
validate Validate the CODEOWNERS file [aliases: v]
generate-and-validate Chains both `generate` and `validate` [aliases: gv]
help Print this message or the help of the given subcommand(s)
Options:
--codeowners-file-path <CODEOWNERS_FILE_PATH> [default: ./.github/CODEOWNERS]
--config-path <CONFIG_PATH> [default: ./config/code_ownership.yml]
--project-root <PROJECT_ROOT> [default: .]
-h, --help
-V, --version
codeowners for-file path/to/file.rb
codeowners for-team Payroll
codeowners validate
(or codeowners gv
) ensures:
- Only one mechanism defines ownership for any file.
- All referenced teams are valid.
- All files in
owned_globs
are owned, unless inunowned_globs
. - The
CODEOWNERS
file is up to date.
-
Written in Rust for speed and reliability.
-
To build locally, install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Please update
CHANGELOG.md
and thisREADME.md
when making changes.