# PipeChecker
> **Catch CI/CD pipeline errors before you push β not after CI fails.**
[](https://github.com/Ayyankhan101/PipeChecker/actions/workflows/ci.yml)
[](https://crates.io/crates/pipechecker)
[](LICENSE-MIT)
[]()
[](Cargo.toml)
---
## What Problem Does This Solve?
Every developer has been here:
```
π You push a small change β CI fails 10 minutes later β
you fix it β push again β CI fails again β repeat 3 more times
```
**PipeChecker runs locally** and validates your CI/CD workflows **before** you commit, so you catch:
| β **Circular dependencies** | Job A β Job B β Job A |
| β **Missing job references** | `needs: [build]` but no `build` job exists |
| β **Empty pipelines** | No jobs or steps defined |
| β οΈ **Hardcoded secrets** | `API_KEY=sk_live_abc123` in env vars |
| β οΈ **Undeclared env vars** | `${{ env.UNKNOWN }}` never defined |
| β οΈ **Unpinned actions** | `uses: actions/checkout` without `@v4` |
| β οΈ **Docker `:latest` tags** | `image: nginx:latest` (unreproducible builds) |
| β οΈ **Missing job timeouts** | No `timeout-minutes` set β jobs can run forever |
---
## Visual Overview
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR WORKFLOW FILE β
β (.github/workflows/ci.yml) β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β PIPECHECKER β
β β
β ββββββββββββββββββ β
β β YAML Parser β β
β β GitHub/GitLab β β
β β CircleCI β β
β βββββββββ¬βββββββββ β
β β β
β βββββββββΌβββββββββ β
β β Auditors β β
β β β β
β β π Syntax β β
β β π DAG/Cycle β β
β β π Secrets β β
β β π³ Docker β β
β β π Pinning β β
β βββββββββ¬βββββββββ β
β β β
ββββββββββββΌββββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
β
PASS β οΈ WARNINGS β ERRORS
No issues Fix before Must fix
found! production before push
```
---
## Documentation
Comprehensive documentation can be found in the [docs/](docs/index.md) folder:
- [Start Here](docs/START_HERE.md)
- [Complete Guide](docs/COMPLETE_GUIDE.md)
- [TUI Guide](docs/TUI_GUIDE.md)
- [Contributing](docs/CONTRIBUTING.md)
---
## Supported Platforms
| **GitHub Actions** | `.github/workflows/*.yml` | β
Full support |
| **GitLab CI** | `.gitlab-ci.yml` | β
Full support |
| **CircleCI** | `.circleci/config.yml` | β
Full support |
---
## Installation
### From crates.io
```bash
cargo install pipechecker
```
### From source
```bash
git clone https://github.com/Ayyankhan101/PipeChecker.git
cd PipeChecker
cargo install --path .
```
### Via npm (once published)
```bash
npm install -g pipechecker
```
---
## GitHub Action
PipeChecker can be used directly in your GitHub workflows:
```yaml
name: CI Pipeline Check
on: [push, pull_request]
jobs:
pipechecker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Ayyankhan101/PipeCheck/actions/pipecheck@v0.2.9
```
### Action Inputs
| `path` | No | `.github/workflows` | Path to workflow file(s) |
| `strict` | No | `false` | Exit with error on warnings |
| `diff` | No | `false` | Check only changed files |
| `diff-branch` | No | `main` | Base branch for diff mode |
---
## Diff Mode
Check only workflow files that changed since a base branch:
```bash
# Check files changed since main
pipechecker --diff --diff-branch main
# Short form
pipechecker -d
```
This uses `git diff --name-only` to find changed workflow files, then checks only those. Faster in monorepos with many workflows.
---
## Quick Start
### 1. Check a single file
```bash
pipechecker .github/workflows/ci.yml
```
### 2. Auto-detect your workflow
```bash
pipechecker
# β Auto-detected: .github/workflows/ci.yml
# Provider: GitHubActions
# 0 errors, 0 warnings
```
### 3. Audit everything
```bash
pipechecker --all
# Checking 3 workflow file(s)...
#
# π .github/workflows/ci.yml
# Provider: GitHubActions
# β
No issues found
#
# π .github/workflows/deploy.yml
# Provider: GitHubActions
# 1 errors, 2 warnings
# β ERROR: Circular dependency detected (job: deploy)
# π‘ Remove one of the dependencies to break the cycle
# β οΈ WARNING: Job 'deploy' has no steps
#
# ββββββββββββββββββββββββββββββββββββββββ
# Total: 1 errors, 2 warnings across 3 files
```
---
## Interactive TUI
PipeChecker includes a **terminal UI** for browsing results across multiple files:
```bash
pipechecker --tui
```
```
ββββββββββββββββββββββββββββββββββββββββββββ
β π Pipecheck - Interactive Mode β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Workflows β
ββΆ β deploy.yml β 2 errors β 1 warnings β
β β
ci.yml β 0 errors β 0 warnings β
β β οΈ lint.yml β 0 errors β 3 warnings β
ββββββββββββββββββββββββββββββββββββββββββββ€
β [β/β] Navigate [Enter] Details [Q] Quitβ
ββββββββββββββββββββββββββββββββββββββββββββ
```
**Keyboard shortcuts:**
| `β` / `k` | Move up |
| `β` / `j` | Move down |
| `Enter` / `Space` | Toggle detail view |
| `q` / `Esc` | Quit |
---
## All CLI Flags
| `FILE` | Path to a specific workflow file |
| `--all`, `-a` | Audit **all** discovered workflow files |
| `--tui` | Launch the interactive terminal UI |
| `--watch`, `-w` | Watch for file changes and re-run audits |
| `--fix` | Auto-fix issues (pin unpinned actions + Docker `:latest` tags) |
| `--install-hook` | Install a git pre-commit hook |
| `--format`, `-f` `<text\|json>` | Output format (default: `text`) |
| `--strict`, `-s` | Treat warnings as errors (exit code 1) |
| `--quiet`, `-q` | Only output errors β suppress warnings and info. Perfect for CI |
| `--verbose` | Show diagnostic info (auditors ran, per-severity counts, discovered files) |
| `--no-pinning` | Skip Docker image and action-pinning checks |
| `--version` | Show version |
| `--help` | Show help |
---
## Output Explained
### Severity Levels
| β | **Error** | Must fix β will break your pipeline |
| β οΈ | **Warning** | Should fix β may cause issues later |
| βΉοΈ | **Info** | Informational β nothing to worry about |
### Example output with details
```
Provider: GitHubActions
2 errors, 1 warnings
β ERROR: Circular dependency detected (job: deploy) [line 42]
π‘ Remove one of the dependencies to break the cycle
β ERROR: Job 'deploy' depends on non-existent job 'build' (job: deploy) [line 45]
π‘ Add a job with id 'build' or remove the dependency
β οΈ WARNING: Job 'lint' has no steps (job: lint) [line 12]
π‘ Add steps to perform work in this job
```
Each issue includes:
- **What** went wrong (clear message)
- **Where** it happened (job name + line number)
- **How** to fix it (actionable suggestion)
---
## JSON Output
Perfect for CI/CD integration or programmatic consumption:
```bash
pipechecker --format json
```
```json
{
"provider": "GitHubActions",
"issues": [
{
"severity": "Error",
"message": "Circular dependency detected: job-a -> job-b -> job-a",
"location": { "line": 42, "column": 3, "job": "deploy" },
"suggestion": "Remove one of the dependencies to break the cycle"
}
],
"summary": "1 errors, 0 warnings"
}
```
---
## Modes of Operation
### π§ Auto-Fix Mode
Automatically pins unpinned GitHub Actions to known versions:
```bash
pipechecker --fix
```
```
π§ Auto-fix mode
β¨ Fixed 2 issue(s) in .github/workflows/ci.yml:
actions/checkout β actions/checkout@v4
actions/setup-node β actions/setup-node@v4
π‘ Review the changes and commit them!
```
### π Watch Mode
Monitors workflow files and re-runs on every save β perfect for development:
```bash
pipechecker --watch
```
```
π Watching for workflow changes...
Press Ctrl+C to stop
π File changed: .github/workflows/ci.yml
Provider: GitHubActions
0 errors, 0 warnings
β
All checks passed
```
### π€« Quiet Mode (CI-Friendly)
Only output errors β suppress warnings and info. Perfect for CI pipelines where you want clean output:
```bash
pipechecker --quiet
# or
pipechecker -q
```
```
β Circular dependency detected (job: deploy) (in .github/workflows/deploy.yml)
```
Exit code is still `1` if there are errors β works perfectly with `--strict` for failing CI on any issue.
### π’ Verbose Mode
See exactly what PipeChecker is doing β which files it found, which auditors ran, and per-severity breakdowns:
```bash
pipechecker --verbose
```
```
π Auditing: .github/workflows/ci.yml
π Auditors ran: syntax, dag, secrets, pinning
π Found: 0 errors, 1 warnings, 0 info
β±οΈ Checked in 3.2ms
```
### β±οΈ Timing Metrics
Every audit now shows how long it took β because speed matters:
```bash
pipechecker .github/workflows/ci.yml
```
```
Provider: GitHubActions
0 errors, 0 warnings
β
All checks passed
β±οΈ Checked in 2.1ms
```
### π Pre-commit Hook
Never commit a broken workflow again:
```bash
pipechecker --install-hook
```
```
β
Pre-commit hook installed!
Pipecheck will run before every commit
Use 'git commit --no-verify' to skip
```
The hook automatically validates any workflow files you stage:
```bash
$ git commit -m "Update CI pipeline"
π Checking workflows with pipechecker...
β ERROR: Circular dependency detected (job: deploy) [line 42]
π‘ Remove one of the dependencies to break the cycle
β Workflow validation failed!
Fix errors above or use 'git commit --no-verify' to skip
```
---
## Configuration File
Create a `.pipecheckerrc.yml` in your project root to customize behavior:
```yaml
# Files to skip (glob patterns supported)
ignore:
- .github/workflows/experimental-*.yml
- .github/workflows/draft-*.yml
- old-pipeline.yml
# Toggle individual audit rules
rules:
circular_dependencies: true # Detect dependency cycles
missing_secrets: true # Flag hardcoded secrets
docker_latest_tag: true # Warn about :latest tags
```
PipeChecker searches for config in this order:
1. `.pipecheckerrc.yml`
2. `.pipecheckerrc.yaml`
3. `.pipechecker.yml`
---
## How the Auditors Work
### π Syntax Auditor
Validates the structural integrity of your pipeline:
- β
Jobs are defined
- β
Steps exist within jobs
- β
No duplicate job IDs
- β
`needs` / `depends_on` targets exist
### π DAG Auditor (Cycle Detection)
Builds a **dependency graph** of your jobs and runs **Tarjan's Strongly Connected Components** algorithm:
```
job-a ββdependsβββΆ job-b
β² β
β βΌ
βββββdependsββββ job-c
```
β β **Circular dependency detected:** job-a β job-b β job-c β job-a
### π Secrets Auditor
Scans for security issues in environment variables and run blocks:
```yaml
env:
API_KEY: sk_live_abc123 # β οΈ Hardcoded secret
TOKEN: ${{ secrets.TOKEN }} # β
Correct way
RUN: echo ${{ secrets.API_KEY }} # βΉοΈ Info β ensure it's configured
RUN: echo ${{ env.UNDEFINED }} # β οΈ Undeclared env var
```
Detects:
- Hardcoded API keys, passwords, tokens
- Secret references in `with:` blocks
- Undeclared `${{ env.X }}` references
- Suspicious values (long alphanumeric strings, base64)
### π³ Docker & π Pinning Auditor
Ensures reproducible builds:
```yaml
uses: actions/checkout # β οΈ No version pin
uses: actions/checkout@v4 # β
Pinned
image: nginx:latest # β οΈ Unpredictable
image: nginx:1.25-alpine # β
Specific
```
---
## Real-World Examples
### Example 1: Valid workflow
```bash
$ pipechecker .github/workflows/ci.yml
Provider: GitHubActions
0 errors, 0 warnings
```
### Example 2: Circular dependency
```yaml
jobs:
deploy:
needs: [test]
steps: [{ run: echo deploy }]
test:
needs: [deploy]
steps: [{ run: echo test }]
```
```bash
$ pipechecker broken.yml
Provider: GitHubActions
1 errors, 0 warnings
β ERROR: Circular dependency detected (job: deploy)
π‘ Remove one of the dependencies to break the cycle
```
### Example 3: Hardcoded secrets
```yaml
jobs:
build:
env:
API_SECRET: sk_live_hardcoded_value
steps: [{ run: echo building }]
```
```bash
$ pipechecker secrets.yml
Provider: GitHubActions
0 errors, 1 warnings
β οΈ WARNING: Job 'build' env 'API_SECRET' may contain a hardcoded secret
π‘ Use secrets.API_SECRET instead of hardcoding
```
---
## Architecture
```
pipechecker/
βββ src/
β βββ main.rs # CLI entry point (clap)
β βββ lib.rs # Public API β audit_file, audit_content, discover_workflows
β βββ models.rs # Core types β Pipeline, Job, Step, Issue, Severity
β βββ error.rs # Error enum (thiserror)
β βββ config.rs # .pipecheckerrc.yml loading
β βββ fix.rs # Auto-fix for action pinning
β βββ tui.rs # Interactive terminal UI (ratatui + crossterm)
β βββ parsers/
β β βββ mod.rs # Provider detection + dispatch
β β βββ github.rs # GitHub Actions YAML parser
β β βββ gitlab.rs # GitLab CI YAML parser
β β βββ circleci.rs # CircleCI YAML parser
β βββ auditors/
β βββ mod.rs # Module gate
β βββ syntax.rs # Structural validation
β βββ dag.rs # Dependency graph + cycle detection (petgraph)
β βββ secrets.rs # Secret/env var scanning (regex)
β βββ pinning.rs # Action/Docker image pinning
βββ tests/
β βββ parser_test.rs # Parser integration tests
β βββ auditors_test.rs # Auditor + fixture tests
βββ tests/fixtures/ # Sample workflow files for testing
```
---
## CI/CD Integration
Add PipeChecker to your own CI pipeline:
```yaml
- name: Validate workflows
run: |
cargo install pipechecker
pipechecker --all --strict --format json
```
Or use it as a pre-commit hook (recommended):
```bash
pipechecker --install-hook
```
---
## Development
### Run tests
```bash
cargo test
# 103 tests β all passing
```
### Lint & format
```bash
cargo clippy -- -D warnings
cargo fmt -- --check
```
### Coverage
```bash
cargo tarpaulin --fail-under 55
```
---
## License
This project is licensed under either **MIT** or **Apache-2.0** at your option.
```
SPDX: MIT OR Apache-2.0
```
---
<div align="center">
**PipeChecker** β *because waiting 10 minutes for CI to tell you about a typo is nobody's idea of fun.*
[Report a bug](https://github.com/Ayyankhan101/PipeCheck/issues) Β· [Request a feature](https://github.com/Ayyankhan101/PipeCheck/issues) Β· [Contributing](docs/CONTRIBUTING.md)
</div>