You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve the npm-facing README so the core value, quick start, and option groups are
clearer to scan. Reformat the CLI help output into spaced sections and make the
help-output test resilient to future column-width tweaks.
Made-with: Cursor
<palign="center">Generate a polished, interactive HTML report that shows which files in a Git repository are covered by CODEOWNERS rules and where ownership gaps exist. You can also run it in CI or from the command line to fail when files are not covered by CODEOWNERS.</p>
5
+
<palign="center">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.</p>
See how ownership coverage looks in practice with [this interactive report](https://watson.github.io/codeowners-audit/example.html) for the `nodejs/node` repository.
12
12
@@ -17,35 +17,51 @@ See how ownership coverage looks in practice with [this interactive report](http
17
17
- How much of this repository is actually covered?
18
18
- Which directories have the biggest ownership gaps?
19
19
- Which specific files have no matching owner rule?
20
+
- Which `CODEOWNERS` rules look valid in git, but are ignored or ineffective on GitHub?
20
21
21
-
`codeowners-audit` scans your repository, applies `CODEOWNERS`matching rules, and produces a single self-contained HTML report you can open locally or upload to a public link.
22
+
`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.
22
23
23
24
## Highlights
24
25
25
-
- Interactive HTML report with no build step
26
-
- Coverage summary: total files, owned, unowned, and percentage
27
-
- Directory explorer with filtering, sorting, and drill-down
28
-
- Full unowned file list with scope and text filtering
29
-
- Ownership explorer with quick chips and file filtering for resolved CODEOWNERS owners, including `@org/team`, `@username`, and email owners
- Detects CODEOWNERS patterns that match no repository paths
32
-
- Detects directories with fragile coverage — 100% covered through individual file rules, but new files would lack owners
33
-
- Warns when extra or unsupported `CODEOWNERS` files will be ignored by GitHub
34
-
- Optional upload to [zenbin.org](https://zenbin.org) for easy sharing
26
+
- Self-contained interactive HTML report
27
+
- Coverage drill-down by repository, directory, file, and resolved owner
28
+
- CI-friendly defaults that can fail builds when files are uncovered
29
+
- GitHub-parity validation for ignored `CODEOWNERS` files, missing paths, invalid owners, oversized files, and fragile coverage
30
+
- Optional team suggestions for uncovered directories based on git history
31
+
- Works on local repositories or remote GitHub repositories with a single command
35
32
36
-
## Installation
33
+
## Quick Start
37
34
38
-
Run with `npx` (no install):
35
+
Run without installing:
39
36
40
37
```bash
41
38
npx codeowners-audit
42
39
```
43
40
44
-
Or install globally:
41
+
For repeat use in a repository or CI, add it as a dev dependency:
45
42
46
43
```bash
47
-
npm install -g codeowners-audit
48
-
codeowners-audit
44
+
npm install --save-dev codeowners-audit
45
+
```
46
+
47
+
Common first runs:
48
+
49
+
Generate a report for the current repository:
50
+
51
+
```bash
52
+
npx codeowners-audit
53
+
```
54
+
55
+
Fail in CI without writing HTML:
56
+
57
+
```bash
58
+
npx codeowners-audit --no-report
59
+
```
60
+
61
+
Audit a remote GitHub repository:
62
+
63
+
```bash
64
+
npx codeowners-audit watson/codeowners-audit
49
65
```
50
66
51
67
## Usage
@@ -54,106 +70,148 @@ codeowners-audit
54
70
codeowners-audit [repo-or-path] [options]
55
71
```
56
72
57
-
The first argument is optional and can be:
73
+
The executable name is `codeowners-audit`. If you are running it without installing it as a dependency, prefix commands with `npx`.
58
74
59
-
- A **remote repository URL** (e.g. `https://github.com/owner/repo`) or **GitHub shorthand** (`owner/repo`) — the repo will be cloned into a temp directory, audited, and the clone removed automatically.
60
-
- A **local directory path** (e.g. `~/code/my-repo`) — equivalent to `--cwd`.
61
-
-**Omitted** — the current working directory is used.
75
+
`[repo-or-path]` is optional and can be:
76
+
77
+
- A remote repository URL such as `https://github.com/owner/repo`
78
+
- GitHub shorthand such as `owner/repo`
79
+
- A local directory path such as `~/code/my-repo`
80
+
- Omitted, in which case the current working directory is used
62
81
63
82
By default, the tool:
64
83
65
84
- analyzes tracked files from `git ls-files`
66
85
- writes the report to a temporary path
67
86
- prompts you to press Enter before opening the report in your default browser
68
87
69
-
When standard input is non-interactive (no TTY - e.g. a CI environemnt), the command automatically behaves as if
70
-
`--no-open --list-unowned --fail-on-unowned` were specified:
88
+
When 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:
89
+
71
90
- it never prompts to open a browser
72
91
- it prints all unowned file paths to stdout
73
92
- it exits non-zero when uncovered files exist
74
93
75
-
Use `--output` or `--output-dir` for deterministic artifact paths, or `--no-report` to skip writing HTML entirely.
76
-
In interactive mode, `--no-report` implies `--list-unowned` so output still stays useful.
94
+
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.
95
+
96
+
## Options
77
97
78
-
### Options
98
+
### Input and Scope
79
99
80
100
| Option | Description |
81
101
| --- | --- |
82
-
|`-o, --output <path>`| Output HTML file path |
83
-
|`--output-dir <dir>`| Output directory for the generated HTML report |
84
102
|`--cwd <dir>`| Run git commands from this directory |
85
103
|`--include-untracked`| Include untracked files in the analysis |
104
+
|`-g, --glob <pattern>`| Repeatable file filter for report and check scope (default: `**`) |
105
+
106
+
### Report Output
107
+
108
+
| Option | Description |
109
+
| --- | --- |
110
+
|`-o, --output <path>`| Output HTML file path |
111
+
|`--output-dir <dir>`| Output directory for the generated HTML report |
86
112
|`--no-report`| Skip HTML report generation (implies `--list-unowned`) |
113
+
|`--upload`| Upload to zenbin and print a public URL |
114
+
115
+
### Interaction and Diagnostics
116
+
117
+
| Option | Description |
118
+
| --- | --- |
119
+
|`--no-open`| Do not prompt to open the report in your browser |
120
+
|`-y, --yes`| Automatically answer yes to interactive prompts |
121
+
|`--verbose`| Enable verbose progress output |
122
+
|`-h, --help`| Show this help |
123
+
|`-v, --version`| Show version |
124
+
125
+
### Core Coverage Checks
126
+
127
+
| Option | Description |
128
+
| --- | --- |
87
129
|`--list-unowned`| Print unowned file paths to stdout |
88
130
|`--fail-on-unowned`| Exit non-zero when one or more files are unowned |
131
+
132
+
### GitHub Validation and Policy Checks
133
+
134
+
| Option | Description |
135
+
| --- | --- |
89
136
|`--fail-on-oversized-codeowners`| Exit non-zero when the active `CODEOWNERS` file exceeds GitHub's 3 MB limit |
90
-
|`--fail-on-missing-paths`| Exit non-zero when one or more CODEOWNERS paths match no repository files |
137
+
|`--fail-on-missing-paths`| Exit non-zero when one or more `CODEOWNERS` paths match no repository files |
91
138
|`--validate-github-owners`| Validate `@username` and `@org/team` owners against GitHub and use only validated owners for coverage |
92
-
|`--fail-on-invalid-owners`| Exit non-zero when one or more CODEOWNERS rules contain invalid GitHub owners |
93
-
|`--fail-on-missing-directory-slashes`| Exit non-zero when directory CODEOWNERS paths do not follow the explicit trailing-slash style |
139
+
|`--fail-on-invalid-owners`| Exit non-zero when one or more `CODEOWNERS` rules contain invalid GitHub owners |
140
+
|`--fail-on-missing-directory-slashes`| Exit non-zero when directory `CODEOWNERS` paths do not follow the explicit trailing-slash style |
94
141
|`--fail-on-location-warnings`| Exit non-zero when extra or ignored `CODEOWNERS` files are found |
95
142
|`--fail-on-fragile-coverage`| Exit non-zero when directories have fragile file-by-file coverage |
|`--suggest-teams`| Suggest `@org/team` for uncovered directories |
98
149
|`--suggest-window-days <days>`| Git history lookback window for suggestions (default: `365`) |
99
150
|`--suggest-top <n>`| Top team suggestions to keep per directory (default: `3`) |
100
151
|`--suggest-ignore-teams <list>`| Comma-separated team slugs or `@org/slug` entries to exclude from suggestions |
101
152
|`--github-org <org>`| Override GitHub org for team lookups |
102
153
|`--github-token <token>`| GitHub token for team lookups (falls back to `GITHUB_TOKEN`, then `GH_TOKEN`) |
103
154
|`--github-api-base-url <url>`| GitHub API base URL (default: `https://api.github.com`) |
104
-
|`--upload`| Upload to zenbin and print a public URL |
105
-
|`-y, --yes`| Automatically answer yes to interactive prompts |
106
-
|`--no-open`| Do not prompt to open the report in your browser |
107
-
|`--verbose`| Enable verbose progress output |
108
-
|`-h, --help`| Show this help |
109
-
|`-v, --version`| Show version |
110
155
111
156
## Examples
112
157
113
-
Generate report and open it after pressing Enter:
158
+
Generate a report and open it after pressing Enter:
114
159
115
160
```bash
116
161
codeowners-audit
117
162
```
118
163
164
+
Write a report to a known path without opening a browser:
Most CI systems (including GitHub Actions) run in a non-interactive environment (no TTY on stdin).
146
-
In non-interactive environments, `codeowners-audit` automatically:
147
-
- disables browser prompts (`--no-open`)
148
-
- prints unowned files to stdout (`--list-unowned`)
149
-
- exits `1` when unowned files exist (`--fail-on-unowned`)
202
+
Most CI systems, including GitHub Actions, run in a non-interactive environment. In that mode, `codeowners-audit` automatically:
203
+
204
+
- disables browser prompts with `--no-open`
205
+
- prints unowned files to stdout with `--list-unowned`
206
+
- exits `1` when uncovered files exist with `--fail-on-unowned`
150
207
151
208
Exit code behavior:
152
-
- Exit code `0`: all matched files are covered by `CODEOWNERS`, and no enabled validation policy failed.
153
-
- Exit code `1`: at least one enforced policy failed. This includes uncovered files and any enabled `--fail-on-*` validation rule described in the [Options](#options) section.
154
-
- Exit code `2`: runtime/setup error (for example: not in a Git repository, missing `CODEOWNERS`, invalid arguments).
155
209
156
-
### Common CI commands
210
+
- Exit code `0`: all matched files are covered by `CODEOWNERS`, and no enabled validation policy failed
211
+
- Exit code `1`: at least one enforced policy failed, including uncovered files and any enabled `--fail-on-*` validation rule
212
+
- Exit code `2`: runtime or setup error, for example not being in a git repository, missing `CODEOWNERS`, or invalid arguments
213
+
214
+
### Common CI Commands
157
215
158
216
Validate all tracked files:
159
217
@@ -179,64 +237,34 @@ Validate and write reports into an artifact directory:
179
237
codeowners-audit --output-dir artifacts
180
238
```
181
239
182
-
Validate only a subset (for example spec files):
240
+
Validate only a subset, for example spec files:
183
241
184
242
```bash
185
243
codeowners-audit --glob "**/*.spec.js"
186
244
```
187
245
188
-
Validate multiple subsets in one run (combined as a union):
The report follows practical `CODEOWNERS` resolution behavior:
204
-
205
-
- A file is considered **owned** if at least one owner is resolved.
206
-
- When `--validate-github-owners` is enabled, `@username` and `@org/team` owners only count if GitHub confirms they exist and have write access to the repository.
207
-
- The ownership explorer surfaces the resolved owners for each matched file, including email owners.
208
-
- Within a single `CODEOWNERS` file, the **last matching rule wins**.
209
-
- A pattern line with no owners acts as an ownerless override only when it is the last matching rule for a path, matching GitHub's documented behavior.
210
-
- GitHub only considers `CODEOWNERS` at `.github/CODEOWNERS`, `CODEOWNERS`, and `docs/CODEOWNERS`, using the first file found in that order.
211
-
- Patterns are always resolved from the repository root, regardless of which supported `CODEOWNERS` location is active.
212
-
- Extra `CODEOWNERS` files in supported locations and any `CODEOWNERS` files outside those locations are reported as ignored by GitHub.
213
-
- Directory rules match descendant files whether they are written as `/path/to/dir` or `/path/to/dir/`.
214
-
- Use `--fail-on-missing-directory-slashes` if you want CI to enforce the explicit `/path/to/dir/` form as a readability and consistency convention.
215
-
- GitHub-invalid `CODEOWNERS` syntax is skipped, including negation patterns (`!pattern`), escaped leading `#` patterns such as `\#file`, and bracket expressions such as `[ab]` or `[a-z]`.
255
+
- Follows GitHub `CODEOWNERS` discovery order: `.github/CODEOWNERS`, `CODEOWNERS`, then `docs/CODEOWNERS`
256
+
- Uses standard last-match-wins behavior, including ownerless overrides when the last matching rule has no owners
257
+
- Resolves patterns from the repository root, regardless of which supported `CODEOWNERS` location is active
258
+
- Optionally validates `@username` and `@org/team` owners against GitHub with `--validate-github-owners`
259
+
- Reports extra or ignored `CODEOWNERS` files, missing paths, fragile coverage, and unsupported syntax that GitHub would not honor
216
260
217
261
## Requirements
218
262
219
263
- `git`available on `PATH`
220
264
221
-
## Upload size note
222
-
223
-
ZenBin 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.
224
-
225
-
## Report contents
226
-
227
-
The generated page includes:
228
-
229
-
- repository-level ownership metrics and coverage bar
230
-
- scoped directory table with coverage bars
231
-
- searchable list of unowned files
232
-
- ownership explorer for filtering files by resolved CODEOWNERS owner, including `@org/team`, `@username`, and email owners
233
-
- active `CODEOWNERS` file and rule count
234
-
- warnings for extra or unsupported `CODEOWNERS` files that GitHub will ignore
235
-
- warnings for CODEOWNERS patterns that match no repository paths
236
-
- warnings for slashless directory entries that do not follow the explicit trailing-slash style
237
-
- warnings for directories with fragile coverage (owned through individual file rules only)
265
+
## Upload Size Note
238
266
239
-
The report is self-contained, so it can be opened directly from disk or shared after upload.
267
+
zenbin 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.
0 commit comments