Skip to main content

ciparity

English · Русский · 简体中文 · Español · Português

PyPI Python CI License

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 .

ciparity demo

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.
  • --fix only 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-whitespace are 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 --fix or --all-files are 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)

Source distribution for ciparity 0.3.1
File Size Uploaded
ciparity-0.3.1.tar.gz 114.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ciparity 0.3.1
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page