ciparity
English · Русский · 简体中文 · Español · Português
Your hooks passed. CI failed anyway. The two configs drifted apart: someone bumped ruff in
.pre-commit-config.yaml and not in the workflow, someone added mypy --strict to CI only,
someone added a hook CI never runs. The worse case is quieter: both sides green while a check
stopped running months ago.
ciparity reads .pre-commit-config.yaml and your CI pipeline, GitHub Actions or GitLab CI, and
prints where they disagree, then fixes the version drift for you. Static parsing only: no
network, no Docker, no API keys, and it never runs your tools.
pip install ciparity
ciparity .
The recording above is generated from real runs by scripts/demo_gif.py, so it cannot drift
away from what the tool actually prints.
--fix edits .pre-commit-config.yaml as text, so comments, quotes and key order survive. It
moves hooks onto the version CI already uses, because CI is the version every reviewer sees.
Use --fix --dry-run to see the diff and write nothing.
Exit code is 1 when there are differences, so it works as a check.
What it looks for
| Check | Example |
|---|---|
| Tool in one side only | vulture is a hook, no CI job runs it |
| Version drift | hook rev: v0.5.0 against pip install ruff==0.6.2, fixable |
| Argument drift | --strict passed in CI but not in the hook |
| Python version | default_language_version: python3.11 while CI sets up only 3.12 |
| Node version | default_language_version: node 20.11.0 while CI sets up 22 |
| Narrower in CI | CI runs pre-commit run without --all-files, so it only sees the diff |
Versions are read from hook rev:, from pip install tool==x, uv tool install, pipx install,
npm i -g tool@x, and from the version: input of known actions such as astral-sh/ruff-action.
Commands are found in workflow run: blocks and in GitLab script: blocks, including behind
uv run, uvx, poetry run, npx and python -m.
Supported CI
| Provider | Read from | Runtime versions from |
|---|---|---|
| GitHub Actions | .github/workflows/*.yml |
setup-python, setup-node |
| GitLab CI | .gitlab-ci.yml, plus include: local: files |
the job image:, python:3.12-slim |
Both are parsed when both exist, and a repository that pins different versions in different pipelines gets reported instead of silently fixed.
Usage
ciparity [path] [--fix [--dry-run]] [--json] [--ignore pytest,codespell] [--exit-zero]
As a pre-commit hook:
repos:
- repo: https://github.com/Topicspot/ciparity
rev: v0.3.1
hooks:
- id: ciparity
In GitHub Actions, as a step in the workflow you already have:
- uses: Topicspot/ciparity@v0.3.1
with:
path: .
args: --ignore codespell
The action installs the published package and runs it, so the job fails when the two sides drift
apart. version: pins a release; leaving it empty installs the latest one.
Deliberate non-goals and limits
- Only GitHub Actions and GitLab CI are parsed. Other systems are a new module in
ciparity/ci/, and pull requests are welcome. --fixonly edits.pre-commit-config.yaml. It never rewrites your pipelines.- GitLab
include:is followed for local files only. Remote and template includes are reported as a blind spot rather than ignored quietly. - Only tools it recognises are compared. File hygiene hooks like
trailing-whitespaceare ignored on purpose, nobody runs those in CI and reporting them would be noise. - If a CI job runs
pre-commit run --all-files, the two sides are parity by definition and "missing in CI" findings are suppressed. - Composite actions and reusable workflows are not followed, so tools that only run inside them are invisible.
- Flags such as
--fixor--all-filesare treated as mode flags and never reported.
Alternatives
- pre-commit.ci runs your hooks as a service, which removes the drift instead of reporting it. If you can use it, use it.
- act runs workflows locally, so you can see what CI does. It answers a different question and is much heavier.
- zizmor and actionlint lint the workflow files themselves. They do not know your pre-commit config.
License
MIT
☕ Support the author
This project is free and MIT-licensed. If it saved you time, you can send a coffee.
USDT, Tron network (TRC-20) only:
TS9ywGeSyKQxiCszdKCHLR8DRAsnYCosNN
Другие языки / Other languages
- Українська: проєкт безкоштовний. Якщо він заощадив вам час — можна підтримати автора, USDT у мережі Tron (TRC-20), адреса вище.
- Русский: проект бесплатный. Если он сэкономил вам время, можно поддержать автора, USDT в сети Tron (TRC-20), адрес выше.
Release files for ciparity 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ciparity-0.3.1.tar.gz | 114.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ciparity-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 135.2 kB
Release files / ciparity-0.3.1.tar.gz
| Download URL | ciparity-0.3.1.tar.gz |
|---|---|
| Size | 114.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e9fa13da3214ca44447f1a4dbdd090e531607c9cb6ec7136d76f219a77d3b29e
|
|
BLAKE2b-256 checksum How to use checksums |
646a72f620c7561ff5df20a2c7cb3a1bb7dec9a9e6da3ecb0edb94a840643bbc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 1, 2026.
Transparency logRelease files / ciparity-0.3.1-py3-none-any.whl
| Download URL | ciparity-0.3.1-py3-none-any.whl |
|---|---|
| Size | 20.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2cc949bcb80e5e05b0595bfab0ab729808bbc758639d6632feb84eaec0e16c55
|
|
BLAKE2b-256 checksum How to use checksums |
3748b68b5f289b997039a692a2437b367704536c197806e8ea1cd7799755e7a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 1, 2026.
Transparency log