From 50c0aa2546b5da07cabeb3af53f460f8376ed804 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 10 Feb 2026 16:48:41 +0100 Subject: [PATCH 1/5] Add phpbench markdown report extension --- phpbench.json | 5 +- tests/Bench/Extension/MarkdownExtension.php | 33 +++++ tests/Bench/Extension/MarkdownRenderer.php | 133 ++++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 tests/Bench/Extension/MarkdownExtension.php create mode 100644 tests/Bench/Extension/MarkdownRenderer.php diff --git a/phpbench.json b/phpbench.json index d62e210..37f09ff 100644 --- a/phpbench.json +++ b/phpbench.json @@ -2,5 +2,8 @@ "$schema": "./vendor/phpbench/phpbench/phpbench.schema.json", "runner.bootstrap": "vendor/autoload.php", "runner.path": "tests/Bench", - "runner.file_pattern": "*Bench.php" + "runner.file_pattern": "*Bench.php", + "core.extensions": [ + "Tempest\\Highlight\\Tests\\Bench\\Extension\\MarkdownExtension" + ] } diff --git a/tests/Bench/Extension/MarkdownExtension.php b/tests/Bench/Extension/MarkdownExtension.php new file mode 100644 index 0000000..42cf9a4 --- /dev/null +++ b/tests/Bench/Extension/MarkdownExtension.php @@ -0,0 +1,33 @@ +register(MarkdownRenderer::class, function (Container $container) { + return new MarkdownRenderer( + $container->get(ConsoleExtension::SERVICE_OUTPUT_STD), + $container->get(ExpressionExtension::SERVICE_PLAIN_PRINTER), + ); + }, [ + ReportExtension::TAG_REPORT_RENDERER => [ + 'name' => 'markdown', + ], + ]); + } +} diff --git a/tests/Bench/Extension/MarkdownRenderer.php b/tests/Bench/Extension/MarkdownRenderer.php new file mode 100644 index 0000000..51b1acf --- /dev/null +++ b/tests/Bench/Extension/MarkdownRenderer.php @@ -0,0 +1,133 @@ +renderContent($reports); + $file = $config['file']; + + if ($file === null) { + $this->output->write($content); + + return; + } + + $this->writeFile($file, $content); + } + + public function configure(OptionsResolver $options): void + { + $options->setDefaults([ + 'file' => null, + ]); + $options->setAllowedTypes('file', ['null', 'string']); + } + + private function renderContent(Reports $reports): string + { + $lines = []; + + foreach ($reports->tables() as $table) { + array_push($lines, ...$this->renderTable($table)); + } + + return implode("\n", $lines) . "\n"; + } + + private function renderTable(Table $table): array + { + $lines = []; + $title = $table->title(); + + if ($title !== null && $title !== '') { + $lines[] = "## {$title}"; + $lines[] = ''; + } + + $columns = $table->columnNames(); + + if ($columns === []) { + return $lines; + } + + $lines[] = $this->renderRow($columns); + $lines[] = $this->renderSeparatorRow($columns); + + foreach ($table as $row) { + $lines[] = $this->renderDataRow($row); + } + + $lines[] = ''; + + return $lines; + } + + private function renderRow(array $cells): string + { + return '| ' . implode(' | ', $cells) . ' |'; + } + + private function renderSeparatorRow(array $columns): string + { + return $this->renderRow(array_map( + fn (string $column): string => str_repeat('-', max(3, mb_strlen($column))), + $columns, + )); + } + + private function renderDataRow(TableRow $row): string + { + $cells = array_map($this->formatCell(...), iterator_to_array($row)); + + return $this->renderRow($cells); + } + + private function formatCell(Node $node): string + { + return str_replace('|', '\\|', trim($this->printer->print($node))); + } + + private function writeFile(string $file, string $content): void + { + $this->createDirectory(dirname($file)); + + if (file_put_contents($file, $content) === false) { + throw new RuntimeException(sprintf('Could not write to file "%s"', $file)); + } + + $this->output->writeln("Written markdown report to: {$file}"); + } + + private function createDirectory(string $directory): void + { + if (is_dir($directory)) { + return; + } + + if (! mkdir($directory, 0o777, true) && ! is_dir($directory)) { + throw new RuntimeException(sprintf('Could not create directory "%s"', $directory)); + } + } +} From b31778e527e4457f5eefd5cf2305c48265bf278d Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 10 Feb 2026 16:48:50 +0100 Subject: [PATCH 2/5] Remove stderr redirect from benchmark CI --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 876a92d..461acbd 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -39,7 +39,7 @@ jobs: run: | git checkout ${{ github.event.pull_request.head.sha }} composer install --no-interaction --prefer-dist --quiet - vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none 2>&1 | tee benchmark-result.txt || true + vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none | tee benchmark-result.txt || true - name: Prepare artifact run: | From 5266e4164e22148254706169ca01ce02cd2dc993 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 10 Feb 2026 16:48:59 +0100 Subject: [PATCH 3/5] Remove code fences from benchmark comment --- .github/workflows/benchmark-comment.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/benchmark-comment.yml b/.github/workflows/benchmark-comment.yml index d5e90aa..bb41a09 100644 --- a/.github/workflows/benchmark-comment.yml +++ b/.github/workflows/benchmark-comment.yml @@ -56,8 +56,6 @@ jobs: Comparison of `${{ steps.bench.outputs.head-ref }}` against `${{ steps.bench.outputs.base-ref }}` (`${{ steps.bench.outputs.base-sha }}`). - ``` ${{ steps.bench.outputs.result }} - ``` Generated by phpbench against commit ${{ steps.bench.outputs.head-sha }} From c0f37592e48f19e33f140215ebe30d44387a81c4 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 10 Feb 2026 16:57:50 +0100 Subject: [PATCH 4/5] Use markdown output for phpbench --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 461acbd..446924e 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -39,7 +39,7 @@ jobs: run: | git checkout ${{ github.event.pull_request.head.sha }} composer install --no-interaction --prefer-dist --quiet - vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none | tee benchmark-result.txt || true + vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none --output=markdown | tee benchmark-result.txt || true - name: Prepare artifact run: | From 8f08b86bc44994695eb6f2507dbc674bae526f31 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 10 Feb 2026 16:57:53 +0100 Subject: [PATCH 5/5] Wrap benchmark results in collapsible details --- .github/workflows/benchmark-comment.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/benchmark-comment.yml b/.github/workflows/benchmark-comment.yml index bb41a09..64d079e 100644 --- a/.github/workflows/benchmark-comment.yml +++ b/.github/workflows/benchmark-comment.yml @@ -56,6 +56,11 @@ jobs: Comparison of `${{ steps.bench.outputs.head-ref }}` against `${{ steps.bench.outputs.base-ref }}` (`${{ steps.bench.outputs.base-sha }}`). +
+ Open to see the benchmark results + ${{ steps.bench.outputs.result }} +
+ Generated by phpbench against commit ${{ steps.bench.outputs.head-sha }}