PHP-QA-CI: A Comprehensive Quality Assurance Pipeline in a Single Dependency
In the PHP ecosystem, setting up a comprehensive quality assurance pipeline typically involves installing and configuring a dozen different tools, each with their own configuration files, command-line interfaces, and quirks. What if you could get a battle-tested, production-ready QA pipeline with a single Composer dependency?
The Problem with Traditional QA Setup
Setting up quality assurance tools for a PHP project traditionally involves a time-consuming process:
- Installing multiple dev dependencies individually
- Creating configuration files for each tool
- Writing scripts to run tools in the correct order
- Ensuring consistency across different projects
- Maintaining and updating configurations as tools evolve
- Training team members on different tool interfaces
This fragmented approach leads to inconsistency across projects, maintenance overhead, and often results in teams skipping important QA steps due to complexity.
Enter PHP-QA-CI
PHP-QA-CI is our first-party quality assurance and continuous integration pipeline that solves these problems elegantly. Built by Long Term Support LTD, it provides a complete QA pipeline through a single Composer dependency.
The key innovation is simple yet powerful: instead of manually orchestrating multiple tools, PHP-QA-CI provides:
- Pre-configured, sensible defaults for all integrated tools
- Logical execution order that fails fast on errors
- Consistent interface across all projects
- Easy customization when needed
- Version-specific branches for different PHP versions
The Complete Tool Suite
Installing PHP-QA-CI gives you immediate access to a comprehensive suite of quality assurance tools, organized into four logical categories:
The tools are executed in a logical order, from fastest to slowest, to provide quick feedback:
1. Validation and Checks
- PSR-4 Validation - Checks code namespaces for PSR-4 standard compliance (built-in script)
- Composer Check for Issues - Runs composer diagnose and dumps autoloader
- Strict Types Enforcing - Checks and can fix files without strict types defined
2. Linting
- PHP Parallel Lint - Very fast PHP syntax error checking
3. Static Analysis
- PHPStan - Performs static code analysis
4. Testing
- PHPUnit - Runs unit tests
- Infection - Mutation testing tool that deliberately mutates your code to test test quality
5. Documentation
- Markdown Links Checker - Validates links in README.md and docs/*.md files (built-in script)
6. Final Checks
- Uncommitted Changes Check - Verifies no pending code changes before further processing
7. Code Formatting
- Beautifier and Fixer - Automatically reformats PHP code and applies coding standards
- PHP Code Sniffer - Checks remaining coding standards issues
Installation and Basic Usage
Getting started with PHP-QA-CI requires just a single Composer command:
{
"require-dev": {
"lts/php-qa-ci": "dev-master@dev"
},
"config": {
"bin-dir": "bin"
}
}
Install the package (using the PHP 8.4 branch):
composer require --dev lts/php-qa-ci:dev-php8.4
That's it! You now have access to the complete QA pipeline:
#!/bin/bash
# Run the complete QA pipeline
./bin/qa
# Run with a specific PHP version
export PHP_QA_CI_PHP_EXECUTABLE=/usr/bin/php8.3
./bin/qa
# Run on a specific directory
./bin/qa /path/to/scan
# Run a single tool (example with PHPStan)
./bin/qa -t phpstan
The pipeline runs tools in a logical order designed to "fail as quickly as possible," saving time by catching basic issues before running more time-consuming analyses.
PHP Version Support
PHP-QA-CI maintains separate branches for different PHP versions, ensuring compatibility and leveraging version-specific features:
master
- Stable release branchphp8.3
- PHP 8.3 specific configurationsphp8.4
- PHP 8.4 support (current recommended branch as of 2025)
This branching strategy allows the tool to provide optimal configurations for each PHP version while maintaining backward compatibility where needed.
Configuration and Customization
While PHP-QA-CI works out of the box with sensible defaults, it's designed for easy customization. The tool looks for custom configurations in your project's qaConfig
directory, falling back to defaults when custom configs aren't found.
Creating Custom Configurations
#!/bin/bash
# Create custom configuration directory
mkdir -p qaConfig
# Copy and customize PHPStan configuration
cp vendor/lts/php-qa-ci/configDefaults/generic/phpstan.neon qaConfig/
# Edit qaConfig/phpstan.neon as needed
# Copy and customize PHP CS Fixer configuration
cp vendor/lts/php-qa-ci/configDefaults/generic/php_cs.php qaConfig/
# Edit qaConfig/php_cs.php as needed
# The QA pipeline will automatically use your custom configs
PHPStan Custom Configuration Example
Here's how to extend the default PHPStan configuration for your project:
includes:
- vendor/lts/php-qa-ci/configDefaults/generic/phpstan.neon
parameters:
level: 9
paths:
- src
- tests
excludePaths:
- tests/fixtures
ignoreErrors:
- '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\)#'
reportUnmatchedIgnoredErrors: false
checkMissingIterableValueType: false
PHP CS Fixer Custom Configuration
Customize coding standards while maintaining the base configuration:
<?php
declare(strict_types=1);
// Include the default configuration
$config = require __DIR__ . '/../vendor/lts/php-qa-ci/configDefaults/generic/php_cs.php';
// Get the default finder
$finder = require __DIR__ . '/../vendor/lts/php-qa-ci/configDefaults/generic/php_cs_finder.php';
// Customize the finder if needed
$finder
->exclude('legacy')
->notPath('src/Migrations/Version*.php');
// Add or override rules
$rules = $config->getRules();
$rules['php_unit_test_class_requires_covers'] = false;
$rules['php_unit_internal_class'] = false;
return $config
->setFinder($finder)
->setRules($rules);
Symfony Project Integration
PHP-QA-CI includes special considerations for Symfony projects. When installing in a Symfony project, you have two options:
#!/bin/bash
# For Symfony projects: choose between Symfony defaults or php-qa-ci defaults
# Option 1: Use php-qa-ci defaults (more extensive)
rm phpunit.xml.dist
ln -s vendor/lts/php-qa-ci/configDefaults/generic/phpunit.xml
# Option 2: Keep Symfony defaults
# Simply accept the recipe prompts during installation
# Create project-specific overrides
mkdir -p qaConfig
echo "parameters:
level: 8
paths:
- src
excludePaths:
- var
- vendor" > qaConfig/phpstan.neon
The PHP-QA-CI defaults are generally more extensive than Symfony's defaults, including additional static analysis rules and stricter coding standards.
Advanced Features
Hooks System
PHP-QA-CI supports pre and post execution hooks, allowing you to integrate custom logic into the pipeline:
#!/bin/bash
# Create custom hooks for the QA pipeline
mkdir -p qaConfig
# Pre-hook: Run before QA pipeline starts
cat > qaConfig/preBashHook.bash << 'EOF'
#!/bin/bash
echo "Starting QA pipeline for project: $(basename $(pwd))"
echo "PHP Version: $($PHP_QA_CI_PHP_EXECUTABLE --version | head -n1)"
# Clear any caches that might affect results
if [ -d "var/cache" ]; then
rm -rf var/cache/*
fi
EOF
# Post-hook: Run after QA pipeline completes
cat > qaConfig/postBashHook.bash << 'EOF'
#!/bin/bash
echo "QA Pipeline completed!"
# Generate a summary report
if [ -f "infection.log" ]; then
echo "Mutation Score: $(grep -oP 'Mutation Score Indicator \(MSI\): \K[0-9.]+' infection.log)%"
fi
# Send notification (example)
# curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
# -H 'Content-type: application/json' \
# --data '{"text":"QA Pipeline completed successfully!"}'
EOF
chmod +x qaConfig/*.bash
Mutation Testing with Infection
One of the most powerful features is the integrated mutation testing via Infection. This helps assess the quality of your test suite by introducing small changes (mutations) to your code and checking if tests catch them:
{
"source": {
"directories": [
"src"
]
},
"logs": {
"text": "infection.log",
"summary": "summary.log",
"debug": "debug.log",
"perMutator": "per-mutator.md"
},
"mutators": {
"@default": true,
"global-ignoreSourceCodeByRegex": [
"Assert::.*"
]
},
"testFramework": "phpunit",
"testFrameworkOptions": "--configuration=phpunit.xml"
}
Performance Optimization
The pipeline is optimized for performance through several strategies:
- Fail-fast approach: Basic checks run first
- Parallel execution where possible
- Intelligent caching of results
- Option to run quick tests only during development
CI/CD Integration
PHP-QA-CI is designed to work seamlessly in continuous integration environments. Here's an example GitHub Actions workflow:
name: Quality Assurance
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
qa:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.1', '8.2', '8.3']
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: xdebug
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run QA Pipeline
run: ./bin/qa
env:
PHP_QA_CI_PHP_EXECUTABLE: /usr/bin/php${{ matrix.php-version }}
The pipeline works equally well with other CI systems like GitLab CI, Jenkins, or Bitbucket Pipelines. The consistent interface means your local development experience matches your CI environment exactly.
Real-World Benefits
Consistency Across Projects
With PHP-QA-CI, all your projects use the same QA pipeline, making it easy for developers to move between projects without learning new tools or configurations.
Time Savings
Setting up a comprehensive QA pipeline manually can take hours or days. With PHP-QA-CI, you're up and running in minutes with a battle-tested configuration.
Maintenance Reduction
Instead of maintaining configurations for a dozen tools across multiple projects, you maintain a single dependency. Updates to tool configurations are handled centrally.
Best Practices by Default
The default configurations encode years of PHP development best practices, ensuring your code meets high quality standards without extensive research.
Comparison with Manual Setup
Consider what manual setup of these tools would require:
Aspect | Manual Setup | PHP-QA-CI |
---|---|---|
Initial Setup Time | 2-4 hours | 5 minutes |
Configuration Files | 10-15 files | 0 (uses defaults) |
Composer Dependencies | 12+ packages | 1 package |
Execution Scripts | Custom required | Single qa command |
Cross-project Consistency | Manual synchronization | Automatic |
Tool Updates | Individual updates | Single update |
Troubleshooting Common Issues
Permission Issues
If you encounter permission issues with the qa script:
chmod +x vendor/lts/php-qa-ci/bin/qa
# Or use composer's bin directory
chmod +x bin/qa
Memory Limits
Some tools like PHPStan may require increased memory limits:
export PHP_QA_CI_PHP_EXECUTABLE="php -d memory_limit=512M"
./bin/qa
Tool-Specific Issues
Individual tools can be run in isolation for debugging:
# Run only PHPStan
./bin/qa phpstan
# Run with verbose output
./bin/qa --verbose
Future Development
PHP-QA-CI continues to evolve with the PHP ecosystem. Current development focuses on:
- Support for newer PHP versions as they're released
- Integration of emerging QA tools
- Performance optimizations for large codebases
- Enhanced reporting and metrics
- Better IDE integration support
Conclusion
PHP-QA-CI represents a paradigm shift in PHP quality assurance setup. By providing a complete, pre-configured pipeline through a single dependency, it removes the barriers to implementing comprehensive quality checks in PHP projects.
Whether you're starting a new project or looking to improve quality assurance in an existing codebase, PHP-QA-CI offers immediate value with minimal setup effort. The combination of sensible defaults, easy customization, and comprehensive tool coverage makes it an essential addition to any serious PHP development workflow.
The tool embodies the philosophy of the PHP language itself: pragmatic, powerful, and focused on developer productivity. By abstracting away the complexity of QA pipeline configuration, PHP-QA-CI lets developers focus on what matters most - writing quality code.
Get Started Today
Ready to streamline your PHP quality assurance workflow? Visit the PHP-QA-CI GitHub repository or install it directly via Composer:
composer require --dev lts/php-qa-ci:dev-master@dev