PHPackages                             itzmekhokan/pressready - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. itzmekhokan/pressready

ActivePhpcodesniffer-standard[Testing &amp; Quality](/categories/testing)

itzmekhokan/pressready
======================

Is your WordPress site ready for the next PHP or WordPress version? Scan the whole installed stack and find out before you upgrade.

v1.6.0(3w ago)227↓88.9%[1 issues](https://github.com/itzmekhokan/pressready/issues)GPL-2.0-or-laterPHPPHP &gt;=7.4CI passing

Since Jun 2Pushed 3w agoCompare

[ Source](https://github.com/itzmekhokan/pressready)[ Packagist](https://packagist.org/packages/itzmekhokan/pressready)[ RSS](/packages/itzmekhokan-pressready/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (10)Dependencies (5)Versions (31)Used By (0)

Pressready
==========

[](#pressready)

[![CI](https://github.com/itzmekhokan/pressready/actions/workflows/ci.yml/badge.svg)](https://github.com/itzmekhokan/pressready/actions/workflows/ci.yml)[![Latest version](https://camo.githubusercontent.com/4fce7382eb7788cc644e8ace2a122d6c2d756409fb4450f85c75f6a1e5568d20/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f69747a6d656b686f6b616e2f707265737372656164792e737667)](https://packagist.org/packages/itzmekhokan/pressready)[![License: GPL v2+](https://camo.githubusercontent.com/26f8b6541ea045cc1dbc2267208158b5a7ebbf5cf437c4b486d80fee9386f77e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d47504c2d2d322e302d2d6f722d2d6c617465722d626c75652e737667)](LICENSE)

> **Is your WordPress site ready for the next PHP or WordPress version?**Scan the whole installed stack — every plugin, theme, and mu-plugin, not just your own code — and find out exactly what breaks *before* you upgrade.

`vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content` runs static analysis across every component and returns a verdict grouped by plugin/theme, with `file:line` and a clear severity for every finding.

**[→ Full documentation](https://itzmekhokan.github.io/pressready/)**

---

Contents
--------

[](#contents)

- [Severity model](#severity-model)
- [Install](#install)
- [Quick start](#quick-start)
- [All options](#all-options)
- [Output formats](#output-formats)
- [Compatibility matrix](#compatibility-matrix)
- [Large stacks &amp; performance](#large-stacks--performance)
- [Config file](#config-file)
- [WP-CLI](#wp-cli)
- [GitHub Actions / CI](#github-actions--ci)
- [Run anywhere with Docker](#run-anywhere-with-docker)
- [GitLab CI](#gitlab-ci)
- [Other CI systems](#other-ci-systems)
- [Use the ruleset in your editor](#use-the-ruleset-in-your-editor)
- [Pre-commit hook (optional)](#pre-commit-hook-optional)
- [Baseline (legacy sites)](#baseline-legacy-sites)
- [Exit codes](#exit-codes)
- [Per-finding suppression](#per-finding-suppression)
- [Roadmap](#roadmap)

---

Severity model
--------------

[](#severity-model)

LevelMeaningEngine`fatal`A symbol **removed** by the target version — PHP symbol gone, or a WordPress core API removed by the target WP version → white screen / undefined-symbol fatal on upgradePHPCompatibility · Pressready sniff`risky`Behavioural change that still runs but may produce wrong resultsPHPCompatibility`php`PHP feature deprecated (not yet removed)PHPCompatibility`wp`WordPress core API deprecated (but still shimmed) by the target WP versionPressready sniffUnder the hood Pressready runs two engines in a single PHPCS pass: [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) for the PHP axis, and a custom sniff driven by an authoritative WP deprecations dataset for the WordPress axis.

The WP dataset records the WordPress version it was generated from. If `--wp` targets a newer release than the dataset, Pressready prints a warning to stderr (WP-side results may be incomplete — regenerate the dataset) rather than imply a clean bill of health. Point a run at a custom or newer dataset with the `PRESSREADY_DATASET=/path/to/wp-deprecations.json` environment variable.

---

Install
-------

[](#install)

### Standalone PHAR (no Composer)

[](#standalone-phar-no-composer)

The quickest way to run Pressready anywhere — CI, a server, or a project you don't want to add a dev dependency to. The `.phar` is a single self-contained file that bundles the whole PHPCS toolchain, so there's nothing to `composer install` and **no chance of clashing with a project's own pinned `squizlabs/php_codesniffer`**.

```
curl -L https://github.com/itzmekhokan/pressready/releases/latest/download/pressready.phar -o pressready.phar
chmod +x pressready.phar
./pressready.phar --php=8.4 --wp=6.9 --path=wp-content
```

On first run it extracts its bundled toolchain to a cache dir; subsequent runs reuse it. Every flag works exactly as the Composer-installed CLI.

> Building from source: `php -d phar.readonly=0 bin/build-phar.php` (after `composer install`) writes `build/pressready.phar`.

### Homebrew (macOS / Linux)

[](#homebrew-macos--linux)

```
brew tap itzmekhokan/pressready
brew install pressready

pressready --php=8.4 --wp=6.9 --path=wp-content
```

The formula installs the released `.phar` and runs it with a Homebrew-managed `php` (pulled in as a dependency), so there's nothing else to set up. Upgrade with `brew upgrade pressready`.

### Composer

[](#composer)

Pressready installs in two tiers depending on how new a PHP version you need to target.

### Default — no config (PHP ≤ 8.1)

[](#default--no-config-php--81)

The standard install needs **no stability config**. It pulls the stable PHPCompatibility engine, which detects everything up to **PHP 8.1** plus the full WordPress deprecations axis:

```
composer require --dev itzmekhokan/pressready
```

This works under a normal `"minimum-stability": "stable"` project. Most sites can stop here.

### Targeting PHP 8.2–8.4 — opt in to the pre-release engine

[](#targeting-php-8284--opt-in-to-the-pre-release-engine)

PHP 8.2–8.4 detection needs `PHPCompatibility 10`, which only ships as a pre-release. Allow dev stability **and** request the pre-release engine explicitly (Composer prefers stable otherwise, so you must name it):

```
composer config minimum-stability dev
composer config prefer-stable true
composer config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer config --no-plugins allow-plugins.phpcsstandards/phpcsutils true
composer require --dev itzmekhokan/pressready phpcompatibility/phpcompatibility-wp:3.0.0-alpha2
```

Equivalent `composer.json`:

```
{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "require-dev": {
        "itzmekhokan/pressready": "*",
        "phpcompatibility/phpcompatibility-wp": "3.0.0-alpha2"
    },
    "config": {
        "allow-plugins": {
            "dealerdirect/phpcodesniffer-composer-installer": true,
            "phpcsstandards/phpcsutils": true
        }
    }
}
```

### Global install — scan many sites from one place

[](#global-install--scan-many-sites-from-one-place)

Prefer one shared install for ad-hoc scans across all your local sites? Install it globally. Configure global Composer once (the dev-stability lines are only needed for PHP 8.2–8.4 — drop them if you only target PHP ≤ 8.1):

```
# Configure global Composer once
composer global config minimum-stability dev
composer global config prefer-stable true
composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer global config --no-plugins allow-plugins.phpcsstandards/phpcsutils true

# Install globally (drop the explicit engine pin if you only target PHP ≤ 8.1)
composer global require itzmekhokan/pressready phpcompatibility/phpcompatibility-wp:3.0.0-alpha2

# Put the global bin on your PATH (zsh; use ~/.bashrc for bash)
echo 'export PATH="$PATH:$(composer global config home)/vendor/bin"' >> ~/.zshrc && source ~/.zshrc
```

Then scan any site from anywhere by pointing `--path` at its `wp-content`:

```
pressready --php=8.2 --path=/path/to/site/wp-content

# Sweep every project under a dev root
for proj in */ ; do
  echo "===== $proj ====="
  pressready --php=8.2 --path="$proj/wp-content" --format=summary
done
```

Global is ideal for a developer's local sweeps across many sites. For **CI and team reproducibility**, still use `composer require --dev` per project so the engine version is pinned in each `composer.lock`.

### Verify the standards registered

[](#verify-the-standards-registered)

```
vendor/bin/phpcs -i   # should list "Pressready" and "PHPCompatibilityWP"
```

Requires PHP 7.4+.

---

Quick start
-----------

[](#quick-start)

```
# The headline question: will PHP 8.4 + WP 6.9 break this site, and where?
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content

# PHP axis only — every removal and deprecation by PHP 8.4.
vendor/bin/pressready --php=8.4 --path=wp-content

# WordPress axis only — every core API deprecated by WP 6.9.
vendor/bin/pressready --wp=6.9 --path=wp-content

# Delta: only what newly breaks upgrading FROM 6.4 TO 6.9.
vendor/bin/pressready --wp=6.9 --since=6.4 --path=wp-content

# Scan a single plugin or theme.
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content/plugins/woocommerce

# Scan just your own code (theme + brand mu-plugins), skipping third-party plugins.
vendor/bin/pressready --php=8.4 --wp=6.9 \
  --path=wp-content/themes/acme --path=wp-content/mu-plugins/acme

# PHP upgrade path — everything that breaks across 8.1 → 8.4.
vendor/bin/pressready --php=8.1-8.4 --path=wp-content
```

On a large `wp-content` the report leads with a **fix-first block** — every `fatal` then every `risky` finding with a clickable `path:line` — so upgrade blockers aren't buried under the deprecation tail. Key output behaviours:

- **Deprecations hidden by default** — the report shows fatals and risky findings inline; each component header still carries its deprecation count, and `--all` lists the full deprecation tail when you're ready to clear it
- **Duplicate collapse** — identical findings show once as `(×N)` with a line list (disable with `--no-collapse`)
- **Colour-coded severities** — red fatal, yellow risky, cyan deprecation (auto-off when piped)
- **Live progress spinner** — shown on a TTY, suppressed in CI and pipes

---

All options
-----------

[](#all-options)

FlagDescription`--php=`Target PHP version or range, e.g. `8.4` or `8.1-8.4``--wp=`Target WordPress version, e.g. `6.9``--since=`With `--wp`: show only what newly deprecates upgrading from this version`--path=`Path to scan (default: cwd). **Repeatable** — pass `--path` more than once, or a comma list, to scan several targets in one pass`--format=`Output format — see [Output formats](#output-formats)`--matrix`Grade the requested target span and report the **highest fatal-free version and the first break** — see [Compatibility matrix](#compatibility-matrix)`--fail-on=`Exit non-zero when findings at/above this level exist: `fatal` · `risky` · `deprecated``--ignore-on=`Hide findings at/below this level (the inverse of `--fail-on`): `fatal` · `risky` · `deprecated``--parallel[=N]`phpcs worker count. **ON by default** (auto CPU cores). `--parallel=1` disables`--cache[=]`Cache results so re-scans only reprocess changed files`--no-cache`Force a fresh scan even when `--cache` is set`--ignore=`Extra comma-separated path patterns to skip`--no-default-ignore`Disable built-in ignores (`vendor`, `node_modules`, `build`, `dist`, `*.min.php`, `tests`, `*.blade.php`)`-h`, `--help`Print the usage / flag reference and exit`-V`, `--version`Print the version and exit (resolves the installed release, or `git describe` in a dev checkout)`--only=`Show only components whose name matches this substring`--top=N`Show only the N worst components (most fatals first)`--no-collapse`Show one line per finding instead of collapsing duplicates`--all`List every deprecation inline. By default the deprecation tail is hidden so fatals/risky stay scannable (`--verbose` is an alias)`--baseline[=]`Suppress findings present in the baseline snapshot`--generate-baseline[=]`Snapshot current findings to a baseline file and exit`--config=`Load defaults from a JSON config file (CLI flags always win)---

Output formats
--------------

[](#output-formats)

FormatUse case`grouped`**Default.** Human-readable, grouped by component with fix-first block and colours`table`WP-CLI-style `+--+--+` ASCII table, one row per (collapsed) finding`summary`One line per component — counts only, no per-file detail`json`Machine-readable `{tally, components}` — pipe to `jq` or scripts`sarif`SARIF 2.1.0 for code-scanning dashboards (GitHub Advanced Security, etc.)`github`GitHub Actions workflow commands — inline PR annotations`gitlab`GitLab Code Quality report (Code Climate JSON) — inline MR widget annotations```
# Human formats
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content                  # grouped (default)
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=table
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=summary

# Machine formats
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=json
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=sarif > pressready.sarif
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=github
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --format=gitlab > gl-code-quality-report.json
```

---

Compatibility matrix
--------------------

[](#compatibility-matrix)

Instead of asking "does this one target break my site?", `--matrix` answers the question every site owner actually has — **how far can I safely upgrade, and what's the first thing that breaks?** It grades each version in the requested span from a single scan:

```
vendor/bin/pressready --php=7.4-8.4 --matrix --path=wp-content
```

```
  Pressready — compatibility matrix — PHP 7.4–8.4
  Scanned: wp-content

  PHP
    7.4    ✓ clear
    8.0    ✗ 1 fatal
    8.1    ✗ 1 fatal
    8.2    ✗ 1 fatal
    8.3    ✗ 1 fatal
    8.4    ✗ 1 fatal

  ✓ Safe through PHP 7.4.
  ✗ First break: PHP 8.0 (1 fatal).

```

- Pass a **range** (`--php=7.4-8.4`) to grade across it; a single `--php=8.4` grades just that version.
- `--format=json` emits the per-version grid plus `safe_through` / `first_break` for each axis, so CI can consume the ceiling.
- Honours `--fail-on`: a span containing a fatal exits non-zero.
- The WP axis is graded too; it lights up as the dataset gains removal data.

---

Large stacks &amp; performance
------------------------------

[](#large-stacks--performance)

Pressready is built to scan a full enterprise `wp-content` — hundreds of plugins, tens of thousands of files:

FeatureHow it worksMeasured gain**Parallel**phpcs forks workers (auto CPU cores by default)~5× faster on a real stack**Cache**re-scans only reprocess changed files~37× faster on a warm cache**Default ignores**skips `vendor/`, `node_modules/`, `build/`, `dist/`, `*.min.php`, `tests/`removes un-fixable noise automatically**Collapse**identical findings show once as `(×N)`up to 45% fewer output lines```
# Parallel: explicit count or disable
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --parallel=8
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --parallel=1   # serial

# Cache: warm the cache on first run, near-instant on subsequent runs
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --cache

# Focus: top 10 worst components, or a single one by name
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --top=10
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --only=woocommerce

# Add extra ignores on top of the defaults
vendor/bin/pressready --php=8.4 --path=wp-content --ignore='*/cache/*,*/languages/*'

# Hide the deprecation tail — show only fatals and risky changes
vendor/bin/pressready --php=8.4 --wp=6.9 --path=wp-content --ignore-on=deprecated
```

---

Config file
-----------

[](#config-file)

Commit shared defaults to a `.pressready.json` in your project root — CLI flags always override the file.

```
{
    "php": "8.4",
    "wp": "6.9",
    "fail-on": "fatal",
    "paths": ["wp-content/themes/acme", "wp-content/mu-plugins/acme"],
    "ignore": ["*/cache/*", "*/languages/*"],
    "top": 20
}
```

```
vendor/bin/pressready --path=wp-content              # picks up .pressready.json automatically
vendor/bin/pressready --config=ci/pressready.json    # or point at a specific file
```

Recognised keys mirror the flags (use `paths: []` for multiple scan targets). **Unknown keys are reported as a warning** so a typo doesn't silently change your scan scope. CLI flags always override the file — passing any `--path` on the command line replaces the config's `path`/`paths` entirely.

---

WP-CLI
------

[](#wp-cli)

Pressready ships a `wp pressready scan` command — same engine, run from the WordPress root, defaulting to the site's `wp-content`. Runs *before* WordPress boots — no database required.

### Register the command

[](#register-the-command)

Add to your project's `wp-cli.yml`:

```
require:
  - vendor/itzmekhokan/pressready/wp-cli.php
```

Or pass `--require` inline:

```
wp --require=vendor/itzmekhokan/pressready/wp-cli.php pressready scan --php=8.4 --wp=6.9
```

### Usage

[](#usage)

```
wp pressready scan --php=8.4 --wp=6.9
wp pressready scan wp-content/plugins --php=8.4       # specific directory (positional)
wp pressready scan --wp=6.9 --format=json
wp pressready scan --wp=6.9 --since=6.4               # delta scan
wp pressready scan --php=8.4 --wp=6.9 --fail-on=fatal # CI gate
wp pressready scan --php=8.4 --wp=6.9 --top=10        # focus
wp pressready scan --php=7.4-8.4 --matrix             # how far can I upgrade?
```

`--format`: `table` (default) · `summary` · `json` · `csv` · `yaml` · `count`

`--matrix` grades every version in the span and prints the highest fatal-free version + first break per axis (a graded table plus a safe-through/first-break verdict), honouring `--fail-on` for CI.

All standalone CLI flags (`--ignore-on`, `--parallel`, `--cache`, `--ignore`, `--only`, `--top`, `--config`, etc.) work identically with the WP-CLI command.

---

GitHub Actions / CI
-------------------

[](#github-actions--ci)

### Recommended: the `itzmekhokan/pressready@v1` action

[](#recommended-the-itzmekhokanpressreadyv1-action)

The published Docker action bakes Pressready **and** its PHPCS 4.x toolchain into the image, so your repo carries no Composer boilerplate and there is no chance of clashing with a project's own `squizlabs/php_codesniffer ^3.13` pin. A whole CI gate reduces to:

```
- uses: actions/checkout@v4
- uses: itzmekhokan/pressready@v1
  with:
    baseline: .pressready-baseline.json
    fail-on: fatal
    format: github
```

`.pressready.json` and the baseline stay repo-local — they're read from your checkout, so per-repo scope (target PHP/WP + `paths`) is unchanged.

#### Inputs

[](#inputs)

InputDefaultDescription`config``.pressready.json`Path to the config file. Ignored if absent (the CLI auto-discovers `.pressready.json` from the checkout).`baseline`—Path to a baseline file. The gate then fails only on findings **not** in the baseline.`fail-on``fatal`Severity threshold that fails the build: `fatal`, `risky`, or `deprecated`.`format``github`Output format: `github`, `grouped`, `table`, `summary`, `json`, `sarif`.`php`—Override the target PHP version/range (else taken from config), e.g. `8.4` or `8.1-8.4`.`wp`—Override the target WP version (else taken from config), e.g. `6.9`.`working-directory``.`Directory to scan from, relative to the checkout.#### Output

[](#output)

OutputDescription`exit-code`Pressready exit code: `0` clean, `1` findings at/above the threshold, `2` usage/config error.Minimal `.github/workflows/pressready.yml`:

```
name: PressReady
on: [ pull_request ]
permissions:
  contents: read
jobs:
  gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: itzmekhokan/pressready@v1
        with:
          baseline: .pressready-baseline.json
          fail-on: fatal
          format: github
```

> Pin to `@v1` for the moving major tag, or `@v1.0.0` for an immutable release. The image is published to `ghcr.io/itzmekhokan/pressready` and pulled pre-built, so runs don't rebuild it.

### Raw CLI recipes

[](#raw-cli-recipes)

If you'd rather run the binary yourself (e.g. you already install Pressready via Composer in an isolated `tools/` project), these recipes still apply.

#### Inline PR annotations

[](#inline-pr-annotations)

```
- name: Pressready scan
  run: |
    vendor/bin/pressready \
      --php=8.4 --wp=6.9 \
      --path=wp-content \
      --format=github
```

#### Fail the build on fatals

[](#fail-the-build-on-fatals)

```
- name: Pressready scan
  run: |
    vendor/bin/pressready \
      --php=8.4 --wp=6.9 \
      --path=wp-content \
      --fail-on=fatal \
      --cache
```

#### Upload SARIF to GitHub Advanced Security

[](#upload-sarif-to-github-advanced-security)

```
- name: Pressready scan
  run: |
    vendor/bin/pressready \
      --php=8.4 --wp=6.9 \
      --path=wp-content \
      --format=sarif > pressready.sarif

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: pressready.sarif
```

#### Baseline: fail only on new findings

[](#baseline-fail-only-on-new-findings)

```
- name: Pressready scan
  run: |
    vendor/bin/pressready \
      --php=8.4 --wp=6.9 \
      --path=wp-content \
      --baseline \
      --fail-on=fatal \
      --format=github
```

---

Run anywhere with Docker
------------------------

[](#run-anywhere-with-docker)

The published image is **dual-mode**: as a GitHub Action it consumes the action inputs, and anywhere else it passes arguments straight through to the CLI. So the same image is a general-purpose runner — no Composer, no PHP, no toolchain clash:

```
docker run --rm -v "$PWD":/src -w /src ghcr.io/itzmekhokan/pressready:1 \
  --php=8.4 --wp=6.9 --path=wp-content
```

The same multi-arch image is mirrored to **Docker Hub** for environments that can't pull from GHCR — swap the registry prefix, everything else is identical:

```
docker run --rm -v "$PWD":/src -w /src docker.io/itzmekhokan/pressready:1 \
  --php=8.4 --wp=6.9 --path=wp-content
```

---

GitLab CI
---------

[](#gitlab-ci)

`--format=gitlab` emits a [Code Quality](https://docs.gitlab.com/ci/testing/code_quality/) report (Code Climate JSON). Publish it as a `codequality` artifact and GitLab renders every finding inline on the merge request — and in the **Code Quality** MR widget — with no extra tooling:

```
# .gitlab-ci.yml
pressready:
  image: ghcr.io/itzmekhokan/pressready:1
  variables:
    GITHUB_ACTIONS: ""          # force CLI passthrough mode on the dual-mode image
  script:
    - pressready --php=8.4 --wp=6.9 --path=wp-content
        --format=gitlab > gl-code-quality-report.json
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    paths:
      - gl-code-quality-report.json
```

To **fail the pipeline** on fatals (the Code Quality report is informational and never fails the job on its own), run a second gate — the report and the gate share one scan if you cache, or just scan twice:

```
  script:
    - pressready --php=8.4 --wp=6.9 --path=wp-content
        --format=gitlab > gl-code-quality-report.json
    - pressready --php=8.4 --wp=6.9 --path=wp-content --fail-on=fatal
```

---

Other CI systems
----------------

[](#other-ci-systems)

Any runner that can pull a Docker image can gate on Pressready — the dual-mode image is a self-contained CLI (no PHP/Composer on the agent). Two ready recipes:

### Bitbucket Pipelines

[](#bitbucket-pipelines)

```
# bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Pressready
        image: ghcr.io/itzmekhokan/pressready:1
        script:
          - pressready --php=8.4 --wp=6.9 --path=wp-content --fail-on=fatal
```

### Jenkins (declarative pipeline)

[](#jenkins-declarative-pipeline)

```
// Jenkinsfile — runs the gate inside the published image on any agent with Docker.
pipeline {
  agent { docker { image 'ghcr.io/itzmekhokan/pressready:1' } }
  stages {
    stage('Pressready') {
      steps {
        sh 'pressready --php=8.4 --wp=6.9 --path=wp-content --fail-on=fatal'
      }
    }
  }
}
```

Both honour the standard exit codes (`0` clean · `1` findings at/above `--fail-on` · `2` usage/config error), so the step fails the build exactly when the gate trips. Swap the image for `pressready.phar` or `vendor/bin/pressready` on agents that already have PHP.

---

Use the ruleset in your editor
------------------------------

[](#use-the-ruleset-in-your-editor)

Pressready is a phpcs standard, so any phpcs-aware editor can surface findings inline as you type — no separate plugin. Point your editor at the installed binary and the bundled standard:

**VS Code** ([phpcs / “PHP Sniffer” extensions](https://marketplace.visualstudio.com/search?term=phpcs&target=VSCode)) — `.vscode/settings.json`:

```
{
  "phpsab.executablePathCS": "vendor/bin/phpcs",
  "phpsab.standard": "vendor/itzmekhokan/pressready/Pressready/ruleset.xml"
}
```

**PhpStorm** — *Settings → PHP → Quality Tools → PHP\_CodeSniffer*: set the path to `vendor/bin/phpcs`, then under the *PHP\_CodeSniffer* inspection set **Coding standard** to *Custom* and choose `Pressready/ruleset.xml`.

This runs the WordPress-deprecation sniff live. PHP-version findings come from the bundled PHPCompatibility standard — pass the target version with `--runtime-set testVersion 8.4` in the inspection’s *Tool arguments* to grade against a specific PHP. For the full severity model and version gating, keep using the `pressready` CLI / CI gate; the editor integration is for fast feedback while editing.

---

Pre-commit hook (optional)
--------------------------

[](#pre-commit-hook-optional)

Pressready ships a [pre-commit](https://pre-commit.com) hook so a project **can choose** to scan for newly-introduced PHP/WordPress upgrade-readiness issues before each commit. It is entirely **opt-in** — nothing runs until a project adds it to its own `.pre-commit-config.yaml`. Teams that don't want it simply don't add it.

### Adopt it (Docker — no local PHP needed)

[](#adopt-it-docker--no-local-php-needed)

```
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/itzmekhokan/pressready
    rev: v1.6.0
    hooks:
      - id: pressready
        args: [--php=8.4, --wp=6.9, --path=wp-content]
```

```
pre-commit install      # enable the hook in this clone
git commit …            # the scan now runs on commits that touch PHP
```

The hook runs via the published Docker image (the PHPCS toolchain is baked in), so it needs only Docker, which pre-commit manages. Omit `args` and commit a `.pressready.json` instead — it's auto-discovered.

### Or without Docker (use your installed binary)

[](#or-without-docker-use-your-installed-binary)

Prefer no Docker? Wire a local hook to the Composer-installed binary or the PHAR — equally opt-in:

```
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: pressready
        name: Pressready upgrade-readiness scan
        entry: vendor/bin/pressready          # or: ./pressready.phar
        language: system
        files: \.php$
        pass_filenames: false
        args: [--php=8.4, --wp=6.9, --path=wp-content]
```

> Tune `--fail-on` to taste — e.g. `--fail-on=fatal` blocks the commit only on real breakage and lets deprecations through.

---

Baseline (legacy sites)
-----------------------

[](#baseline-legacy-sites)

Adopt Pressready on a site with pre-existing issues without drowning in noise — snapshot today's findings, then fail CI only on *new* ones.

```
# Step 1: snapshot existing findings once.
vendor/bin/pressready --php=8.4 --wp=6.9 --generate-baseline --path=wp-content

# Step 2: from now on, fail only on new findings.
vendor/bin/pressready --php=8.4 --wp=6.9 --baseline --fail-on=fatal --path=wp-content
```

Findings are keyed by `path → signature` (sniff code + message with line numbers neutralised), so the baseline survives line shifts and reordering. Use `--baseline=` / `--generate-baseline=` to store the baseline at a custom path.

Paths are normalised **relative to the directory you run from** (your repo root), so a baseline generated locally matches one generated in CI regardless of whether `--path` was absolute, relative, or scoped to a subdirectory. Run `generate-baseline` and `--baseline` from the same working directory (the repo root) and the keys line up.

---

Exit codes
----------

[](#exit-codes)

CI gates can rely on a stable exit-code contract:

CodeMeaning`0`Clean — no findings, or none at/above the `--fail-on` threshold`1`Findings at/above the `--fail-on` threshold (`fatal` / `risky` / `deprecated`)`2`Usage / config error — bad flag, a `--path` that doesn't exist, or **zero files scanned**Without `--fail-on`, the scan reports findings but exits `0`. Exit `2` is deliberately distinct from `1`: scanning zero files (a misconfigured path or over-broad `--ignore`) fails as a config error rather than passing vacuously, so a broken gate goes red instead of green.

---

Per-finding suppression
-----------------------

[](#per-finding-suppression)

Uses native PHPCS inline comments — no custom syntax to learn:

```
create_function( '$x', 'return $x;' ); // phpcs:ignore
get_postdata( 1 );                      // phpcs:ignore Pressready.WordPress.Deprecated.DeprecatedFunction
```

---

Roadmap
-------

[](#roadmap)

PhaseScopeStatus1WP-deprecations dataset generator + authoritative JSON dataset✅ done2Custom PHPCS sniff + reporter (grouped / summary / json), version gate + delta, exit codes✅ done3`--php=` via bundled PHPCompatibility; unified severity model (fatal / risky / php / wp)✅ done4Per-component attribution, baseline, `--format=github`, inline suppression✅ done5`wp pressready scan` WP-CLI command✅ done6Enterprise scale: parallel, cache, path ignores, duplicate collapsing, `--only`/`--top`, config file, SARIF, PHP ranges, docblock dataset coverage✅ done7Docker GitHub Action (`ghcr.io` image, `@v1`) — one-line CI adoption with the PHPCS toolchain baked into the image✅ done8+DataViews admin report; fix-hint links; WP.org distributionplanned---

Acknowledgements
----------------

[](#acknowledgements)

- [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) — the PHP-version compatibility engine that powers the PHP axis
- [PHP\_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) — the static analysis foundation both engines run on

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance85

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

16

Last Release

26d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/13062380?v=4)[Khokan Sardar](/maintainers/itzmekhokan)[@itzmekhokan](https://github.com/itzmekhokan)

---

Top Contributors

[![itzmekhokan](https://avatars.githubusercontent.com/u/13062380?v=4)](https://github.com/itzmekhokan "itzmekhokan (55 commits)")

---

Tags

clicode-qualitycompatibility-checkercontinuous-integrationdeveloper-toolslinterphpphp8phpcompatibilityphpcsstatic-analysisupdatesupgrade-toolwordpresswordpress-developmentwp-clicompatibilityphpcswordpressstatic analysisupgradephpcompatibilitydeprecations

### Embed Badge

![Health badge](/badges/itzmekhokan-pressready/health.svg)

```
[![Health](https://phpackages.com/badges/itzmekhokan-pressready/health.svg)](https://phpackages.com/packages/itzmekhokan-pressready)
```

###  Alternatives

[wp-coding-standards/wpcs

PHP\_CodeSniffer rules (sniffs) to enforce WordPress coding conventions

2.8k47.8M2.4k](/packages/wp-coding-standards-wpcs)[slevomat/coding-standard

Slevomat Coding Standard for PHP\_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.

1.5k134.0M2.3k](/packages/slevomat-coding-standard)[phpcompatibility/phpcompatibility-wp

A ruleset for PHP\_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.

22234.3M789](/packages/phpcompatibility-phpcompatibility-wp)[wp-cli/wp-cli-tests

WP-CLI testing framework

423.1M143](/packages/wp-cli-wp-cli-tests)[woocommerce/woocommerce-sniffs

WooCommerce sniffs

497.5M55](/packages/woocommerce-woocommerce-sniffs)[yoast/yoastcs

PHP\_CodeSniffer rules for Yoast projects

221.2M34](/packages/yoast-yoastcs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
