Find drift between your pre-commit hooks and your GitHub Actions steps.
Project description
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 .
pre-commit hooks: 5 CI steps: 4 ci: GitHub Actions
mypy arguments differ: different arguments
pre-commit: -
ci: --strict
ruff version differs: pinned to different versions
pre-commit: 0.5.0
ci: 0.6.2
fix: rev v0.5.0 -> v0.6.2
vulture not in pre-commit: runs in CI but is not a pre-commit hook
ci: ci.yml:test
python python differs: pre-commit pins a python version CI never sets up
pre-commit: 3.11
ci: 3.12
4 difference(s).
1 can be fixed automatically: ciparity --fix
$ ciparity --fix
--- .pre-commit-config.yaml
+++ .pre-commit-config.yaml
@@ -2,7 +2,7 @@
python: python3.11
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.5.0
+ rev: v0.6.2
hooks:
- id: ruff
args: [--fix]
https://github.com/astral-sh/ruff-pre-commit: rev v0.5.0 -> v0.6.2
Wrote .pre-commit-config.yaml. 1 fixed, 3 left.
--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.0
hooks:
- id: ciparity
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), адрес выше.
Project details
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 ciparity-0.3.0.tar.gz.
File metadata
- Download URL: ciparity-0.3.0.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6ba3fac0f367a4092873a23589d54e83484b7a7af25cffe4040a8de583dd78f
|
|
| MD5 |
d0b0402764f9c5f517a2e16ace599d6f
|
|
| BLAKE2b-256 |
b5065c00149724c06f8bfab304b6f9284d2f4c7aec8ff2f6a1689a70aab70b01
|
Provenance
The following attestation bundles were made for ciparity-0.3.0.tar.gz:
Publisher:
release.yml on Topicspot/ciparity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ciparity-0.3.0.tar.gz -
Subject digest:
a6ba3fac0f367a4092873a23589d54e83484b7a7af25cffe4040a8de583dd78f - Sigstore transparency entry: 2280478726
- Sigstore integration time:
-
Permalink:
Topicspot/ciparity@dc57c331b876f6399abc652ffe7522055de6e628 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Topicspot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc57c331b876f6399abc652ffe7522055de6e628 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ciparity-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ciparity-0.3.0-py3-none-any.whl
- Upload date:
- Size: 20.7 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 |
9df68431d07d9c9f78f589d716e083c366725b5cd2c91a9b489ecbd841a4b4cd
|
|
| MD5 |
c924a1feb8df6902b35241da1823743f
|
|
| BLAKE2b-256 |
11439aea76505e555ecc5f86e8fc69207508d9a3a90bd61d1812ff7a4b478bf4
|
Provenance
The following attestation bundles were made for ciparity-0.3.0-py3-none-any.whl:
Publisher:
release.yml on Topicspot/ciparity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ciparity-0.3.0-py3-none-any.whl -
Subject digest:
9df68431d07d9c9f78f589d716e083c366725b5cd2c91a9b489ecbd841a4b4cd - Sigstore transparency entry: 2280478780
- Sigstore integration time:
-
Permalink:
Topicspot/ciparity@dc57c331b876f6399abc652ffe7522055de6e628 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Topicspot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc57c331b876f6399abc652ffe7522055de6e628 -
Trigger Event:
push
-
Statement type: