CI/CD Integration
How to integrate Prune into automated pipelines using exit codes, GitHub Actions, and streaming output.
Prune is designed for use in CI/CD pipelines. It respects exit codes for pipeline gating, supports machine-readable output formats, and can stream findings incrementally for large codebases.
Exit Code Behavior
By default, prune scan exits with code 0 regardless of findings. This is suitable for report-only mode, where you want findings logged but do not want to block a build.
To make Prune fail the pipeline when findings are detected, pass --fail-on-findings:
prune scan --fail-on-findingsIf any findings pass the --min-confidence filter, Prune exits with code 1 and prints an error message to stderr:
Error: found 3 findingsCombine --fail-on-findings with --min-confidence to control the severity threshold that blocks the build:
# Fail only if there are safe (high-confidence) dead code findings
prune scan --fail-on-findings --min-confidence safe
# Fail on safe or likely_dead findings
prune scan --fail-on-findings --min-confidence likely_deadGitHub Actions
Basic setup (build from source)
name: Code Quality
on:
push:
pull_request:
jobs:
dead-code:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Install Prune
run: go install github.com/carlosedujs/prune/cmd/prune@latest
- name: Run dead code analysis
run: prune scan --fail-on-findingsUsing a pre-built binary
Download a specific release binary to avoid requiring Go in the CI image:
- name: Install Prune
run: |
curl -L https://github.com/carlosedujs/prune/releases/latest/download/prune_Linux_x86_64.tar.gz | tar xz
mv prune /usr/local/bin/pruneReport-only mode (no build failure)
To run Prune and log findings without blocking the pipeline:
- name: Run dead code analysis (report only)
run: prune scan --format json | tee findings.json
continue-on-error: true
- name: Upload findings
uses: actions/upload-artifact@v4
with:
name: dead-code-findings
path: findings.jsonUsing JSON Output for Post-Processing
In CI, JSON or NDJSON output is more useful than the table format for downstream tools:
// [!code ++]
# Count total safe findings (updated for new JSON structure)
prune scan --format json | jq '.findings | map(select(.confidence == "safe")) | length'
# List all orphaned files
prune scan --format json | jq '.findings[] | select(.kind == "unused_file") | .file'
# Fail if more than 10 safe findings
COUNT=$(prune scan --format json | jq '.findings | map(select(.confidence == "safe")) | length')
if [ "$COUNT" -gt 10 ]; then
echo "Too many dead code findings: $COUNT"
exit 1
fiThe new JSON format wraps findings in a root object with summary and metadata. Update any jq filters to access .findings first.
// [!code --]
// [!code highlight]
# Count total safe findings
prune scan --format json | jq 'map(select(.confidence == "safe")) | length'
# List all orphaned files
prune scan --format json | jq '.[] | select(.kind == "unused_file") | .file'
# Fail if more than 10 safe findings
COUNT=$(prune scan --format json | jq 'map(select(.confidence == "safe")) | length')
if [ "$COUNT" -gt 10 ]; then
echo "Too many dead code findings: $COUNT"
exit 1
fi// [!code focus]
Streaming for Large Codebases
For large projects, --stream with NDJSON output allows results to appear in CI logs before the full scan completes:
prune scan --stream --format ndjsonEach finding is printed to stdout as it is discovered. This is useful when the full scan takes several seconds and you want early visibility in logs.
Streaming mode processes files in batches of up to 50, emitted every --stream-interval milliseconds (default: 250ms). Results from streaming mode may appear in a different order than standard mode.
Recommended Pipeline Configuration
A production configuration for a TypeScript project using Prune in CI:
prune.yaml:
version: 2
project:
name: my-app
language: js-ts
ts_config:
enabled: true
baseUrl: .
paths:
"@/*":
- src/*
"~/*":
- src/components/*
scan:
paths:
- src
include:
- '**/*.ts'
- '**/*.tsx'
exclude:
- node_modules/**
- dist/**
- .next/**
- '**/*.test.ts'
- '**/*.spec.ts'
entrypoints:
files:
- src/index.ts
patterns:
- src/pages/**
rules:
unused_function:
enabled: true
unused_variable:
enabled: true
unused_export:
enabled: true
unused_file:
enabled: true
dead_feature_flag:
enabled: false
suspicious_dynamic_usage:
enabled: true
report:
format: table
min_confidence: safeGitHub Actions step:
- name: Analyze dead code
run: prune scan --config prune.yaml --fail-on-findings --min-confidence safeThis configuration excludes test files from the scan, disables the feature flag rule (not applicable to all projects), and fails the build on any high-confidence dead code finding.