Skip to content
getnextpdf.com

Engineering quality

Every push and pull request to NextPDF runs build-blocking CI gates for static analysis, changed-line coverage, mutation score, and tagged-output validation.

Three PHPStan gates run on every push and pull request:

GateScopeBlocking
Level 10src/Yes
Level max (strict profile)src/Yes
SARIF annotationsrc/Advisory

CI treats PHPStan Level 10 findings in src/ as build-blocking. Two settings raise the bar above a default Level 10 run:

  • treatPhpDocTypesAsCertain — PHPStan trusts the PHPDoc annotation as ground truth rather than re-widening to the native type, so a narrowing annotation that contradicts what static analysis can derive is a reported finding.
  • reportUnmatchedIgnoredErrors — every suppression must match a currently-reported error, or the build fails.

Each ignoreErrors entry for src/ is pinned to a PHPStan identifier, an exact file path, and where relevant an exact occurrence count — a new occurrence of the same identifier anywhere else, or a second occurrence in the same file, fails the build.

CI enforces a 90% coverage threshold on the lines each pull request changes, measured with PCOV against the base branch. A pull request below the threshold fails the build.

Mutation testing checks that the tests assert on behaviour: CI mutates the code and requires a test to fail. Three mutation score indicators carry monotonically non-decreasing floors:

MetricEnforced minimum
raw_msi88.9%
effective_msi89.0%
covered_msi88.9%

A pull request that would drop any metric below its floor is rejected. CI applies a documented variance tolerance before comparing a run against the floors.

CI runs veraPDF 1.30.1 with the pdfua.strict profile as a build-blocking gate on the tagged-output corpus.