phpcq/author-validation
CLI tool to validate author metadata across a repo: checks PHP file headers and composer.json/bower.json/packages.json against git history. Supports YAML config for author alias mapping, ignore/include/exclude rules, and copy-left enforcement.
Installation:
Add to composer.json under require-dev:
"phpcq/author-validation": "^1.0"
Run composer update.
First Run: Execute the CLI tool in your project root:
./vendor/bin/check-author.php
This checks all PHP files, composer.json, and package files against Git authorship.
Basic Configuration:
Create a .check-author.yml file in your project root with minimal settings:
ignore:
- "Build Bot <bot@example.com>"
exclude:
- "vendor/"
- "tests/"
Pre-CI Validation: Integrate into a GitHub Actions workflow to block merges with mismatched authors:
# .github/workflows/author-validation.yml
name: Author Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/check-author.php
Path Scoping:
Limit checks to specific directories (e.g., Laravel’s app/):
./vendor/bin/check-author.php app/
Or via config:
include:
- "app/"
- "config/"
Author Aliasing: Map historical authors to current names (e.g., after renames):
mapping:
"Old Name <old@example.com>": "New Name <new@example.com>"
Copy-Left Enforcement: Enforce specific authors for certain files/directories:
copy-left:
"Lead Developer <dev@example.com>": "src/"
Pre-Commit Hook: Use with Husky to fail locally:
# package.json
"husky": {
"hooks": {
"pre-commit": "./vendor/bin/check-author.php --quiet"
}
}
CI/CD Pipeline: Run as a build step with path filtering:
# GitLab CI example
test:
script:
- ./vendor/bin/check-author.php --path=app/
Laravel Artisan Integration: Create a custom command to wrap the tool:
// app/Console/Commands/ValidateAuthors.php
public function handle() {
$command = base_path('vendor/bin/check-author.php');
$exitCode = shell_exec("$command app/ 2>&1");
if ($exitCode !== 0) {
$this->error('Author validation failed!');
exit(1);
}
}
Laravel-Specific: Exclude Blade templates by default (they’re not PHP files):
exclude:
- "resources/views/**/*.blade.php"
Monorepos:
Use --path to scope to Laravel directories:
./vendor/bin/check-author.php packages/laravel-app/
Git Workflow:
Ensure CI runs git fetch --unshallow if using shallow clones to avoid missing history.
Git History Dependencies:
- run: git fetch --unshallow
Case Sensitivity:
"John Doe" vs. "john doe" may not match.Blade Template Exclusions:
.blade.php files are PHP but often excluded.include:
- "resources/views/**/*.blade.php"
Vendor Directory Conflicts:
vendor/ may trigger false positives.vendor/ in config.Verbose Output:
Use --verbose to see detailed mismatches:
./vendor/bin/check-author.php --verbose
Dry Runs: Test without failing builds:
./vendor/bin/check-author.php --dry-run
Config Validation: Validate YAML syntax with:
./vendor/bin/check-author.php --config=.check-author.yml --dry-run
Path Resolution:
include/exclude are resolved from the config file’s directory.Author Mapping:
mapping:
"Old Name <old@example.com>":
- "New Name <new@example.com>"
- "Team Alias <team@example.com>"
Copy-Left Overrides:
**/ for deep paths:
copy-left:
"Lead <lead@example.com>": "src/**/*.php"
Custom Comparators: Extend the tool by implementing a custom comparator (advanced). See source.
Laravel Service Provider: Register the tool as a Laravel service for dynamic config:
// config/check-author.php
return [
'ignore' => env('AUTHOR_VALIDATION_IGNORE', []),
];
CI Notifications: Parse output in CI to send Slack alerts on failures:
- name: Slack Notification
if: failure()
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Author validation failed!"}' \
$SLACK_WEBHOOK
How can I help you explore Laravel packages today?