Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/wsdlgenerator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ name: Wsdl Generator
on: [push, pull_request]
jobs:
wsdlgenerator:
name: Wsdl Generator (PHP ${{ matrix.php-versions }})
name: Wsdl Generator (PHP ${{ matrix.php-versions }}${{ matrix.coverage && ', coverage' || '' }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['8.1', '8.2', '8.3']
# Coverage is measured once, on the newest PHP, rather than once per version.
include:
- php-versions: '8.3'
coverage: true
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -19,7 +23,7 @@ jobs:
# soap is not required by the package; it backs the tests that read a
# generated document the way a client does.
extensions: dom, pcre, soap, spl
coverage: xdebug
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
tools: php-cs-fixer, cs2pr

- name: Validate composer.json
Expand Down Expand Up @@ -48,6 +52,10 @@ jobs:
run: vendor/bin/phpstan analyse --error-format=checkstyle --memory-limit=512M | cs2pr

- name: Run Unit Tests
if: ${{ !matrix.coverage }}
run: composer unittest
env:
XDEBUG_MODE: coverage

# Fails the job when the lines or methods of src fall below 100%.
- name: Run Unit Tests with the coverage gate
if: ${{ matrix.coverage }}
run: composer coverage-gate
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,13 @@ major release may change that.
## Development

```
composer fix # apply the code style
composer stan # static analysis
composer unittest # the unit tests
composer fulltest # all three
composer fix # apply the code style
composer stan # static analysis
composer unittest # the unit tests
composer fulltest # all three
composer coverage # the unit tests, with a coverage summary
composer coverage-gate # the unit tests, failing below 100% coverage
```

Coverage needs Xdebug. Continuous integration runs the gate on PHP 8.3, and the
unit tests alone on 8.1 and 8.2.
9 changes: 9 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@
"check": "vendor/bin/php-cs-fixer fix --dry-run",
"stan": "vendor/bin/phpstan analyse --memory-limit=512M",
"unittest": "vendor/bin/phpunit --testsuite unit",
"coverage": [
"@putenv XDEBUG_MODE=coverage",
"vendor/bin/phpunit --testsuite unit --coverage-text --only-summary-for-coverage-text"
],
"coverage-gate": [
"@putenv XDEBUG_MODE=coverage",
"vendor/bin/phpunit --testsuite unit --coverage-clover build/coverage/clover.xml",
"php tests/coverage-gate.php build/coverage/clover.xml 100"
],
"fulltest": [
"@fix",
"@stan",
Expand Down
5 changes: 0 additions & 5 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
<directory suffix=".php">./src</directory>
</include>
</source>
<coverage>
<report>
<text outputFile="php://stdout" showOnlySummary="true"/>
</report>
</coverage>
<php>
<ini name="memory_limit" value="512M"/>
<ini name="soap.wsdl_cache_enabled" value="0"/>
Expand Down
44 changes: 44 additions & 0 deletions tests/coverage-gate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/**
* Coverage gate.
*
* Reads a clover coverage report and exits non-zero when the lines or the methods
* of src fall short of a required percentage, 100 by default. PHPUnit reports
* coverage without enforcing it, so continuous integration runs this after the
* suite to fail a change that leaves code untested.
*
* Usage: php tests/coverage-gate.php <clover.xml> [required percentage]
*/
$report = $argv[1] ?? '';
$required = (float) ($argv[2] ?? 100);

if ($report === '' || !is_file($report)) {
fwrite(STDERR, "Coverage gate: no clover report at '$report'.\n");
exit(2);
}

$clover = simplexml_load_file($report);
$metrics = $clover === false ? null : $clover->project->metrics;
if ($metrics === null || $metrics->getName() !== 'metrics') {
fwrite(STDERR, "Coverage gate: '$report' is not a clover report.\n");
exit(2);
}

$failed = false;
foreach (['Lines' => 'statements', 'Methods' => 'methods'] as $label => $metric) {
$total = (int) $metrics[$metric];
$covered = (int) $metrics['covered' . $metric];
$percent = $total === 0 ? 100.0 : $covered / $total * 100;

$met = $percent >= $required;
$failed = $failed || !$met;
printf(" %-8s %6.2f%% (%d/%d) %s\n", $label . ':', $percent, $covered, $total, $met ? 'ok' : 'below ' . $required . '%');
}

if ($failed) {
fwrite(STDERR, "Coverage gate: coverage is below {$required}%.\n");
exit(1);
}

echo "Coverage gate: passed.\n";
Loading