Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Fix PHPBench workflow #1206

Merged
merged 6 commits into from
Nov 24, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/benchmark-empty.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Fallback workflow to be able to have the branch protection enabled at all times.
name: Benchmark Tests
name: Empty Benchmark Tests

on:
# To be aware it need to be the counter-part of benchmark.yaml.
Expand Down
38 changes: 37 additions & 1 deletion .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,40 @@ jobs:
pr-bench-test:
runs-on: ubuntu-latest
name: Benchmark PR
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
ini-values: phar.readonly=0, display_errors=On, error_reporting=-1
tools: composer
coverage: none

- name: Install Composer dependencies
uses: ramsey/composer-install@v2

- name: Ensure that the make target is up to date
run: make _vendor_install

- name: Install PHPBench
uses: ramsey/composer-install@v2
with:
working-directory: vendor-bin/phpbench

- name: Ensure that the PHPBench make target is up to date
run: make phpbench_install

- name: Run PHPBench
run: make phpbench

pr-main-bench-test:
runs-on: ubuntu-latest
name: Benchmark PR compared to main
needs: main-bench-test
steps:
- name: Checkout
Expand Down Expand Up @@ -91,7 +125,7 @@ jobs:
with:
name: bench-branch-main-result

- name: Run PHPBench against PR branch
- name: Run PHPBench for PR branch
run: make phpbench_pr


Expand All @@ -102,7 +136,9 @@ jobs:
name: Benchmark tests status
runs-on: ubuntu-latest
needs:
- main-bench-test
- pr-bench-test
- pr-main-bench-test
if: always()
steps:
- name: Successful run
Expand Down
3 changes: 2 additions & 1 deletion bin/bench-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@

echo 'Failed!'.PHP_EOL;
echo 'Missed the target by '.$relativeDifference.'%'.PHP_EOL;
exit(1);
// TODO: https://github.com/box-project/box/issues/552
exit(0);
2 changes: 1 addition & 1 deletion fixtures/bench/with-compactors/box.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"main": "box.php",
"output": "../../../dist/bench/box.phar",

"directories-bin": ["../../../res/requirement-checker"],
"directories-bin": ["res"],
"force-autodiscovery": true,

"dump-autoload": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace HumbugBox451\KevinGH\RequirementChecker;

if (isset($_SERVER['BOX_REQUIREMENT_CHECKER'])) {
$enableRequirementChecker = $_SERVER['BOX_REQUIREMENT_CHECKER'];
if (\is_bool($enableRequirementChecker) && !$enableRequirementChecker) {
return;
}
if (\is_string($enableRequirementChecker) && \in_array(\strtolower($enableRequirementChecker), ['false', '0'], \true)) {
return;
}
if (!\is_bool($enableRequirementChecker) && !\is_string($enableRequirementChecker)) {
echo \PHP_EOL . 'Unhandled value type for "BOX_REQUIREMENT_CHECKER". Got "' . \gettype($enableRequirementChecker) . '". Proceeding with the requirement checks.' . \PHP_EOL;
}
}
if (\false === \in_array(\PHP_SAPI, array('cli', 'phpdbg', 'embed', 'micro'), \true)) {
echo \PHP_EOL . 'The application may only be invoked from a command line, got "' . \PHP_SAPI . '"' . \PHP_EOL;
exit(1);
}
require __DIR__ . '/../vendor/autoload.php';
if (!Checker::checkRequirements()) {
exit(1);
}
103 changes: 103 additions & 0 deletions fixtures/bench/with-compactors/res/requirement-checker/src/Checker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

declare (strict_types=1);
namespace HumbugBox451\KevinGH\RequirementChecker;

