Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

CODEOWNERS Guard

CODEOWNERS Guard

Fast, GitHub-native validation for the CODEOWNERS file that GitHub will actually use.

CI CodeQL Release build Latest release Downloads License Node.js 24 or newer GitHub Action runtime: Node.js 24 Platforms: Windows, Linux, and macOS

Last commit on main Open issues

CODEOWNERS Guard combines GitHub's own diagnostics with local repository checks. It runs as a native Node.js action, so it works on Linux, macOS, and Windows without pulling a container image.

Why Guard

  • GitHub is the syntax authority. Diagnostics come from the same CODEOWNERS API that evaluates the selected branch, tag, or commit.
  • Local checks cover the gaps. Duplicate patterns, rules that match no tracked file, and files without an effective owner are reported separately.
  • Action-first feedback. Findings become file annotations and a job summary, with counts exposed as workflow outputs.
  • No container startup. The Action runs directly on Node.js 24 on Linux, macOS, and Windows runners.
  • Useful outside Actions. The same core ships as a cross-platform CLI with deterministic text and JSON output.

Feature Comparison

The closest tools overlap, but they optimize for different workflows. This table compares documented behavior in fixed releases rather than treating every difference as an advantage.

Capability CODEOWNERS Guard 0.1.2 codeowners-validator 0.7.4 codeowners-audit 2.9.0
Delivery Native Node.js 24 Action and npm CLI Docker Action and Go CLI npm CLI and CI command
Syntax approach GitHub CODEOWNERS errors API at a selected ref Built-in syntax checker Local GitHub-parity checks
Duplicate patterns Built in (duplicates) Built in (duppatterns) Not documented
Dangling or missing patterns Built in (dangling) Built in (files) Opt-in (--fail-on-missing-paths)
Unowned tracked files Built in (unowned) Experimental (notowned) Built in for non-interactive CI
Separate owner and team lookup Uses GitHub diagnostics; no extra lookup Built in (owners) Opt-in (--validate-github-owners)
GitHub Actions feedback File annotations, job summary, and outputs Docker Action Run the CLI in a workflow
Interactive HTML coverage report Not included Not documented Built in
Team suggestions from Git history Not included Not documented Opt-in (--suggest-teams)

The comparison reflects the linked release documentation checked on 2026-09-04. "Not documented" means the capability is not described there, not that it is impossible. Review each project's current documentation before choosing a tool.

Checks

Check What it reports Severity
syntax Errors returned by GitHub's CODEOWNERS API for the selected ref Error
duplicates A pattern that appears more than once Warning
dangling A pattern that matches no tracked file Warning
unowned A tracked file with no effective owner, including files cleared by an ownerless rule Warning

Rules use GitHub's last-match-wins behavior. CODEOWNERS Guard searches the standard locations in GitHub's order: .github/CODEOWNERS, CODEOWNERS, then docs/CODEOWNERS.

When the syntax check is disabled, local checks assume the remaining CODEOWNERS lines are valid. Keep syntax enabled in the Action, or validate the committed ref with GitHub before relying on local-only coverage results.

See the check reference for exact matching, exclusion, and result-limit behavior.

GitHub Action

name: CODEOWNERS

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
      - uses: rarepops/[email protected]
        with:
          checks: syntax,duplicates,dangling,unowned
          exclude: |
            dist/
            coverage/

For the strongest supply-chain pinning, replace v0.1.2 with its full commit SHA. A complete least-privilege workflow is available in examples/codeowners.yml.

Released tags are exercised from the independent public integration repository.

The action adds file annotations and a job summary. Its default token is ${{ github.token }}, and the workflow only needs contents: read.

The Action takes its API endpoint from GitHub's runner environment. It does not accept an endpoint input that could redirect the automatically supplied token. GitHub Enterprise Server runners provide their own trusted GITHUB_API_URL.

Inputs

Input Default Description
github-token ${{ github.token }} Token used for GitHub diagnostics
path . Repository path relative to GITHUB_WORKSPACE
codeowners auto-detect Explicit CODEOWNERS path for local checks; with syntax, it must select GitHub's effective file
checks all checks Comma-separated checks
exclude none Newline-separated gitignore patterns omitted from local checks
repository ${{ github.repository }} Repository in owner/name form
ref ${{ github.sha }} Branch, tag, or commit used by the syntax check
fail-on warning Failure threshold: warning or error
max-annotations 50 Maximum workflow annotations and summary rows, up to 100

