Build/Test Tools: Publish PHPUnit timing metrics to CodeVitals - #13083
Build/Test Tools: Publish PHPUnit timing metrics to CodeVitals#13083lancewillett wants to merge 5 commits into
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
@johnbillion Thanks for suggesting CodeVitals on https://core.trac.wordpress.org/ticket/65887#comment:4. CodeVitals requires GitHub repository admin access to manage metric definitions. Could you add these six definitions for
The service silently drops unknown metric keys. This PR verifies that all six were accepted, so the scheduled publishing step will fail clearly if any definition is missing. Once these exist, I can complete the authenticated submission and verify the public dashboard: https://codevitals.run/public/WordPress/wordpress-develop/metrics |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @lance.willett@a8c.com. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
desrosj
left a comment
There was a problem hiding this comment.
Some small questions and change requests.
|
Thanks @desrosj -- fixed pushed bfd9637
I originally limited this to weekly runs for storage and consistency, but updated it to publish after every push to PR runs remain excluded because their branch-specific results are less comparable—and would create a LOT more storage that isn't that helpful for stats. At least, not now. |
|
@adimoldovan Curious your take on the approach. Is there a better way to store the test run results and display it in a dashboard somewhere? |
There was a problem hiding this comment.
Pull request overview
This PR adds a small pipeline to extract aggregate timing statistics from the PHPUnit JUnit report produced in CI and publish those aggregates to the existing public CodeVitals dashboard for trunk pushes, enabling trend tracking without exposing per-test details.
Changes:
- Add an XML-streaming parser (
WP_PHPUnit_Timing_Metrics) to compute suite time, p95/p99/max test time, and slow-test counts from a JUnit report. - Add a CLI publisher (
prepare-timing-results.php) that produces a compact JSON payload for CodeVitals ingestion. - Extend the canonical PHPUnit CI job to publish and validate the six metrics after the main suite run.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
tests/phpunit/includes/class-wp-phpunit-timing-metrics.php |
Implements JUnit XML parsing and aggregate timing metric extraction. |
tests/phpunit/prepare-timing-results.php |
CLI wrapper to generate the CodeVitals JSON payload from a JUnit file plus commit metadata. |
tests/phpunit/tests/includes/junitTimingMetrics.php |
Adds PHPUnit coverage for timing extraction logic and edge cases. |
.github/workflows/reusable-phpunit-tests-v3.yml |
Publishes timing metrics to CodeVitals from the canonical trunk push job and validates acceptance. |
.github/workflows/phpunit-tests.yml |
Passes the CodeVitals token secret through to the reusable PHPUnit workflow. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| $file = tempnam( sys_get_temp_dir(), 'junit-timing-' ); | ||
| $this->temporary_files[] = $file; | ||
| $suite_time_attribute = null === $suite_time ? '' : sprintf( ' time="%s"', $suite_time ); |
There was a problem hiding this comment.
I think that this makes sense. Any objection to this @lancewillett?
There was a problem hiding this comment.
Good call. Pushed a follow-up (d450580) that fails the test explicitly when tempnam() returns false, so it can't reach unlink() in teardown.
desrosj
left a comment
There was a problem hiding this comment.
I think this is worth trying. There's one outstanding Copilot comment I think is worth including.
@lancewillett The approach works if the goal is to store the trend. If what we want is signal to optimize slow tests, none of the six aggregates can name a test. #13070 already gives us time, file, and line per case, so publishing the top slow tests or those over a threshold as Github annotations would get us there. That could be a good signal in PRs too, so an author can spot a slow test they added. |
…ics test. If tempnam() returns false, fail the test explicitly instead of storing false and emitting an unlink() warning during teardown. See #65887.
|
@adimoldovan Thanks for your feedback. Opened #13212 for flagging the slow tests by name using annotations. |
Trac ticket: https://core.trac.wordpress.org/ticket/65887
What this changes
The canonical PHPUnit job publishes six aggregate timing metrics to the existing public CodeVitals dashboard after every push to
trunk:The publisher reads the existing JUnit report immediately after the main test suite, before later test-group runs replace the file. It streams the XML, creates a small JSON payload, and sends no test names or per-test records.
This complements #13070. That pull request preserves the raw JUnit report for detailed analysis; this one adds the visible trend layer.
Metrics
phpunit-suite-timephpunit-p95-test-timephpunit-p99-test-timephpunit-max-test-timephpunit-tests-over-500msphpunit-tests-over-1sKeeping one metric visible by default avoids crowding the existing dashboard. The other five remain available from the Other selector for diagnosis.
The definitions must exist in CodeVitals before the first submission. Suggested priorities are 100–105 in the order above, with a regression noise floor of 0 until
trunkruns establish a baseline.The workflow also verifies that CodeVitals accepted all six metrics. A missing definition fails the step instead of silently dropping data.
How to validate
After the first
trunkpush following merge, open:https://codevitals.run/public/WordPress/wordpress-develop/metrics
The PHPUnit main suite time card should appear. Select it to view the trend by commit. Use Other to add the percentile, maximum, and slow-test-count metrics.
The parser can be checked locally with:
A previously captured CI report containing 30,871 timed test cases produced:
An authenticated CodeVitals submission remains a pre-merge validation item. The token stays in the existing
CODEVITALS_PROJECT_TOKENActions secret and is never available to local or pull-request runs.Testing
actionlintpassed for both changed workflow files.