$ npm install codeowners-audit
Generate a polished, interactive HTML report for CODEOWNERS coverage, ownership gaps, and GitHub-parity validation. Run it locally for investigation or in CI to fail when files are uncovered.
See how ownership coverage looks in practice with this interactive report for the nodejs/node repository.
CODEOWNERS is great for review routing, but it is hard to quickly answer:
CODEOWNERS rules look valid in git, but are ignored or ineffective on GitHub?codeowners-audit scans a repository, applies practical CODEOWNERS resolution, and produces a single self-contained HTML report you can open locally, archive in CI, or upload to a public link.
CODEOWNERS files, missing paths, invalid owners, oversized files, and fragile coverageRun without installing:
npx codeowners-audit
For repeat use in a repository or CI, add it as a dev dependency:
npm install --save-dev codeowners-audit
Common first runs:
Generate a report for the current repository:
npx codeowners-audit
Fail in CI without writing HTML:
npx codeowners-audit --no-report
Audit a remote GitHub repository:
npx codeowners-audit watson/codeowners-audit
codeowners-audit [repo-or-path] [options]
The executable name is codeowners-audit. If you are running it without installing it as a dependency, prefix commands with npx.
[repo-or-path] is optional and can be:
https://github.com/owner/repoowner/repo~/code/my-repoBy default, the tool:
git ls-filesWhen standard input is non-interactive (no TTY, for example in CI), the command automatically behaves as if --no-open --list-unowned --fail-on-unowned were specified:
Use --output or --output-dir for deterministic artifact paths, or --no-report to skip writing HTML entirely. In interactive mode, --no-report implies --list-unowned so the command still produces useful output.
| Option | Description |
|---|---|
--cwd <dir> | Run git commands from this directory |
--include-untracked | Include untracked files in the analysis |
-g, --glob <pattern> | Repeatable file filter for report and check scope (default: **) |
| Option | Description |
|---|---|
-o, --output <path> | Output HTML file path |
--output-dir <dir> | Output directory for the generated HTML report |
--no-report | Skip HTML report generation (implies --list-unowned) |
--upload | Upload to zenbin and print a public URL |
| Option | Description |
|---|---|
--no-open | Do not prompt to open the report in your browser |
-y, --yes | Automatically answer yes to interactive prompts |
--verbose | Enable verbose progress output |
-h, --help | Show this help |
-v, --version | Show version |
| Option | Description |
|---|---|
--list-unowned | Print unowned file paths to stdout |
--fail-on-unowned | Exit non-zero when one or more files are unowned |
| Option | Description |
|---|---|
--fail-on-oversized-codeowners | Exit non-zero when the active CODEOWNERS file exceeds GitHub's 3 MB limit |
--fail-on-missing-paths | Exit non-zero when one or more CODEOWNERS paths match no repository files |
--validate-github-owners | Validate @username and @org/team owners against GitHub and use only validated owners for coverage |
--fail-on-invalid-owners | Exit non-zero when one or more CODEOWNERS rules contain invalid GitHub owners |
--fail-on-missing-directory-slashes | Exit non-zero when directory CODEOWNERS paths do not follow the explicit trailing-slash style |
--fail-on-location-warnings | Exit non-zero when extra or ignored CODEOWNERS files are found |
--fail-on-fragile-coverage | Exit non-zero when directories have fragile file-by-file coverage |
| Option | Description |
|---|---|
--suggest-teams | Suggest @org/team for uncovered directories |
--suggest-window-days <days> | Git history lookback window for suggestions (default: 365) |
--suggest-top <n> | Top team suggestions to keep per directory (default: 3) |
--suggest-ignore-teams <list> | Comma-separated team slugs or @org/slug entries to exclude from suggestions |
--github-org <org> | Override GitHub org for team lookups |
--github-token <token> | GitHub token for team lookups (falls back to GITHUB_TOKEN, then GH_TOKEN) |
--github-api-base-url <url> | GitHub API base URL (default: https://api.github.com) |
Generate a report and open it after pressing Enter:
codeowners-audit
Write a report to a known path without opening a browser:
codeowners-audit --output codeowners-gaps-report.html --no-open
Run against a repository from another directory:
codeowners-audit ~/code/my-repo
Audit a remote GitHub repository:
codeowners-audit watson/codeowners-audit
Upload a report and print the public URL:
codeowners-audit --upload
Validate only a subset of files:
codeowners-audit --glob "src/**/*.js" --glob "test/**/*.js"
Suggest teams for uncovered directories:
codeowners-audit --suggest-teams
Most CI systems, including GitHub Actions, run in a non-interactive environment. In that mode, codeowners-audit automatically:
--no-open--list-unowned1 when uncovered files exist with --fail-on-unownedExit code behavior:
0: all matched files are covered by CODEOWNERS, and no enabled validation policy failed1: at least one enforced policy failed, including uncovered files and any enabled --fail-on-* validation rule2: runtime or setup error, for example not being in a git repository, missing CODEOWNERS, or invalid argumentsValidate all tracked files:
codeowners-audit
Validate all tracked files without writing HTML:
codeowners-audit --no-report
Validate and write a report artifact to a known path:
codeowners-audit --output codeowners-gaps-report.html
Validate and write reports into an artifact directory:
codeowners-audit --output-dir artifacts
Validate only a subset, for example spec files:
codeowners-audit --glob "**/*.spec.js"
- name: Verify CODEOWNERS coverage
run: npx codeowners-audit --no-report
CODEOWNERS discovery order: .github/CODEOWNERS, CODEOWNERS, then docs/CODEOWNERSCODEOWNERS location is active@username and @org/team owners against GitHub with --validate-github-ownersCODEOWNERS files, missing paths, fragile coverage, and unsupported syntax that GitHub would not honorgit available on PATHzenbin currently rejects request payloads around 1 MiB and larger. Very large repositories can produce HTML reports beyond that limit, in which case --upload will fail with a clear size error. Use the generated local HTML file directly when this happens.
MIT