pre-commit.ci: Hosted Autofix and Autoupdate
pre-commit.ci is a hosted service that runs your hooks on pull requests, pushes autofixes, and bumps hook revs on a schedule.
Rather than wiring pre-commit into your own CI, pre-commit.ci runs the same config as a managed app. The ci block in your config tunes its behavior.
What it does
pre-commit.ci runs pre-commit run --all-files on each pull request using your .pre-commit-config.yaml. When a fixer modifies files it can commit those fixes back to the branch, and on a schedule it opens autoupdate pull requests. The ci: top-level block controls these features.
Common usage
ci:
autofix_prs: true
autofix_commit_msg: "style: pre-commit fixes"
autoupdate_schedule: weekly
skip: [mypy] # hooks to skip on pre-commit.cici keys
| Key | What it does |
|---|---|
| autofix_prs | Commit hook fixes back to the pull request |
| autofix_commit_msg | Message used for autofix commits |
| autoupdate_schedule | How often to open autoupdate PRs (weekly, monthly) |
| skip | Hook ids to skip on pre-commit.ci (e.g. those needing network) |
| submodules | Whether to clone submodules |
In CI
pre-commit.ci runs without network access for hooks by design, so any hook that downloads at run time must be listed under ci: skip and run elsewhere. It already caches hook environments for you, so you do not manage ~/.cache/pre-commit yourself. The same config also works with self-hosted CI, so you are not locked in.
Common errors in CI
A hook that passes locally but errors on pre-commit.ci with a network or DNS failure needs to be added to ci: skip, since the service blocks network for reproducibility. "autofix" commits that loop usually mean a non-idempotent fixer that never reaches a stable state. If autoupdate PRs stop, the autoupdate_schedule may be unset or the app lacks repo permissions.