Skip to main content

Diagnose CI failures instantly — extract signal lines and explain them in plain English

Project description

ci-why

Your CI failed. 400 lines of logs. This tells you why in seconds.

PyPI version Python License: MIT Downloads

ci-why terminal screenshot

CI logs are noisy. A failed GitHub Actions run gives you hundreds of lines of downloading, copying, grouping, and progress output — and somewhere buried in it is the 3 lines that actually matter.

ci-why strips the noise, extracts the signal lines with context, and optionally asks Claude to explain the root cause and give you concrete fix steps.

No CI platform lock-in. Works on any log you can pipe or point at a file.


Install

pip install ci-why

Or with pipx (recommended for CLI tools — keeps it isolated):

pipx install ci-why

Usage

# From a log file
ci-why build.log

# Pipe directly from GitHub CLI
gh run view --log | ci-why -

# Pattern analysis only — no API call
ci-why build.log --no-ai

# Just the raw extracted failure lines (great for piping)
ci-why build.log --raw

# More context lines around each failure
ci-why build.log --context 5

# Scan only the last N lines (for huge logs)
ci-why build.log --max-lines 10000

AI explanation

Set your Anthropic API key to get plain-English root cause analysis and fix steps:

export ANTHROPIC_API_KEY=sk-ant-...
ci-why build.log

Without the key, ci-why still works — it shows the extracted failure lines using pattern matching only. The AI explanation is additive, not required.


What it recognises

ci-why detects failure signals across Python, Node, Go, Rust, and generic CI output:

Signal Examples
Test failures FAIL, AssertionError, Jest , pytest FAILED
Errors & tracebacks Traceback (most recent call last), panic:, fatal error
Exit codes Process completed with exit code 1
Missing modules ModuleNotFoundError, Cannot find module
Build errors Build failed, SyntaxError, compilation error
Dependency errors npm ERR!, yarn error, pip error, ERESOLVE
Network / timeout Connection refused, ECONNREFUSED, timed out
Lint / type errors ESLint, mypy, ruff, TypeScript TS2345:
Permission errors Permission denied, EACCES

Noise filtered out: download progress, [debug] lines, file copy progress, GHA group markers, already-installed notices.


All options

Arguments:
  SOURCE        CI log file path, or '-' to read from stdin.

Options:
  --no-ai       Skip AI explanation; show pattern matches only.
  --raw         Print extracted failure lines as plain text and exit.
  -c, --context Lines of context around each failure (default: 2, max: 10).
  --max-lines   Truncate log to this many lines before scanning (default: 50000).
  --help        Show this message and exit.

Examples

GitHub Actions log via CLI:

gh run view 1234567890 --log | ci-why -

GitLab CI — download job log and analyse:

curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.com/api/v4/projects/123/jobs/456/trace" | ci-why -

Save just the failure lines to a file:

ci-why build.log --raw > failures.txt

Use in a script — exit code reflects whether failures were found:

ci-why build.log --no-ai --raw || echo "Failures detected"

Development

git clone https://github.com/gitwingo/ci-why
cd ci-why
pip install -e .

Support

If sniff-schema has been useful to you, consider supporting its development:

Buy Me a Ko-Fi

Connect


Made with 💖 by Gitwingo

License

MIT © gitwingo

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

ci_why-0.1.1.tar.gz (101.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ci_why-0.1.1-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

Details for the file ci_why-0.1.1.tar.gz.

File metadata

  • Download URL: ci_why-0.1.1.tar.gz
  • Upload date:
  • Size: 101.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ci_why-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6c243fedd2e61eadfcaddbd977471e0a4c45bc10031119bc49b4ce716d8ba3bd
MD5 3e2d1c81aa4634b3c461875d38fc3007
BLAKE2b-256 76b128e90436681a187f46c99664d3347c182ed262ba4fd4f91f93997609dd3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ci_why-0.1.1.tar.gz:

Publisher: publish.yml on gitwingo/ci-why

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ci_why-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: ci_why-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ci_why-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 328a707c8edf569230f08f2727a51967693bb63bd9f0e03843f2064ca9d0440d
MD5 66aab0aaa2e07c647323301fedf696ee
BLAKE2b-256 bf3ce63efbe34be50189840c8fbbf1a6be2cff2167109ddc8c2efc5bd5c6168e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ci_why-0.1.1-py3-none-any.whl:

Publisher: publish.yml on gitwingo/ci-why

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page