PipeChecker
Catch CI/CD pipeline errors before you push β not after CI fails.
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:
| Catches | Example |
|---|---|
| β 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 |
| β οΈ Missing permissions | No permissions: block β inherits write-all token |
| β οΈ Missing concurrency cancel | Concurrency group without cancel-in-progress |
| β οΈ Static cache keys | actions/cache without hashFiles(...) |
| βΉοΈ Missing retention-days | actions/upload-artifact with default 90-day retention |
Visual Overview
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR WORKFLOW FILE β
β (.github/workflows/ci.yml) β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β PIPECHECKER β
β β
β ββββββββββββββββββ β
β β YAML Parser β β
β β GitHub/GitLab β β
β β CircleCI β β
β βββββββββ¬βββββββββ β
β β β
β βββββββββΌβββββββββ β
β β Auditors β β
β β β β
β β π Syntax β β
β β π DAG/Cycle β β
β β π Secrets β β
β β β±οΈ Timeout β β
β β π Permissionsβ β
β β π Schema β β
β β π Concurrencyβ β
β β π¦ Artifacts β β
β β π³ Docker β β
β β π Pinning β β
β βββββββββ¬βββββββββ β
β β β
ββββββββββββΌββββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
β
PASS β οΈ WARNINGS β ERRORS
No issues Fix before Must fix
found! production before push
Documentation
Comprehensive documentation can be found in the docs/ folder:
Supported Platforms
| Platform | File Pattern | Status |
|---|---|---|
| GitHub Actions | .github/workflows/*.yml |
β Full support |
| GitLab CI | .gitlab-ci.yml |
β Full support |
| CircleCI | .circleci/config.yml |
β Full support |
Installation
From crates.io
From source
Via npm (once published)
GitHub Action
PipeChecker can be used directly in your GitHub workflows:
name: CI Pipeline Check
on:
jobs:
pipechecker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Ayyankhan101/PipeCheck/actions/pipecheck@v0.3.0
Action Inputs
| Input | Required | Default | Description |
|---|---|---|---|
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:
# Check files changed since main
# Short form
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
2. Auto-detect your workflow
# β Auto-detected: .github/workflows/ci.yml
# Provider: GitHubActions
# 0 errors, 0 warnings
3. Audit everything
# 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:
ββββββββββββββββββββββββββββββββββββββββββββ
β π 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:
| Key | Action |
|---|---|
β / k |
Move up |
β / j |
Move down |
Enter / Space |
Toggle detail view |
q / Esc |
Quit |
All CLI Flags
| Flag | Description |
|---|---|
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) |
--init |
Initialize a new workflow from a template |
--template |
Template name: node, rust, docker, gitlab-node |
--force |
Force overwrite existing files (with --init) |
--install-hook |
Install a git pre-commit hook |
--diff, -d |
Check only files changed since base branch |
--diff-branch |
Base branch for diff mode (default: main) |
--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 |
--ci |
CI mode β implies --quiet --strict --format json |
--verbose |
Show diagnostic info (auditors ran, per-severity counts) |
--explain |
Print detailed explanation for a rule code (e.g. PC005) |
--no-pinning |
Skip Docker image and action-pinning checks |
--no-permissions |
Skip permissions auditor (GitHub Actions only) |
--no-schema |
Skip schema validation |
--version |
Show version |
--help |
Show help |
Output Explained
Severity Levels
| Symbol | Level | Meaning |
|---|---|---|
| β | 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) [PC005] [line 42]
π‘ Remove one of the dependencies to break the cycle
β ERROR: Job 'deploy' depends on non-existent job 'build' (job: deploy) [PC004] [line 45]
π‘ Add a job with id 'build' or remove the dependency
β οΈ WARNING: Job 'lint' has no steps (job: lint) [PC003] [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:
Modes of Operation
π§ Auto-Fix Mode
Automatically pins unpinned GitHub Actions to known versions:
π§ 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:
π 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:
# or
β 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.
π€ CI Mode
One flag that implies --quiet --strict --format json. Ideal for CI automation:
π Explain Mode
Get a detailed explanation for any rule code:
π Rule PC005 β Circular dependency detected
Two or more jobs form a dependency cycle (A needs B, B needs A).
The pipeline can never start because each job is waiting for another.
Remove one of the edges in the cycle to break it.
Available rule codes:
| Code | Rule |
|---|---|
PC001 |
Empty pipeline |
PC002 |
Duplicate job ID |
PC003 |
Empty job steps |
PC004 |
Missing dependency |
PC005 |
Circular dependency |
PC006 |
Hardcoded secret |
PC007 |
Secret reference |
PC008 |
Undeclared env var |
PC009 |
Unpinned action |
PC010 |
Docker :latest tag |
PC011 |
Missing timeout |
PC012 |
Missing trigger |
PC013 |
Missing runs-on |
PC014 |
Missing permissions |
PC015 |
Invalid YAML |
PC016 |
Missing concurrency cancel |
PC017 |
Static cache key |
PC018 |
Missing artifact retention |
π’ Verbose Mode
See exactly what PipeChecker is doing β which files it found, which auditors ran, and per-severity breakdowns:
π Auditing: .github/workflows/ci.yml
π Auditors ran: syntax, dag, secrets, timeout, permissions, schema, concurrency, artifacts, 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:
Provider: GitHubActions
0 errors, 0 warnings
β
All checks passed
β±οΈ Checked in 2.1ms
π Pre-commit Hook
Never commit a broken workflow again:
β
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:
)
Configuration File
Create a .pipecheckerrc.yml in your project root to customize behavior:
# 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
timeout_validation: true # Warn about missing timeouts
permissions_check: true # Warn about missing permissions
schema_validation: true # Structural YAML validation
concurrency_validation: true # Check cancel-in-progress
artifacts_check: true # Cache/artifact best practices
PipeChecker searches for config in this order:
.pipecheckerrc.yml.pipecheckerrc.yaml.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_ontargets 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:
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:
uses: actions/checkout # β οΈ No version pin
uses: actions/checkout@v4 # β
Pinned
image: nginx:latest # β οΈ Unpredictable
image: nginx:1.25-alpine # β
Specific
β±οΈ Timeout Auditor
Warns when jobs lack timeout-minutes β prevents runaway CI jobs:
build:
runs-on: ubuntu-latest
# β οΈ No timeout-minutes β can run forever if something hangs
steps:
π Permissions Auditor
Warns when GitHub Actions jobs have no explicit permissions: block:
build:
runs-on: ubuntu-latest
# β οΈ No permissions block β inherits write-all token
steps:
π Schema Auditor
Validates YAML structure against provider-specific schemas β catches missing keys, bad types, and structural issues.
π Concurrency Auditor
Checks for cancel-in-progress: true when concurrency groups are used β prevents wasted CI minutes on outdated runs.
π¦ Artifacts & Cache Auditor
Checks actions/cache for static keys (should include hashFiles(...)) and actions/upload-artifact for missing retention-days.
Real-World Examples
Example 1: Valid workflow
Example 2: Circular dependency
jobs:
deploy:
needs:
steps:
test:
needs:
steps:
)
Example 3: Hardcoded secrets
jobs:
build:
env:
API_SECRET: sk_live_hardcoded_value
steps:
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, rule codes
β βββ 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 (PC001βPC004)
β βββ dag.rs # Dependency graph + cycle detection (PC005)
β βββ secrets.rs # Secret/env var scanning (PC006βPC008)
β βββ timeout.rs # Missing timeout detection (PC011)
β βββ permissions.rs # GitHub Actions permissions (PC014)
β βββ schema.rs # Structural YAML validation (PC012βPC013, PC015)
β βββ concurrency.rs # Concurrency group checks (PC016)
β βββ artifacts.rs # Cache/artifact best practices (PC017βPC018)
β βββ include.rs # GitLab include: block parsing
β βββ pinning.rs # Action/Docker image pinning (PC009βPC010)
βββ templates/ # Embedded workflow templates
βββ 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:
# Option 1: Use the GitHub Action
- uses: Ayyankhan101/PipeCheck/actions/pipecheck@v0.3.0
# Option 2: Run directly
- name: Validate workflows
run: |
cargo install pipechecker
pipechecker --ci
Or use it as a pre-commit hook (recommended):
Development
Run tests
# 134 tests β all passing
Lint & format
Coverage
License
This project is licensed under either MIT or Apache-2.0 at your option.
SPDX: MIT OR Apache-2.0
PipeChecker β because waiting 10 minutes for CI to tell you about a typo is nobody's idea of fun.