Async CLI that audits Python repositories on GitHub for engineering quality and explains every finding.
Project description
repo-auditor
Async CLI that audits Python repositories on GitHub for engineering quality — tests, CI, typing, packaging, docs and security — and explains every finding.
Problem
Judging whether a Python repository is well engineered is manual and inconsistent. Everyone looks at the same things — is there a README? are there tests? is CI running? is the package installable? is a secret committed? — but without explicit criteria the verdict changes with who is looking and on which day.
Existing badges and services hand back a number without saying how they reached it, which
makes the number useless for acting on. Here, a score without a justification is a
bug: the report is a list of findings, each with the evidence behind it and a concrete
recommendation. The number is only a summary of that list. The exact method is public in
docs/scoring.md.
Features
- Audit a single repository or every public repository of a user
- Eight dimensions: security, documentation, testing, CI/CD, static quality, packaging, activity and community
- Every finding carries evidence and, when not OK, an actionable recommendation
- Bounded concurrency, proactive rate-limit handling, retry with exponential backoff
- Local SQLite cache with TTL and conditional (ETag) revalidation — a warm cache is nearly free
- Text, JSON and Markdown output; severity-based exit codes for CI use
- Never executes the audited repository's code; a detected secret is reported by file and type, never by value
Requirements
- Python 3.11+
- Optionally a
GITHUB_TOKEN— without one the GitHub API allows 60 requests/hour instead of 5000, which caps a single run at roughly 14 repositories and prints a warning
Installation
uv tool install gh-repo-auditor # or: pipx install gh-repo-auditor
repo-auditor --help
The distribution is published as gh-repo-auditor, but the command it installs is
repo-auditor. The prefix exists because PyPI rejects repo-auditor as too similar to the
unrelated project RepoAuditor; it also states
what is audited — GitHub repositories.
For local development:
uv sync
uv run repo-auditor --help
Usage
export GITHUB_TOKEN=... # optional but recommended
repo-auditor audit psf/requests # audit one repository
repo-auditor audit-user octocat # audit all of a user's public repos
repo-auditor compare psf/requests urllib3/urllib3
repo-auditor audit psf/requests --json # stable JSON (see docs)
repo-auditor audit psf/requests --markdown --output report.md
repo-auditor rules # show active dimensions and weights
repo-auditor cache clear
Real output, auditing this author's own ubuntu-doctor (the tool applied to its own
portfolio):
david-oliveira-dev/ubuntu-doctor score 92.5 INFO
[INFO] activity.has_release: no published release was found
→ Tag a release so users can depend on a specific version.
[INFO] community.security_policy: no SECURITY.md was found
→ Add a SECURITY.md describing how to report vulnerabilities.
[OK] security.no_secret_patterns: no content matching a known secret pattern was found
[OK] documentation.readme_substance: README has 6736 characters and 18 headings
[OK] testing.suite_present: found 18 test file(s), e.g. tests/integration/test_cli.py
[OK] ci.runs_lint_and_tests: a workflow runs both linting and tests
[OK] packaging.src_layout: the package uses a src/ layout
...
Exit codes
| Code | Meaning |
|---|---|
| 0 | clean — no critical finding |
| 1 | a critical finding (e.g. a committed secret) |
| 2 | usage error (bad reference, repository not found) |
| 3 | API/network error |
This makes repo-auditor usable as a CI gate: fail the build if a critical finding
appears.
JSON contract
--json emits a versioned, stable schema (schema_version). It is the tool's public
contract — field names and nesting change only with a version bump. See
docs/scoring.md for what each field means.
Configuration
| Variable | Required | Purpose |
|---|---|---|
GITHUB_TOKEN |
No | Raises the API limit from 60 to 5000 requests/hour |
XDG_CACHE_HOME |
No | Overrides where the SQLite cache is stored |
The token is read only from the environment. It is never accepted as a command-line
argument, never logged, and never written to the cache. See .env.example.
Testing
make check # ruff + mypy (strict) + pytest with coverage
Every test runs offline. HTTP is exercised with respx against sanitised fixtures of real
API responses; rules are exercised against hand-built snapshots. Minimum coverage: 85%.
Design decisions
docs/architecture.md— the layers and the collect/evaluate boundary, with a diagramdocs/scoring.md— the public scoring methoddocs/api-budget.md— measured API limits, the endpoints used, and the cost of an audit- Architecture decision records in
docs/adr/: snapshot separates collection from evaluation, UNKNOWN never penalizes, SQLite cache over an external service
Limitations
Stated up front, because a quality tool that overstates its reach is its own counter-example:
- Does not analyse source code — no AST, no complexity metrics
- Does not run the audited repository's tests, and never executes its code
- GitHub only; Python repositories only
- Community and activity signals are heuristics, not measurements
- Secret detection reports a pattern compatible with a secret, never a certainty — and never prints the value it matched
Roadmap
v1.1 adds audit history over time; v1.2 user-defined rules; v2.0 would require abstracting the provider layer to support GitLab.
Contributing
Issues and pull requests are welcome. Please read the PR template first.
License
MIT — see LICENSE.
Contact
David Oliveira — davidoliveira.devbr@gmail.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gh_repo_auditor-1.0.0.tar.gz.
File metadata
- Download URL: gh_repo_auditor-1.0.0.tar.gz
- Upload date:
- Size: 132.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c09cd650e9116ae937158ed3bd049902860a9e1f54888c9d39ad9ec8c9502aab
|
|
| MD5 |
1e3bafb6b11c3b3adb33d62847237f99
|
|
| BLAKE2b-256 |
78e15d8f869997a753aade50211acea52b07455ddfa6284d9f2ac563f71fa339
|
Provenance
The following attestation bundles were made for gh_repo_auditor-1.0.0.tar.gz:
Publisher:
release.yml on david-oliveira-dev/repo-auditor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gh_repo_auditor-1.0.0.tar.gz -
Subject digest:
c09cd650e9116ae937158ed3bd049902860a9e1f54888c9d39ad9ec8c9502aab - Sigstore transparency entry: 2274779469
- Sigstore integration time:
-
Permalink:
david-oliveira-dev/repo-auditor@daf5e9e7e6c26df12f6474c4491c7c3e717d8e53 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/david-oliveira-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@daf5e9e7e6c26df12f6474c4491c7c3e717d8e53 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gh_repo_auditor-1.0.0-py3-none-any.whl.
File metadata
- Download URL: gh_repo_auditor-1.0.0-py3-none-any.whl
- Upload date:
- Size: 47.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66643a4626e64e1312e9dfcbf3cce6cf37d73252c1234c4009a11c173bb5bf58
|
|
| MD5 |
fb0eb6d98ff2608b55dd845661dcff7e
|
|
| BLAKE2b-256 |
dac2a97b27ce6faacba215729eb2ebce873008ddb7cadb821826779ff39c5461
|
Provenance
The following attestation bundles were made for gh_repo_auditor-1.0.0-py3-none-any.whl:
Publisher:
release.yml on david-oliveira-dev/repo-auditor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gh_repo_auditor-1.0.0-py3-none-any.whl -
Subject digest:
66643a4626e64e1312e9dfcbf3cce6cf37d73252c1234c4009a11c173bb5bf58 - Sigstore transparency entry: 2274779524
- Sigstore integration time:
-
Permalink:
david-oliveira-dev/repo-auditor@daf5e9e7e6c26df12f6474c4491c7c3e717d8e53 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/david-oliveira-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@daf5e9e7e6c26df12f6474c4491c7c3e717d8e53 -
Trigger Event:
push
-
Statement type: