PHPackages                             lts/php-qa-ci - 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. lts/php-qa-ci

ActiveComposer-plugin[Testing &amp; Quality](/categories/testing)

lts/php-qa-ci
=============

Simple PHP QA pipeline and scripts. Largely just a collection of dependencies with configuration and scripts to run them together

03.6k↓33.3%PythonCI failing

Since Feb 4Pushed 1mo agoCompare

[ Source](https://github.com/LongTermSupport/php-qa-ci)[ Packagist](https://packagist.org/packages/lts/php-qa-ci)[ RSS](/packages/lts-php-qa-ci/feed)WikiDiscussions php8.4 Synced 1mo ago

READMEChangelogDependenciesVersions (5)Used By (0)

PHP-QA-CI
=========

[](#php-qa-ci)

A comprehensive quality assurance and continuous integration pipeline for PHP 8.3+ projects, written in Bash. Runs tools in a logical order designed to fail as quickly as possible, suitable for both local development and CI.

This package is written for and tested on Linux.

Install
-------

[](#install)

```
composer require --dev lts/php-qa-ci:dev-php8.4@dev
```

The `qa` script will be installed in your project's bin directory. By default, Composer uses `vendor/bin`, but you can configure a custom location in your `composer.json`:

```
"config": {
    "bin-dir": "bin"
}
```

For Symfony projects, you can accept the prompts to run recipes, but you will then need to decide whether to stick with Symfony defaults or the php-qa-ci defaults (which are more extensive). If you decide to keep the php-qa-ci defaults, remove the config files created by the Symfony recipe:

```
# Revert to php-qa-ci PHPUnit configs (compare files first)
rm phpunit.xml.dist
ln -s vendor/lts/php-qa-ci/configDefaults/generic/phpunit.xml
```

### Required Composer Configuration

[](#required-composer-configuration)

Your project's `composer.json` must allow the required plugins:

```
{
    "config": {
        "allow-plugins": {
            "ergebnis/composer-normalize": true,
            "lts/php-qa-ci": true,
            "phpstan/extension-installer": true
        }
    }
}
```

What It Does
------------

[](#what-it-does)

PHP-QA-CI orchestrates multiple PHP quality tools across four phases:

**Phase 1 -- Code Modification:**

1. Rector (safe functions, PHPUnit, PHP 8.4 upgrades)
2. PHP CS Fixer

**Phase 2 -- Linting and Validation:**3. PSR-4 Validation 4. Composer Checks 5. Strict Types Enforcement 6. PHP Lint 7. Composer Require Checker 8. Markdown Links Checker

**Phase 3 -- Static Analysis:**9. PHPStan (level max)

**Phase 4 -- Testing:**10. PHPUnit 11. Infection (mutation testing, optional, requires Xdebug)

**Post-Success:** PHPLoc (stats only, cannot fail)

See [Pipeline Architecture](./docs/pipeline.md) for full details.

Tool Delivery
-------------

[](#tool-delivery)

PHP-QA-CI uses a hybrid approach to tool delivery:

- **PHARs** (via [PHIVE](https://phar.io/)): PHPStan, PHP CS Fixer, Infection, Composer Require Checker -- delivered in `vendor-phar/`
- **Composer dependencies**: PHPUnit, phpstan-strict-rules, phpstan-phpunit, parallel-lint
- **Isolated Composer project**: Rector -- in `tools/rector/` with its own `composer.json` to prevent dependency conflicts

The `phpstan/phpstan` package is in the `replace` section of `composer.json` since PHPStan is provided via PHAR. This prevents version conflicts when consuming projects also require PHPStan extensions.

Custom PHPStan Rules
--------------------

[](#custom-phpstan-rules)

PHP-QA-CI ships with custom PHPStan rules that are auto-loaded via the PHPStan extension installer:

- **ForbidMockingFinalClassRule** -- Prevents mocking of final classes
- **ForbidAllowMockWithoutExpectationsRule** -- Bans `#[AllowMockObjectsWithoutExpectations]`
- **ForbidDangerousFunctionsRule** -- Bans exec/eval/unserialize and similar
- **ForbidEmptyCatchBlockRule** -- Requires catch blocks to have a body
- **RequireDeclareStrictTypesRule** -- Requires `declare(strict_types=1)` in all PHP files

Projects can add their own rules alongside these defaults.

Quick Setup Scripts
-------------------

[](#quick-setup-scripts)

### GitHub Actions Setup

[](#github-actions-setup)

Automatically install the GitHub Actions workflow for continuous integration:

```
vendor/lts/php-qa-ci/scripts/install-github-actions.bash
```

This will:

- Create `.github/workflows/qa.yml` with an optimized QA pipeline
- Auto-detect your PHP version from `composer.json`
- Configure smart caching for faster builds
- Set up artifact storage for test results

### Branch Protection Setup

[](#branch-protection-setup)

Configure GitHub branch protection rules with sensible defaults:

```
# Standard protection (admins can bypass)
vendor/lts/php-qa-ci/scripts/setup-branch-protection.bash

# Hardened protection (CI enforced for everyone)
vendor/lts/php-qa-ci/scripts/setup-branch-protection.bash --harden
```

**Prerequisites**: Requires [GitHub CLI](https://cli.github.com/) (`gh`) installed and authenticated.

CI/CD Workflows
---------------

[](#cicd-workflows)

PHP-QA-CI includes three GitHub Actions workflows in `.github/workflows/`:

- **`ci.yml`** -- Runs on push/PR to `php8.4`, executes `bash ci.bash`
- **`qa.yml`** -- Template workflow for consuming projects (copy to your project)
- **`update-deps.yml`** -- Weekly scheduled workflow that updates all dependencies (Composer, PHARs via PHIVE, isolated Rector), runs the full QA pipeline, and creates an auto-merge PR if green

See [GitHub Actions Integration](./docs/github-actions.md) for setup details.

Claude Code Integration
-----------------------

[](#claude-code-integration)

PHP-QA-CI integrates with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) to provide development guardrails and automation.

### Deployment

[](#deployment)

Deploy skills and hooks to your project:

```
vendor/lts/php-qa-ci/scripts/deploy-skills.bash vendor/lts/php-qa-ci .
```

This will:

- Copy hooks to `.claude/hooks/`
- Register them in `.claude/settings.json`
- Detect and configure hooks-daemon if present (see hooks-daemon documentation for installation)
- Migrate from legacy classic hooks if found

### Included Hooks

[](#included-hooks)

- `php-qa-ci__auto-continue.py` -- Reduces confirmation prompts
- `php-qa-ci__prevent-destructive-git.py` -- Blocks commands that destroy uncommitted changes
- `php-qa-ci__discourage-git-stash.py` -- Discourages git stash with escape hatch
- `php-qa-ci__block-plan-time-estimates.py` -- Prevents time estimates in plan documents
- `php-qa-ci__validate-claude-readme-content.py` -- Ensures docs contain instructions, not logs
- `php-qa-ci__enforce-markdown-organization.py` -- Enforces doc organization

See `.claude/hooks/README.md` for detailed hook documentation after deployment.

### Composer Plugins

[](#composer-plugins)

PHP-QA-CI registers three Composer plugins:

- **PhiveUpdatePlugin** -- Manages PHAR installation via PHIVE
- **SkillsDeployPlugin** -- Deploys Claude Code skills and hooks
- **PhpStanGuardPlugin** -- Prevents `phpstan/phpstan` from being installed alongside the PHAR

Docs
----

[](#docs)

Comprehensive documentation is available in the [./docs](./docs) folder:

- **[Pipeline Architecture](./docs/pipeline.md)** -- Tool execution order and phases
- **[Tools Overview](./docs/phpqa-tools.md)** -- All tools with configuration details
- **[Configuration](./docs/configuration.md)** -- Customizing tool settings and overrides
- **[Coding Standards](./docs/coding-standards.md)** -- PHP CS Fixer and Rector configuration
- **[GitHub Actions Integration](./docs/github-actions.md)** -- CI/CD setup guide
- **[Continuous Integration](./docs/ci.md)** -- General CI usage and workflows
- **[Platform Detection](./docs/platform-detection.md)** -- Symfony/Laravel specific settings

Tool-specific documentation:

- **[PHPStan](./docs/tools/phpstan.md)** -- Static analysis configuration and custom rules
- **[PHPUnit](./docs/tools/phpunit.md)** -- Test runner configuration and modes
- **[Infection](./docs/tools/infection.md)** -- Mutation testing setup

Other Notes
-----------

[](#other-notes)

### Specify PHP Binary Path

[](#specify-php-binary-path)

If you are running multiple PHP versions, you can specify which one to use:

```
export PHP_QA_CI_PHP_EXECUTABLE=/bin/php84
vendor/bin/qa

# Or inline:
PHP_QA_CI_PHP_EXECUTABLE=/bin/php84 vendor/bin/qa
```

### Running Specific Tools

[](#running-specific-tools)

```
# Run only PHPStan
vendor/bin/qa -t stan

# Run only PHP CS Fixer
vendor/bin/qa -t fixer

# Run on specific path
vendor/bin/qa -t stan -p src/Domain
```

### Branches

[](#branches)

- `php8.4` -- Default branch, targets PHP 8.4
- `php8.3` -- PHP 8.3 support

Long Term Support
-----------------

[](#long-term-support)

This package was brought to you by Long Term Support LTD, a company run and founded by Joseph Edmonds.

You can get in touch with Joseph at

Check out Joseph's recent book [The Art of Modern PHP 8](https://ltscommerce.dev/#book)

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance60

Regular maintenance activity

Popularity22

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity21

Early-stage or recently created project

 Bus Factor1

Top contributor holds 75.9% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/5a46ff83653f10442de0a2ba097a939acfb8583e1393a2e376a73cb140348791?d=identicon)[lts](/maintainers/lts)

---

Top Contributors

[![edmondscommerce](https://avatars.githubusercontent.com/u/62842?v=4)](https://github.com/edmondscommerce "edmondscommerce (368 commits)")[![LTSCommerce](https://avatars.githubusercontent.com/u/72404520?v=4)](https://github.com/LTSCommerce "LTSCommerce (73 commits)")[![rossmitchell](https://avatars.githubusercontent.com/u/7073145?v=4)](https://github.com/rossmitchell "rossmitchell (35 commits)")[![everon](https://avatars.githubusercontent.com/u/375251?v=4)](https://github.com/everon "everon (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (3 commits)")[![tahirqureshi](https://avatars.githubusercontent.com/u/73536349?v=4)](https://github.com/tahirqureshi "tahirqureshi (1 commits)")

### Embed Badge

![Health badge](/badges/lts-php-qa-ci/health.svg)

```
[![Health](https://phpackages.com/badges/lts-php-qa-ci/health.svg)](https://phpackages.com/packages/lts-php-qa-ci)
```

###  Alternatives

[phpspec/prophecy

Highly opinionated mocking framework for PHP 5.3+

8.5k551.7M682](/packages/phpspec-prophecy)[brianium/paratest

Parallel testing for PHP

2.5k118.8M754](/packages/brianium-paratest)[beberlei/assert

Thin assertion library for input validation in business models.

2.4k96.9M570](/packages/beberlei-assert)[mikey179/vfsstream

Virtual file system to mock the real file system in unit tests.

1.4k108.0M2.7k](/packages/mikey179-vfsstream)[orchestra/testbench

Laravel Testing Helper for Packages Development

2.2k39.1M32.1k](/packages/orchestra-testbench)[phpspec/phpspec

Specification-oriented BDD framework for PHP 7.1+

1.9k36.7M3.1k](/packages/phpspec-phpspec)

PHPackages © 2026

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