From f0275e65c1b5a81973cee349b9944ddcaa5da717 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 14:55:43 +0200 Subject: [PATCH 1/2] chore: add github workflows --- .github/workflows/main.yml | 28 ++++++++ .github/workflows/release.yml | 68 +++++++++++++++++++ .../Util/Shared/InheritedAsserts.php | 23 ++++--- 3 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..30d2886 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,28 @@ +name: CI +on: + pull_request: +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + matrix: + php: [8.2, 8.3, 8.4] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: phpstan + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + - name: Run PHPStan + run: phpstan diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..39b0080 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: Automated release +on: + push: + branches: + - master +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + matrix: + php: [ 8.2, 8.3, 8.4 ] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + + - name: Execute Code Sniffer + run: vendor/bin/phpcs + + - name: Execute PHP Stan + run: vendor/bin/phpstan + + - name: Run test suite + run: | + php -S 127.0.0.1:8000 -t tests/data/app >/dev/null 2>&1 & + php -S 127.0.0.1:8010 -t tests/data/rest >/dev/null 2>&1 & + php vendor/bin/codecept run + + + release: + name: Automated release + needs: + - tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: > + npx + -p "@semantic-release/commit-analyzer" + -p "@semantic-release/release-notes-generator" + -p conventional-changelog-conventionalcommits + -p semantic-release + -- semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +permissions: + packages: write + contents: write + pull-requests: write \ No newline at end of file diff --git a/src/Codeception/Util/Shared/InheritedAsserts.php b/src/Codeception/Util/Shared/InheritedAsserts.php index 7f2fd8f..0843f07 100644 --- a/src/Codeception/Util/Shared/InheritedAsserts.php +++ b/src/Codeception/Util/Shared/InheritedAsserts.php @@ -10,6 +10,7 @@ use PHPUnit\Framework\Constraint\LogicalNot; use PHPUnit\Framework\Constraint\StringMatchesFormatDescription; use ReflectionClass; +use ReflectionException; trait InheritedAsserts { @@ -49,7 +50,7 @@ protected function assertClassHasStaticAttribute(string $attributeName, string $ { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); - Assert::assertTrue($this->hasStaticAttribute($attributeName, $className), $message); + Assert::assertTrue(self::hasStaticAttribute($attributeName, $className), $message); } /** @@ -69,7 +70,7 @@ protected function assertClassNotHasAttribute(string $attributeName, string $cla protected function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); - Assert::assertFalse($this->hasStaticAttribute($attributeName, $className), $message); + Assert::assertFalse(self::hasStaticAttribute($attributeName, $className), $message); } /** @@ -1143,7 +1144,7 @@ protected function assertStringNotEqualsFileIgnoringCase(string $expectedFile, s /** * Asserts that a string does not match a given format string. */ - protected function assertStringNotMatchesFormat(string $format, string $string, string $message = '') + protected function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 12', E_USER_DEPRECATED); $constraint = new LogicalNot(new StringMatchesFormatDescription($format)); @@ -1153,15 +1154,14 @@ protected function assertStringNotMatchesFormat(string $format, string $string, /** * Asserts that a string does not match a given format string. */ - protected function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = '') + protected function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 12', E_USER_DEPRECATED); - Assert::assertFileExists($formatFile); - $constraint = new LogicalNot( - new StringMatchesFormatDescription( - file_get_contents($formatFile) - ) - ); + $content = file_get_contents($formatFile); + if ($content === false) { + Assert::fail(sprintf('Failed to read format file "%s"', $formatFile)); + } + $constraint = new LogicalNot(new StringMatchesFormatDescription($content)); Assert::assertThat($string, $constraint, $message); } @@ -1320,8 +1320,9 @@ protected function markTestSkipped(string $message = ''): never /** * @see https://github.com/sebastianbergmann/phpunit/blob/9.6/src/Framework/Constraint/Object/ClassHasStaticAttribute.php + * @param class-string $className */ - private static function hasStaticAttribute(string $attributeName, string $className) + private static function hasStaticAttribute(string $attributeName, string $className): bool { try { $class = new \ReflectionClass($className); From e648458e0fb5bc98e76bc8286bd4052b7a06215d Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 14:58:47 +0200 Subject: [PATCH 2/2] chore: improve phpstan asserts --- src/Codeception/Util/Shared/InheritedAsserts.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Codeception/Util/Shared/InheritedAsserts.php b/src/Codeception/Util/Shared/InheritedAsserts.php index 0843f07..5048840 100644 --- a/src/Codeception/Util/Shared/InheritedAsserts.php +++ b/src/Codeception/Util/Shared/InheritedAsserts.php @@ -402,8 +402,7 @@ protected function assertInstanceOf(string $expected, $actual, string $message = * Asserts that a variable is of type array. * * @param mixed $actual - * - * @phpstan-assert array $actual + * @phpstan-assert array $actual */ protected function assertIsArray($actual, string $message = ''): void { @@ -475,7 +474,7 @@ protected function assertIsInt($actual, string $message = ''): void * * @param mixed $actual * - * @phpstan-assert iterable $actual + * @phpstan-assert iterable $actual */ protected function assertIsIterable($actual, string $message = ''): void { @@ -487,7 +486,7 @@ protected function assertIsIterable($actual, string $message = ''): void * * @param mixed $actual * - * @phpstan-assert !array $actual + * @phpstan-assert !array $actual */ protected function assertIsNotArray($actual, string $message = ''): void { @@ -559,7 +558,7 @@ protected function assertIsNotInt($actual, string $message = ''): void * * @param mixed $actual * - * @phpstan-assert !iterable $actual + * @phpstan-assert !iterable $actual */ protected function assertIsNotIterable($actual, string $message = ''): void {