1010 - ' composer.json'
1111 - ' composer.lock'
1212 - ' phpstan.neon'
13+ - ' phpunit.xml'
1314 - ' .php-cs-fixer.dist.php'
1415 - ' .github/workflows/php-lint.yml'
1516 pull_request :
1920 - ' composer.json'
2021 - ' composer.lock'
2122 - ' phpstan.neon'
23+ - ' phpunit.xml'
2224 - ' .php-cs-fixer.dist.php'
2325 - ' .github/workflows/php-lint.yml'
2426
@@ -285,6 +287,58 @@ jobs:
285287 run : |
286288 composer audit --format=plain || echo "::warning::Vulnerabilities found in dependencies"
287289
290+ # ============================================================
291+ # Unit Tests - PHPUnit with coverage
292+ # ============================================================
293+ tests :
294+ name : Unit Tests (PHPUnit)
295+ runs-on : ubuntu-latest
296+ needs : syntax
297+ permissions :
298+ contents : read
299+ steps :
300+ - name : Checkout
301+ uses : actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
302+
303+ - name : Setup PHP
304+ uses : shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
305+ with :
306+ php-version : ${{ env.PHP_VERSION }}
307+ extensions : xdebug
308+ coverage : xdebug
309+ tools : phpunit:10
310+
311+ - name : Install Composer dependencies
312+ run : composer install --no-progress --prefer-dist --no-interaction
313+
314+ - name : Run PHPUnit tests
315+ run : |
316+ vendor/bin/phpunit --coverage-text --coverage-clover=coverage/clover.xml
317+
318+ - name : Check coverage threshold
319+ run : |
320+ # Extract coverage percentage from clover.xml
321+ if [ -f coverage/clover.xml ]; then
322+ COVERAGE=$(php -r "
323+ \$xml = simplexml_load_file('coverage/clover.xml');
324+ \$metrics = \$xml->project->metrics;
325+ \$elements = (int)\$metrics['elements'];
326+ \$covered = (int)\$metrics['coveredelements'];
327+ if (\$elements > 0) {
328+ echo round((\$covered / \$elements) * 100, 2);
329+ } else {
330+ echo '0';
331+ }
332+ ")
333+ echo "Code coverage: ${COVERAGE}%"
334+ echo "## Test Coverage: ${COVERAGE}%" >> $GITHUB_STEP_SUMMARY
335+
336+ # Fail if coverage is below 70%
337+ if (( $(echo "$COVERAGE < 70" | bc -l) )); then
338+ echo "::warning::Coverage is below 70% threshold"
339+ fi
340+ fi
341+
288342 # ============================================================
289343 # Multi-version PHP Test - Ensure compatibility
290344 # ============================================================
@@ -324,7 +378,7 @@ jobs:
324378 lint-summary :
325379 name : Lint Summary
326380 runs-on : ubuntu-latest
327- needs : [syntax, code-style, phpstan, license-headers, strict-types, security-patterns, composer-audit, php-compat]
381+ needs : [syntax, code-style, phpstan, tests, license-headers, strict-types, security-patterns, composer-audit, php-compat]
328382 if : always()
329383 permissions :
330384 contents : read
@@ -338,6 +392,7 @@ jobs:
338392 echo "| Syntax | ${{ needs.syntax.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
339393 echo "| Code Style | ${{ needs.code-style.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
340394 echo "| PHPStan | ${{ needs.phpstan.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
395+ echo "| Unit Tests | ${{ needs.tests.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
341396 echo "| License Headers | ${{ needs.license-headers.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
342397 echo "| Strict Types | ${{ needs.strict-types.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
343398 echo "| Security Patterns | ${{ needs.security-patterns.result == 'success' && '✅ Pass' || '❌ Fail' }} |" >> $GITHUB_STEP_SUMMARY
@@ -348,6 +403,7 @@ jobs:
348403 if [ "${{ needs.syntax.result }}" != "success" ] || \
349404 [ "${{ needs.code-style.result }}" != "success" ] || \
350405 [ "${{ needs.phpstan.result }}" != "success" ] || \
406+ [ "${{ needs.tests.result }}" != "success" ] || \
351407 [ "${{ needs.strict-types.result }}" != "success" ] || \
352408 [ "${{ needs.security-patterns.result }}" != "success" ]; then
353409 echo ""
0 commit comments