From 45ed0ce6a207717348cac98dd5e51941dbffe8f0 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:48:33 -0300 Subject: [PATCH 1/5] build: Pin the PHP tooling image in the Makefile. --- Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 90ab50d..6915324 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,12 @@ endif TTY := $(shell [ -t 0 ] && echo -it) -DOCKER_RUN = docker run ${PLATFORM} --rm ${TTY} --net=host -v ${PWD}:/app -w /app gustavofreze/php:8.5-alpine +PHP_VERSION := $(shell sed -n 's/.*"php": *"^\([0-9]*\.[0-9]*\)".*/\1/p' composer.json) +IMAGE_VERSION := 1.0.0 +PHP_IMAGE := gustavofreze/php:${PHP_VERSION}-cli-${IMAGE_VERSION} +WORKSPACE := /var/www/html + +DOCKER_RUN = docker run ${PLATFORM} --rm ${TTY} --net=host -v ${PWD}:${WORKSPACE} ${PHP_IMAGE} RESET := \033[0m GREEN := \033[0;32m @@ -44,6 +49,10 @@ show-reports: ## Open coverage and mutation reports in the browser show-outdated: ## Show outdated direct dependencies @${DOCKER_RUN} composer outdated --direct +.PHONY: show-image +show-image: ## Show the pinned PHP tooling image + @echo ${PHP_IMAGE} + .PHONY: clean clean: ## Remove dependencies and generated artifacts @sudo chown -R ${USER}:${USER} ${PWD} @@ -66,7 +75,7 @@ help: ## Display this help message | awk 'BEGIN {FS = ":.*?## "}; {printf "$(YELLOW)%-25s$(RESET) %s\n", $$1, $$2}' @echo "" @echo "$$(printf '$(GREEN)')Reports$$(printf '$(RESET)')" - @grep -E '^(show-reports|show-outdated):.*?## .*$$' $(MAKEFILE_LIST) \ + @grep -E '^(show-reports|show-outdated|show-image):.*?## .*$$' $(MAKEFILE_LIST) \ | awk 'BEGIN {FS = ":.*?## "}; {printf "$(YELLOW)%-25s$(RESET) %s\n", $$1, $$2}' @echo "" @echo "$$(printf '$(GREEN)')Cleanup$$(printf '$(RESET)')" From 3aa6a64c9eabe606222a427a1c17d29be32e50a2 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:48:33 -0300 Subject: [PATCH 2/5] ci: Resolve the tooling image from the Makefile. --- .github/workflows/ci.yml | 49 ++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b401ca6..1b5f8ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,42 +11,39 @@ permissions: contents: read jobs: - resolve-php-version: - name: Resolve PHP version + resolve-tooling-image: + name: Resolve tooling image runs-on: ubuntu-latest timeout-minutes: 5 outputs: - php-version: ${{ steps.config.outputs.php-version }} + php-image: ${{ steps.config.outputs.php-image }} steps: - name: Checkout uses: actions/checkout@v7 - - name: Resolve PHP version from composer.json + - name: Resolve tooling image from the Makefile id: config - run: | - version=$(jq -r '.require.php' composer.json | grep -oP '\d+\.\d+' | head -1) - echo "php-version=$version" >> "$GITHUB_OUTPUT" + run: echo "php-image=$(make show-image)" >> "$GITHUB_OUTPUT" build: name: Build - needs: resolve-php-version + needs: resolve-tooling-image runs-on: ubuntu-latest timeout-minutes: 15 + env: + image: ${{ needs.resolve-tooling-image.outputs.php-image }} + workspace: /var/www/html steps: - name: Checkout uses: actions/checkout@v7 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - tools: composer:2 - php-version: ${{ needs.resolve-php-version.outputs.php-version }} - - name: Validate composer.json - run: composer validate --no-interaction + run: docker run --rm -v "${PWD}":${{ env.workspace }} ${{ env.image }} composer validate --no-interaction - name: Install dependencies - run: composer install --no-progress --optimize-autoloader --prefer-dist --no-interaction + run: > + docker run --rm -v "${PWD}":${{ env.workspace }} ${{ env.image }} + composer install --no-progress --optimize-autoloader --prefer-dist --no-interaction - name: Upload vendor and composer.lock as artifact uses: actions/upload-artifact@v7 @@ -58,19 +55,13 @@ jobs: auto-review: name: Auto review - needs: [resolve-php-version, build] + needs: [resolve-tooling-image, build] runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v7 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - tools: composer:2 - php-version: ${{ needs.resolve-php-version.outputs.php-version }} - - name: Download vendor artifact from build uses: actions/download-artifact@v8 with: @@ -78,23 +69,17 @@ jobs: path: . - name: Run review - run: composer review + run: make review tests: name: Tests - needs: [resolve-php-version, auto-review] + needs: [resolve-tooling-image, auto-review] runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v7 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - tools: composer:2 - php-version: ${{ needs.resolve-php-version.outputs.php-version }} - - name: Download vendor artifact from build uses: actions/download-artifact@v8 with: @@ -102,4 +87,4 @@ jobs: path: . - name: Run tests - run: composer tests + run: make tests From de52d1fdfc97f7c302d05da58bf3516343a191b9 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:48:33 -0300 Subject: [PATCH 3/5] chore: Align the tooling configuration with the ecosystem assets. --- composer.json | 1 + phpstan.neon.dist | 63 ++++++++++++++++++----------------------------- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/composer.json b/composer.json index 29fca8a..f0caf0b 100644 --- a/composer.json +++ b/composer.json @@ -62,6 +62,7 @@ "ergebnis/composer-normalize": true, "infection/extension-installer": true }, + "process-timeout": 0, "sort-packages": true }, "scripts": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9c748f1..958a5b2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,54 +3,39 @@ parameters: paths: - src - tests - reportUnmatchedIgnoredErrors: true + tmpDir: reports/phpstan ignoreErrors: # Constructor parameter $aggregateState cannot carry PHPDoc per code-style rule; # the getter return-type mismatch is the downstream symptom of that constraint. - - - identifier: missingType.iterableValue - path: src/Snapshot/Snapshot.php - - - identifier: return.type - path: src/Snapshot/Snapshot.php - + - identifier: missingType.iterableValue + path: src/Snapshot/Snapshot.php + - identifier: return.type + path: src/Snapshot/Snapshot.php # Constructor parameter $serializedEvent cannot carry PHPDoc per code-style rule. - - - identifier: missingType.iterableValue - path: src/Upcast/IntermediateEvent.php - + - identifier: missingType.iterableValue + path: src/Upcast/IntermediateEvent.php # Trait argument-type error reported in context of test fixture upcasters, # whose rewrite() return is untyped because PHPDoc is prohibited in tests/. - - - identifier: argument.type - path: src/Upcast/SingleUpcasterBehavior.php - + - identifier: argument.type + path: src/Upcast/SingleUpcasterBehavior.php # Constructor parameter $propertyNames cannot carry PHPDoc per code-style rule; # the implode() argument-type error is the downstream symptom of that constraint. - - - identifier: missingType.iterableValue - path: src/Exceptions/IncompleteAggregateState.php - - - identifier: argument.type - path: src/Exceptions/IncompleteAggregateState.php - + - identifier: missingType.iterableValue + path: src/Exceptions/IncompleteAggregateState.php + - identifier: argument.type + path: src/Exceptions/IncompleteAggregateState.php # ReflectionClass requires class-string|object; ClassName::shortName accepts the wider # object|string so call sites can pass static::class. The narrowing is safe at every call. - - - identifier: argument.type - path: src/Internal/ClassName.php - + - identifier: argument.type + path: src/Internal/ClassName.php # tests/ — PHPDoc and @var are prohibited inside tests/, so PHPStan errors # for typed arrays in fixtures and helpers route through ignoreErrors. - - - identifier: missingType.iterableValue - path: tests/* - - - identifier: return.type - path: tests/* - - - identifier: assign.propertyType - path: tests/Models/* - - - identifier: property.nonObject - path: tests/Unit/* + - identifier: missingType.iterableValue + path: tests/* + - identifier: return.type + path: tests/* + - identifier: assign.propertyType + path: tests/Models/* + - identifier: property.nonObject + path: tests/Unit/* + reportUnmatchedIgnoredErrors: true From 5ecbf504a6ea37e0ed2ebdf8972dbb464f4fbf0b Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:48:33 -0300 Subject: [PATCH 4/5] docs: Standardize the Copilot instructions. --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index de1576d..e34c801 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -6,7 +6,7 @@ PHP library in the tiny-blocks ecosystem. ## Mandatory pre-task step -Before starting any task, read and strictly follow `CLAUDE.md` and every rule file in +Before starting any task, read and strictly follow `.claude/CLAUDE.md` and every rule file in `.claude/rules/`. These files are the absolute source of truth for code generation. Apply every rule strictly. Do not deviate from the patterns, folder structure, or naming conventions defined in them. From d2b67242a92f4f86f04c442c032d56572e16828f Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:48:33 -0300 Subject: [PATCH 5/5] docs: Run the pull request checklist through the Makefile. --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7a2c836..e9cc769 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,5 +12,5 @@ Closes #... - [ ] Tests added or updated. - [ ] Documentation updated when applicable. -- [ ] `composer review` passes. -- [ ] `composer tests` passes. +- [ ] `make review` passes. +- [ ] `make tests` passes.