From 83a411f67642d6d20d98f639991e304d975daaaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Wed, 3 Jun 2026 13:45:49 +0200 Subject: [PATCH 01/10] Setup php 8.5 Docker Compose service --- docker-compose.yml | 10 ++++++++++ docker/php85/Dockerfile | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 docker/php85/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 9896e09..c7d43bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,3 +9,13 @@ services: working_dir: /code volumes: - ./:/code:delegated + php85: + build: + context: . + dockerfile: docker/php85/Dockerfile + container_name: php-testbench.craftzing.php85 + restart: unless-stopped + tty: true + working_dir: /code + volumes: + - ./:/code:delegated diff --git a/docker/php85/Dockerfile b/docker/php85/Dockerfile new file mode 100644 index 0000000..162065a --- /dev/null +++ b/docker/php85/Dockerfile @@ -0,0 +1,10 @@ +FROM php:8.5-cli-alpine3.21 + +WORKDIR /code + +USER root +COPY docker/setup.sh . +RUN chmod u+x /code/setup.sh && /code/setup.sh && rm /code/setup.sh +COPY --from=composer:2.10 /usr/bin/composer /usr/local/bin/composer + +USER app From f282e697c40d05fcc2d311d4d175ad52e4c4597a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Wed, 3 Jun 2026 13:45:56 +0200 Subject: [PATCH 02/10] Upgrade to composer 2.10 --- docker/php84/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/php84/Dockerfile b/docker/php84/Dockerfile index 98d3245..ae1e49e 100644 --- a/docker/php84/Dockerfile +++ b/docker/php84/Dockerfile @@ -5,6 +5,6 @@ WORKDIR /code USER root COPY docker/setup.sh . RUN chmod u+x /code/setup.sh && /code/setup.sh && rm /code/setup.sh -COPY --from=composer:2.8 /usr/bin/composer /usr/local/bin/composer +COPY --from=composer:2.10 /usr/bin/composer /usr/local/bin/composer USER app From bdb68f637d45cfd33a10827080e534f3c7141fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Wed, 3 Jun 2026 14:35:07 +0200 Subject: [PATCH 03/10] Replace Makefile by Taskfile --- .gitattributes | 2 +- CONTRIBUTING.md | 16 +++++++++--- Makefile | 13 ---------- Taskfile.yml | 61 ++++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 4 +-- 5 files changed, 76 insertions(+), 20 deletions(-) delete mode 100644 Makefile create mode 100644 Taskfile.yml diff --git a/.gitattributes b/.gitattributes index 97fb776..a143f13 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,4 +12,4 @@ *.md export-ignore *.yml export-ignore .php-cs-fixer.dist.php export-ignore -Makefile export-ignore +Taskfile.yml export-ignore diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5f6546..c2d4e78 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,9 +14,17 @@ Make sure to follow these rules when creating a pull request: - We follow [Semantic Versioning](http://semver.org/), so please send pull requests to the correct branch - Update the [CHANGELOG.md](CHANGELOG.md) file with any changes/additions/... and follow the [changelog standards](http://keepachangelog.com/) -## 🧪 Running tests +# 🏃‍➡️ Running locally -You can run the test suite with the following command: -```bash -vendor/bin/phpunit +This project is fully Dockerized, meaning [Docker](https://docs.docker.com) (or [Orbstack](https://orbstack.dev) for macOS users) is the only requirement +to run this project locally. Using Docker Compose, we set up a container for each supported PHP version. + +> [!TIP] +> While you can run Docker Compose commands directly, we highly recommend to use our predefined tasks using +> [Task](https://taskfile.dev). All docs will always refer to these tasks, but if you prefer not to install +> Task, you can inspect [Taskfile.yml](./Taskfile.yml) to see which Docker Compose commands are used under the hood. + +To explore all available tasks, run: +```shell +task ``` diff --git a/Makefile b/Makefile deleted file mode 100644 index bba2ce4..0000000 --- a/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -.PHONY: up -up: ## Up the project using Docker Composer - docker compose up --detach - docker compose exec php84 composer install - -.PHONY: down -down: ## Shutdown the project using Docker Composer - docker compose down - -.PHONY: php84 -php84: ## Open an interactive shell into the `php84` (service in docker-compose.yml) - docker compose up -d - docker compose exec php84 sh diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..7c2d679 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,61 @@ +# https://taskfile.dev +version: '3.50' + +vars: + PHP_VERSIONS: ['8.4', '8.5'] + DEFAULT_PHP_VERSION: '8.5' + +tasks: + default: + desc: 'List all available tasks' + silent: true + cmd: task --list + + up: + desc: 'Up the PHP container(s) and install all Composer dependencies' + cmds: + - docker compose up --detach + - docker compose exec php-{{ .DEFAULT_PHP_VERSION }} composer install + + down: + desc: 'Shutdown the PHP container(s)' + cmds: + - docker compose down + + php: + desc: 'Open an interactive shell into one of the `php` services (see docker-compose.yml)' + summary: | + Open an interactive shell into one of the `php` services (see docker-compose.yml). + + usage: + task php version= + requires: + vars: + - name: version + enum: + ref: .PHP_VERSIONS + cmds: + - docker compose up --detach + - docker compose exec php-{{ .version }} sh + + test: + desc: 'Run the testsuite on all or one of the supported PHP versions' + summary: | + Run the testsuite on all or one of the supported PHP versions. + + usage: + task test + task test version= + vars: + versions: |- + {{- if .version -}} + {{ .version }} + {{- else -}} + {{ join "," .PHP_VERSIONS }} + {{- end -}} + cmds: + - docker compose up --detach + - for: + var: versions + split: ',' + cmd: docker compose exec php-{{ .ITEM }} composer phpunit diff --git a/docker-compose.yml b/docker-compose.yml index c7d43bb..ccfb45c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,5 @@ services: - php84: + php-8.4: build: context: . dockerfile: docker/php84/Dockerfile @@ -9,7 +9,7 @@ services: working_dir: /code volumes: - ./:/code:delegated - php85: + php-8.5: build: context: . dockerfile: docker/php85/Dockerfile From 72431bce6c94158d17e3284be99650301125ef93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Wed, 3 Jun 2026 14:43:30 +0200 Subject: [PATCH 04/10] Run test workflow on php 8.5 --- .github/workflows/{tests.yml => test.yml} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename .github/workflows/{tests.yml => test.yml} (62%) diff --git a/.github/workflows/tests.yml b/.github/workflows/test.yml similarity index 62% rename from .github/workflows/tests.yml rename to .github/workflows/test.yml index 5326d08..761784a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Tests +name: test on: [push, pull_request] jobs: @@ -8,12 +8,12 @@ jobs: fail-fast: true matrix: os: [ubuntu-24.04] - php: [8.4] + php: [8.4, 8.5] dependency-version: [prefer-lowest, prefer-stable] name: PHP ${{ matrix.php }} - ${{ matrix.dependency-version }} steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # https://github.com/actions/checkout/releases/tag/v6.0.2 + - uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # https://github.com/shivammathur/setup-php/releases/tag/2.37.1 with: php-version: ${{ matrix.php }} coverage: pcov From ade15f70927ba23730194bf9918edb362e7d11c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 08:50:34 +0200 Subject: [PATCH 05/10] Only run tests on push to main --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 761784a..ea44ae9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,8 @@ name: test -on: [push, pull_request] +on: + pull_request: + push: + branches: ['main'] jobs: tests: From c4084c5fc3609cbeafc270b391310d1c58f262b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 08:57:49 +0200 Subject: [PATCH 06/10] Upgrade to alpine 3.23 --- docker/php84/Dockerfile | 2 +- docker/php85/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/php84/Dockerfile b/docker/php84/Dockerfile index ae1e49e..88c3e17 100644 --- a/docker/php84/Dockerfile +++ b/docker/php84/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.4-cli-alpine3.21 +FROM php:8.4-cli-alpine3.23 WORKDIR /code diff --git a/docker/php85/Dockerfile b/docker/php85/Dockerfile index 162065a..43d7ceb 100644 --- a/docker/php85/Dockerfile +++ b/docker/php85/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.5-cli-alpine3.21 +FROM php:8.5-cli-alpine3.23 WORKDIR /code From b64e98b589d48351c689b5248e550c29e6734d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 08:59:29 +0200 Subject: [PATCH 07/10] Remove deprecate --no-suggest flag from composer install --- .github/workflows/static-analysis.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 3e320bf..f4a82e8 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -9,7 +9,7 @@ jobs: - uses: shivammathur/setup-php@v2 with: php-version: 8.4 - - run: composer update --prefer-stable --prefer-dist --no-interaction --no-suggest + - run: composer update --prefer-stable --prefer-dist --no-interaction - run: composer phpstan php-cs-fixer: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea44ae9..551dbda 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,5 +20,5 @@ jobs: with: php-version: ${{ matrix.php }} coverage: pcov - - run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest + - run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - run: composer coverage:summary From df4d9cd7ff40678426f559702e64e3d0e1366880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 09:10:34 +0200 Subject: [PATCH 08/10] Lock actions by commit hash --- .github/workflows/static-analysis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index f4a82e8..4cc6987 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -1,12 +1,15 @@ -name: Static analysis -on: [push] +name: static-analysis +on: + pull_request: + push: + branches: ['main'] jobs: phpstan: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: shivammathur/setup-php@v2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # https://github.com/actions/checkout/releases/tag/v6.0.2 + - uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # https://github.com/shivammathur/setup-php/releases/tag/2.37.1 with: php-version: 8.4 - run: composer update --prefer-stable --prefer-dist --no-interaction @@ -15,7 +18,7 @@ jobs: php-cs-fixer: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # https://github.com/actions/checkout/releases/tag/v6.0.2 with: ref: ${{ github.head_ref }} - name: Run PHP CS fixer From 7960ba001f574cec0f4f4fb953694c2d2de23ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 09:20:13 +0200 Subject: [PATCH 09/10] Disable mysql extensions in workflows to prevent deprecation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shivammathur/setup-php installs and enables the pdo_mysql extension by default. Because the extension is loaded, the check evaluates to true. PHP then reads the PDO::MYSQL_ATTR_SSL_CA constant to build the array, which immediately triggers the PHP 8.5 deprecation warning in the CI. This does not happen locally as the local Docker image does not enable the extension. We don’t use it either, so we should not enable it anywhere. --- .github/workflows/static-analysis.yml | 5 +++-- .github/workflows/test.yml | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 4cc6987..a0ee0bf 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -12,6 +12,7 @@ jobs: - uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # https://github.com/shivammathur/setup-php/releases/tag/2.37.1 with: php-version: 8.4 + extensions: -pdo_mysql, -mysqli - run: composer update --prefer-stable --prefer-dist --no-interaction - run: composer phpstan @@ -21,13 +22,13 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # https://github.com/actions/checkout/releases/tag/v6.0.2 with: ref: ${{ github.head_ref }} - - name: Run PHP CS fixer + - name: 'Run PHP CS fixer' uses: ./.github/actions/php-cs-fixer with: workspace: ${{ github.workspace }} args: --config=.php-cs-fixer.dist.php --allow-risky=yes github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Commit CS fixes + - name: 'Commit CS fixes' uses: craftzing/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 with: commit_message: Fix code style violations diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 551dbda..bf5aadf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,5 +20,6 @@ jobs: with: php-version: ${{ matrix.php }} coverage: pcov + extensions: -pdo_mysql, -mysqli - run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - run: composer coverage:summary From 8f542cc915d8af34dbe84203a1512cd64ef03abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81mi=20Pelhate?= Date: Thu, 4 Jun 2026 09:33:33 +0200 Subject: [PATCH 10/10] Fix static analysis --- src/Factories/ImmutableFactory.php | 6 ++++-- src/Factories/InstanceFactory.php | 2 +- src/PHPUnit/DataProviders/EnumCase.php | 12 +++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Factories/ImmutableFactory.php b/src/Factories/ImmutableFactory.php index b6303f5..40570dd 100644 --- a/src/Factories/ImmutableFactory.php +++ b/src/Factories/ImmutableFactory.php @@ -13,7 +13,7 @@ use function iterator_to_array; /** - * @template TClass + * @template TClass of object */ abstract class ImmutableFactory { @@ -34,6 +34,7 @@ final public function __construct( */ public function state(array $state): static { + // @phpstan-ignore-next-line return.type return new static($this->faker, [...$this->state, ...$state], $this->count); } @@ -42,6 +43,7 @@ public function state(array $state): static */ public function times(int $count): static { + // @phpstan-ignore-next-line return.type return new static($this->faker, $this->state, $count); } @@ -87,7 +89,7 @@ public function raw(array $attributes = []): array /** * @param array $attributes - * @return array + * @return array> */ public function rawMany(array $attributes = []): array { diff --git a/src/Factories/InstanceFactory.php b/src/Factories/InstanceFactory.php index 36371b2..21b414d 100644 --- a/src/Factories/InstanceFactory.php +++ b/src/Factories/InstanceFactory.php @@ -8,7 +8,7 @@ use ReflectionProperty; /** - * @template TClass + * @template TClass of object */ final readonly class InstanceFactory { diff --git a/src/PHPUnit/DataProviders/EnumCase.php b/src/PHPUnit/DataProviders/EnumCase.php index b2c7101..a5f5f34 100644 --- a/src/PHPUnit/DataProviders/EnumCase.php +++ b/src/PHPUnit/DataProviders/EnumCase.php @@ -26,10 +26,12 @@ */ private array $options; + /** + * @param TValue $instance + * @param TValue ...$options + */ public function __construct( - /* @var TValue */ public UnitEnum $instance, - /* @param array ...$options */ UnitEnum ...$options, ) { in_array($instance, $options, true) or throw new ValueError('Options should contain the given instance.'); @@ -58,7 +60,7 @@ public function differentInstance(): UnitEnum /** * @param class-string $enumFQCN - * @return iterable>> + * @return iterable}> */ public static function cases(string $enumFQCN): iterable { @@ -72,7 +74,7 @@ public static function cases(string $enumFQCN): iterable /** * @param TValue ...$options - * @return iterable>> + * @return iterable}> */ public static function options(UnitEnum ...$options): iterable { @@ -83,7 +85,7 @@ public static function options(UnitEnum ...$options): iterable /** * @param class-string $enumFQCN - * @return iterable>> + * @return iterable}> */ public static function except(string $enumFQCN, UnitEnum ...$except): iterable {