https://github.com/raiderrobert/ownrs
Auditing ownership of repos
https://github.com/raiderrobert/ownrs
Last synced: 4 months ago
JSON representation
Auditing ownership of repos
- Host: GitHub
- URL: https://github.com/raiderrobert/ownrs
- Owner: raiderrobert
- License: other
- Created: 2026-02-27T17:37:27.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-03-26T22:42:39.000Z (4 months ago)
- Last Synced: 2026-03-27T05:38:47.823Z (4 months ago)
- Language: Rust
- Homepage:
- Size: 151 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# ownrs
Find out who owns what across your GitHub org.
Reconciles three ownership signals — CODEOWNERS, Backstage `catalog-info.yaml`, and GitHub team permissions — and tells you where they agree, disagree, or have gone stale.
## Install
```bash
curl -sSL https://raw.githubusercontent.com/raiderrobert/ownrs/main/install.sh | sh
```
Or with cargo:
```bash
cargo install --path .
```
Requires a GitHub token with `read:org` and `repo` scopes. If you have the [GitHub CLI](https://cli.github.com) installed and authenticated, ownrs picks up your token automatically. Otherwise:
```bash
export GITHUB_TOKEN=
```
## Quick Start
```bash
# See the full picture for your org
ownrs org my-org --detail
# Which repos does my team own?
ownrs org my-org --team platform
# What's broken? Show stale and mismatched repos
ownrs org my-org --status stale,mismatched --format csv
# Check a single repo
ownrs repo my-org/my-repo
ownrs repo # auto-detects from git remote
# Who might own this orphaned repo? (auto-runs for missing/stale)
ownrs repo my-org/forgotten-service
# Force suggestions for a repo with partial ownership
ownrs repo my-org/my-repo --suggest partial
# Combine modes
ownrs repo my-org/my-repo --suggest missing,stale,partial
```
## What It Checks
ownrs compares three sources for each repo:
- **CODEOWNERS** — who reviews PRs (`* @org/team-name`)
- **catalog-info.yaml** — who's listed in the Backstage service catalog (`spec.owner`)
- **GitHub admin teams** — which teams actually have admin access to the repo
By default, if there's any team that appears across all present sources, the repo is **aligned**. Use `--strict` to require all sources to list the exact same teams.
## Alignment States
| Status | What it means |
|--------|--------------|
| `aligned` | Sources agree (at least one team in common) |
| `mismatched` | Sources present but no team overlap |
| `catalog-only` | Only `catalog-info.yaml` declares ownership |
| `codeowners-only` | Only `CODEOWNERS` declares ownership |
| `admin-only` | Team has admin access but no metadata files |
| `stale` | A referenced team no longer exists in the org |
| `missing` | No ownership signal at all |
## Ownership Suggestions
When a repo has no ownership metadata (`missing`) or references a team that no longer exists (`stale`), ownrs automatically suggests likely owners based on recent commit and PR review activity.
It works by resolving contributors to their org teams and ranking teams by total activity:
```
Repository: forgotten-service
Status: missing
Suggested owners (based on last 90 days of activity):
platform-team 12 commits, 4 reviews (alice, bob)
infra-team 3 commits, 1 review (charlie)
```
Use `--suggest` to override which statuses trigger suggestions:
| Mode | Triggers for |
|------|-------------|
| (default) | `missing` and `stale` |
| `--suggest missing` | `missing` only |
| `--suggest stale` | `stale` only |
| `--suggest mismatched` | `mismatched` (sources present, no team overlap) |
| `--suggest partial` | `catalog-only`, `codeowners-only`, `admin-only` |
Org-wide teams are filtered out by default (teams with >20 members). Tune with `--max-team-size` or `--exclude-team`.
## Options
```
Global:
--refresh Force re-fetch (bypass 24h cache)
--strict Require exact team set match across sources
--cache-ttl Cache TTL in seconds (default: 86400)
--token GitHub token (default: GITHUB_TOKEN env var)
org subcommand:
--limit Audit only first N repos
--sort stale (default), active, name
--team Filter to repos where this team appears in any source
--status Filter by alignment status (comma-separated)
--format table (default), csv, json
--detail Show per-repo breakdown
repo subcommand:
--status Filter by alignment status
--format table (default), csv, json
Suggestion Options:
--suggest Override suggestion trigger (missing, stale, mismatched, partial)
--lookback-days Activity lookback window (default: 90)
--max-team-size Filter out teams larger than N (default: 20)
--exclude-team Teams to exclude from suggestions (comma-separated)
```
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success (or no repos matched filter) |
| 1 | Filter matched results |
| 2 | Runtime error |
## License
[PolyForm Shield 1.0.0](LICENSE)