use InvalidArgumentException;
use function count;
use function sprintf;
/** @internal */
final class Checker
{
private static $requirementsConfig;
public static function checkRequirements() : bool
{
$requirements = self::retrieveRequirements();
$checkPassed = $requirements->evaluateRequirements();
$io = new IO();
self::printCheck($checkPassed, new Printer($io->getVerbosity(), $io->hasColorSupport()), $requirements);
return $checkPassed;
}
public static function printCheck($checkPassed, Printer $printer, RequirementCollection $requirements) : void
{
if (\false === $checkPassed && IO::VERBOSITY_VERY_VERBOSE > $printer->getVerbosity()) {
$printer->setVerbosity(IO::VERBOSITY_VERY_VERBOSE);
}
$verbosity = IO::VERBOSITY_VERY_VERBOSE;
$iniPath = $requirements->getPhpIniPath();
$printer->title('Box Requirements Checker', $verbosity);
$printer->printv('> Using PHP ', $verbosity);
$printer->printvln(\PHP_VERSION, $verbosity, 'green');
if ($iniPath) {
$printer->printvln('> PHP is using the following php.ini file:', $verbosity);
$printer->printvln(' ' . $iniPath, $verbosity, 'green');
} else {
$printer->printvln('> PHP is not using any php.ini file.', $verbosity, 'yellow');
}
$printer->printvln('', $verbosity);
if (count($requirements) > 0) {
$printer->printvln('> Checking Box requirements:', $verbosity);
$printer->printv(' ', $verbosity);
} else {
$printer->printvln('> No requirements found.', $verbosity);
}
$errorMessages = [];
foreach ($requirements->getRequirements() as $requirement) {
if ($errorMessage = $printer->getRequirementErrorMessage($requirement)) {
if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
$printer->printvln('' . $requirement->getTestMessage(), IO::VERBOSITY_DEBUG, 'red');
$printer->printv(' ', IO::VERBOSITY_DEBUG);
$errorMessages[] = $errorMessage;
} else {
$printer->printv('E', $verbosity, 'red');
$errorMessages[] = $errorMessage;
}
continue;
}
if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
$printer->printvln('' . $requirement->getTestMessage(), IO::VERBOSITY_DEBUG, 'green');
$printer->printv(' ', IO::VERBOSITY_DEBUG);
} else {
$printer->printv('.', $verbosity, 'green');
}
}
if (IO::VERBOSITY_DEBUG !== $printer->getVerbosity() && count($requirements) > 0) {
$printer->printvln('', $verbosity);
}
if ($requirements->evaluateRequirements()) {
$printer->block('OK', 'Your system is ready to run the application.', $verbosity, 'success');
} else {
$printer->block('ERROR', 'Your system is not ready to run the application.', $verbosity, 'error');
$printer->title('Fix the following mandatory requirements:', $verbosity, 'red');
foreach ($errorMessages as $errorMessage) {
$printer->printv(' * ' . $errorMessage, $verbosity);
}
}
$printer->printvln('', $verbosity);
}
private static function retrieveRequirements() : RequirementCollection
{
if (null === self::$requirementsConfig) {
self::$requirementsConfig = __DIR__ . '/../.requirements.php';
}
$config = (require self::$requirementsConfig);
$requirements = new RequirementCollection();
foreach ($config as $constraint) {
$requirements->addRequirement(self::createCondition($constraint['type'], $constraint['condition']), $constraint['message'], $constraint['helpMessage']);
}
return $requirements;
}
private static function createCondition($type, $condition) : IsFulfilled
{
switch ($type) {
case 'php':
return new IsPhpVersionFulfilled($condition);
case 'extension':
return new IsExtensionFulfilled($condition);
case 'extension-conflict':
return new IsExtensionConflictFulfilled($condition);
default:
throw new InvalidArgumentException(sprintf('Unknown requirement type "%s".', $type));
}
}
}
128 changes: 128 additions & 0 deletions fixtures/bench/with-compactors/res/requirement-checker/src/IO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

declare (strict_types=1);
namespace HumbugBox451\KevinGH\RequirementChecker;

use function fstat;
use function function_exists;
use function getenv;
use function implode;
use function posix_isatty;
use function preg_match;
use function preg_quote;
use function sapi_windows_vt100_support;
use function sprintf;
use function str_replace;
use function stream_isatty;
use const DIRECTORY_SEPARATOR;
use const STDOUT;
/** @internal */
final class IO
{
public const VERBOSITY_QUIET = 16;
public const VERBOSITY_NORMAL = 32;
public const VERBOSITY_VERBOSE = 64;
public const VERBOSITY_VERY_VERBOSE = 128;
public const VERBOSITY_DEBUG = 256;
private $interactive;
private $verbosity = self::VERBOSITY_NORMAL;
private $colorSupport;
private $options;
public function __construct()
{
$this->options = implode(' ', $_SERVER['argv']);
$shellVerbosity = $this->configureVerbosity();
$this->interactive = $this->checkInteractivity($shellVerbosity);
$this->colorSupport = $this->checkColorSupport();
}
public function isInteractive() : bool
{
return $this->interactive;
}
public function getVerbosity() : int
{
return $this->verbosity;
}
public function hasColorSupport() : bool
{
return $this->colorSupport;
}
public function hasParameter($values) : bool
{
$values = (array) $values;
foreach ($values as $value) {
$regexp = sprintf('/\\s%s\\b/', str_replace(' ', '\\s+', preg_quote($value, '/')));
if (1 === preg_match($regexp, $this->options)) {
return \true;
}
}
return \false;
}
private function checkInteractivity(int $shellVerbosity) : bool
{
if (-1 === $shellVerbosity) {
return \false;
}
if (\true === $this->hasParameter(['--no-interaction', '-n'])) {
return \false;
}
if (function_exists('posix_isatty') && !@posix_isatty(STDOUT) && \false === getenv('SHELL_INTERACTIVE')) {
return \false;
}
return \true;
}
private function configureVerbosity() : int
{
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
case -1:
$this->verbosity = self::VERBOSITY_QUIET;
break;
case 1:
$this->verbosity = self::VERBOSITY_VERBOSE;
break;
case 2:
$this->verbosity = self::VERBOSITY_VERY_VERBOSE;
break;
case 3:
$this->verbosity = self::VERBOSITY_DEBUG;
break;
default:
$shellVerbosity = 0;
break;
}
if ($this->hasParameter(['--quiet', '-q'])) {
$this->verbosity = self::VERBOSITY_QUIET;
$shellVerbosity = -1;
} elseif ($this->hasParameter(['-vvv', '--verbose=3', '--verbose 3'])) {
$this->verbosity = self::VERBOSITY_DEBUG;
$shellVerbosity = 3;
} elseif ($this->hasParameter(['-vv', '--verbose=2', '--verbose 2'])) {
$this->verbosity = self::VERBOSITY_VERY_VERBOSE;
$shellVerbosity = 2;
} elseif ($this->hasParameter(['-v', '--verbose=1', '--verbose 1', '--verbose'])) {
$this->verbosity = self::VERBOSITY_VERBOSE;
$shellVerbosity = 1;
}
return $shellVerbosity;
}
private function checkColorSupport() : bool
{
if ($this->hasParameter(['--ansi'])) {
return \true;
}
if ($this->hasParameter(['--no-ansi'])) {
return \false;
}
if (DIRECTORY_SEPARATOR === '\\') {
return function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(STDOUT) || \false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
}
if (function_exists('stream_isatty')) {
return stream_isatty(STDOUT);
}
if (function_exists('posix_isatty')) {
return posix_isatty(STDOUT);
}
$stat = fstat(STDOUT);
return $stat ? 020000 === ($stat['mode'] & 0170000) : \false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare (strict_types=1);
namespace HumbugBox451\KevinGH\RequirementChecker;

use function extension_loaded;
/** @internal */
final class IsExtensionConflictFulfilled implements IsFulfilled
{
private $conflictingExtension;
public function __construct(string $requiredExtension)
{
$this->conflictingExtension = $requiredExtension;
}
public function __invoke() : bool
{
return !extension_loaded($this->conflictingExtension);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare (strict_types=1);
namespace HumbugBox451\KevinGH\RequirementChecker;

use function extension_loaded;
/** @internal */
final class IsExtensionFulfilled implements IsFulfilled
{
private $requiredExtension;
public function __construct(string $requiredExtension)
{
$this->requiredExtension = $requiredExtension;
}
public function __invoke() : bool
{
return extension_loaded($this->requiredExtension);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare (strict_types=1);
namespace HumbugBox451\KevinGH\RequirementChecker;

/** @internal */
interface IsFulfilled
{
public function __invoke() : bool;
}
Loading
Loading