/docs/ @my-org/docs.
The trouble is that GitHub quietly ignores lines it does not understand. A typo in a team name, or a pattern GitHub does not support, and nobody is asked to review. The codeowners feature does two things about that:
- Checking: on a pull request that changes CODEOWNERS, it reports every line GitHub rejects or ignores, and every rule that can never apply.
- Generating: it can write owners you list in the smartcloud config into a marked block of the file, so a shared preset can set owners across many repositories.
Turn it on
1
Run smartcloud on pull requests and pushes
Checking needs
pull_request events. Generating runs on push, schedule and workflow_dispatch. The workflow in Getting started has all of them.2
Grant the permissions
Checking needs
checks: write for its check run and pull-requests: write for the report comment it posts or updates when a finding needs action. Generating also pushes a branch and opens a pull request, so it needs contents: write as well.3
Add a codeowners section
An empty section only checks the file you already have:Add
.github/smartcloud.yml
rules to generate owners too (see Options).4
Require the check
To block a pull request that breaks CODEOWNERS, require the
smartcloud / codeowners check in a ruleset, or use the required feature’s single aggregate check.Options
About patterns and keys:
- A rule with no owners leaves its paths without an owner, overriding an earlier rule, as GitHub documents. That is useful for vendored code.
- GitHub does not support
!(negation),[ ](character ranges) or a pattern starting with an escaped\#, so the config rejects them. - Write a space in a path as
\, as indocs/My\ Files/. - A rule’s key must not be a whole number such as
2: such a key is always read first, so its rule would be written before the others.
Complete example
.github/smartcloud.yml
How it works
Checking
On a pull request that changes CODEOWNERS, unlesscheck is false, smartcloud checks the file at the pull request’s head:
GitHub’s own CODEOWNERS errors come first. They need only read access, so they also work for pull requests from forks; when they cannot be read, smartcloud’s own checks still run. A pull request that does not touch CODEOWNERS is not checked, so a problem already on the default branch does not fail unrelated pull requests.
On a schedule, a manual dispatch or a push, the file on the default branch is checked the same way, and its problems are warnings, since no pull request caused them.
Generating
Whenrules has an entry, smartcloud writes them between two markers on a schedule, a manual dispatch or a push, and proposes the result as one pull request from branch, titled chore(codeowners): generate CODEOWNERS from the smartcloud config:
.github/CODEOWNERS
- Everything outside the markers is kept. The first generation adds the block at the end of the file, or just above a block the sync feature manages (
house:managed:begin), which stays last so synced owners always apply. A block found below the synced one is moved above it. - When
pathis set but GitHub reads an existing file before it, such as.github/CODEOWNERSbeforedocs/CODEOWNERS, nothing is generated and acodeowners.generateerror names the file GitHub uses. - Rules are written in the order the config gives them, and later rules win, as they do everywhere in CODEOWNERS. A repository’s own rules come after its presets’ rules.
- When the file is already up to date, nothing is proposed.
- The same pull request is updated on later runs, since the branch is force-updated.
What you will see on GitHub
- Check run:
smartcloud / codeowners. It fails when a problem aterrorlevel is found, isneutralwith only warnings, and passes otherwise. Each problem is an annotation on the CODEOWNERS line it is about. - Report comment: errors and warnings also appear in smartcloud’s single report comment on the pull request.
- Pull request: when generating, one pull request from
smartcloud/codeowners(or yourbranch) into the default branch. Merge it to apply the owners. - Job summary: the problems found, and “Proposed the generated
<path>on<branch>in pull request #N” when it opened or updated one.
Forks and restricted runs
Checking a pull request from a fork works: GitHub’s CODEOWNERS errors need only read access. In a restricted run, writing the check run or report comment may be refused and is then listed under Restricted access in the job summary; the job’s own summary and annotations still show every problem. Generating runs on pushes and schedules, which never come from a fork. A token that cannot push, such as a workflow token withcontents: read, skips the proposal with a codeowners.generate warning rather than failing the run.
Troubleshooting
Error: codeowners.path is docs/CODEOWNERS, but GitHub reads .github/CODEOWNERS first
Error: codeowners.path is docs/CODEOWNERS, but GitHub reads .github/CODEOWNERS first
GitHub uses only the first CODEOWNERS file it finds, in the order
.github/CODEOWNERS, CODEOWNERS,
docs/CODEOWNERS. Delete the earlier file, or set codeowners.path to it. Nothing is generated until you do.The feature fails: codeowners.branch is the default branch
The feature fails: codeowners.branch is the default branch
The proposal branch is force-updated, so it can never be the branch pull requests merge into. Leave
branch unset
or choose another name.Warning: Could not propose the generated CODEOWNERS
Warning: Could not propose the generated CODEOWNERS
The token cannot push or open pull requests. Grant the job
contents: write and pull-requests: write.codeowners.generated: the pull request edits the generated block
codeowners.generated: the pull request edits the generated block
The block between the
smartcloud:codeowners markers is written from the config. Undo the hand edit and change
codeowners.rules instead; smartcloud regenerates the block. To stop generating entirely, remove rules.codeowners.shadowed: a rule never applies
codeowners.shadowed: a rule never applies
Two lines have the same pattern, and the last matching line wins, so the earlier one does nothing. Merge the owners
into one line or remove the earlier one.
An owner is reported as not existing or unable to write
An owner is reported as not existing or unable to write
That comes from GitHub: the user or team does not exist, is misspelled, or has no write access to the repository.
Give the team write access, or fix the name.
A pull request with a broken CODEOWNERS was not checked
A pull request with a broken CODEOWNERS was not checked
Only pull requests that change one of the CODEOWNERS locations are checked. Problems already on the default branch
are reported as warnings on the next push or scheduled run.