Annotation limits do not change validation counts or failure behavior.

Outputs

The action returns valid, issue-count, error-count, and warning-count.

CLI

Run the published CLI without installing it globally:

npx --yes [email protected] . --checks duplicates,dangling,unowned

Use codeowners-guard@latest instead when you explicitly want the newest release. Pinning a version keeps local and CI runs reproducible.

Build and run the CLI locally:

npm ci
npm run build
node dist/cli.js .

Without --checks, the CLI runs duplicates, dangling, and unowned. The syntax check is opt-in because it requires a GitHub repository and may require authentication.

Local checks require no network access:

node dist/cli.js . \
  --checks duplicates,dangling,unowned \
  --exclude dist/ \
  --format json

GitHub's syntax check validates a committed branch, tag, or SHA:

GITHUB_TOKEN=ghp_example node dist/cli.js . \
  --checks syntax,duplicates,dangling,unowned \
  --repository owner/repository \
  --ref main

Tokens are accepted only through GITHUB_TOKEN or GH_TOKEN; command-line token arguments are deliberately unsupported so credentials do not enter shell history or process listings.

GitHub's syntax endpoint always validates the effective CODEOWNERS file at the selected ref. When --codeowners is combined with syntax, the explicit path must resolve to the same effective file in the checkout.

Use --max-issues to retain up to 10,000 issue details in text or JSON output. The default is 1,000. Use --fail-on error to report local warnings without returning a failing exit status. Exit code 1 means validation failed, and exit code 2 means the command could not run.

See troubleshooting for authentication, ref mismatch, missing file, and exit-code guidance.

Design

GitHub remains the authority for syntax diagnostics. Local checks operate on files returned by git ls-files, use a maintained gitignore-compatible matcher, and do not make separate user or team lookup calls. This keeps the Action small and avoids maintaining a second copy of GitHub's owner-resolution behavior.

The syntax check targets ref, while local checks target the checked-out working tree. In normal Actions usage both refer to the same commit. For uncommitted local changes, run local checks only or push the change to a ref before requesting GitHub diagnostics.

Security

  • GitHub workflow dependencies are pinned to immutable commit SHAs, and repository settings require SHA-pinned Actions.
  • API calls require HTTPS, reject redirects, time out after 15 seconds, cap responses at 1 MiB, and retry only bounded transient failures.
  • Action paths and CODEOWNERS files cannot escape the checked-out workspace through traversal or symbolic links.
  • Terminal text, workflow annotations, and HTML summaries escape control and bidirectional characters.
  • Dependency installation disables lifecycle scripts; CI checks advisories, registry signatures, and dependency diffs.
  • Tagged release artifacts include SHA-256 checksums and GitHub build-provenance attestations.

Performance

  • Tracked paths stream from git ls-files -z, avoiding a fixed child-process output buffer.
  • GitHub diagnostics and tracked-file enumeration run concurrently.
  • Each file is normalized once and evaluated against ownership rules in one pass, while duplicate-only checks skip Git entirely.
  • Finding details are retained within configured bounds while exact counts and failure behavior cover every finding.
  • npm run bench measures a 10,000-rule duplicate workload and a 10,000-file by 100-rule ownership workload.

Development

Requires Node.js 24 or newer.

npm ci
npm run check
npm run bench

npm run check includes linting, strict type checking, tests with coverage thresholds, and a production build. dist/ is committed because GitHub executes JavaScript actions directly from the repository. CI rejects source changes that do not include rebuilt bundles and third-party notices.

License

CODEOWNERS Guard is source-available under the PolyForm Perimeter License 1.0.1. The license permits use, modification, and redistribution, but does not permit using the software to provide a competing product. Review the license terms before adopting or redistributing the project.

Licenses for packages embedded in the distributed bundles are reproduced in THIRD_PARTY_NOTICES.md.

Copyright (c) 2026 Rares (rarepops).

About

GitHub-native CODEOWNERS validation: authoritative diagnostics, duplicate and dangling rules, and unowned tracked files. Node 24 Action and CLI.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages