From 225550d4b772eacfb4b057f68bbd80d09c212dcc Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:52 -0300 Subject: [PATCH 1/5] build: Pin the PHP tooling image in the Makefile. --- Makefile | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 243682d..6915324 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,19 @@ PWD := $(CURDIR) ARCH := $(shell uname -m) PLATFORM := -TTY := $(shell [ -t 0 ] && echo -it) ifeq ($(ARCH),arm64) PLATFORM := --platform=linux/amd64 endif -PROJECT := $(notdir ${PWD}) -DOCKER_RUN = docker run ${PLATFORM} --rm ${TTY} --net=host -v ${PWD}/..:/workspace -w /workspace/${PROJECT} gustavofreze/php:8.5-alpine +TTY := $(shell [ -t 0 ] && echo -it) + +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 ba90dec3c470c85f0cdde99ef182346559352434 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:52 -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 f7590bf5ab66d5d298743c53efb69b067348a66c Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:52 -0300 Subject: [PATCH 3/5] chore: Align the tooling configuration with the ecosystem assets. --- .gitattributes | 2 -- composer.json | 1 + phpstan.neon.dist | 26 ++------------------------ 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/.gitattributes b/.gitattributes index f044953..cc4d0f6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,8 +2,6 @@ *.php text diff=php -# Keep Claude tooling scripts out of GitHub's language statistics - # Dev-only, excluded from the Packagist tarball /.github export-ignore /tests export-ignore diff --git a/composer.json b/composer.json index ffb0176..492e40c 100644 --- a/composer.json +++ b/composer.json @@ -57,6 +57,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 610f14b..839532d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,14 +3,13 @@ parameters: paths: - src - tests - reportUnmatchedIgnoredErrors: true + tmpDir: reports/phpstan ignoreErrors: # Collection is an extension point designed for `new static()`. Subclasses inherit # the private constructor via factory methods. PHPStan cannot verify constructor # compatibility at the parent level, but the design enforces it by convention. - identifier: new.static path: src/Collection.php - # LazyPipeline defers element production, holding its source as `iterable|Closure` until # iteration. The element type is only realized on materialization, so level max cannot bind # the template through the constructor. `new LazyPipeline(...)` then reads as ``, which @@ -21,69 +20,54 @@ parameters: path: src/Internal/LazyPipeline.php - identifier: return.type path: src/Internal/LazyPipeline.php - # src/Internal/ operations and resolvers carry no PHPDoc per php-library-code-style.md. # Their iterable value types and mixed-origin argument types cannot be annotated in # code (the generics carve-out covers only template type parameters, which these # collaborators do not need). Suppressed by identifier per file. - - identifier: missingType.iterableValue path: src/Internal/Operations/Resolving/Each.php - identifier: callable.nonCallable path: src/Internal/Operations/Resolving/Each.php - - identifier: missingType.iterableValue path: src/Internal/Operations/Resolving/Find.php - identifier: return.type path: src/Internal/Operations/Resolving/Find.php - identifier: argument.type path: src/Internal/Operations/Resolving/Find.php - - identifier: missingType.iterableValue path: src/Internal/Operations/Resolving/Join.php - identifier: argument.type path: src/Internal/Operations/Resolving/Join.php - - identifier: missingType.iterableValue path: src/Internal/Operations/Resolving/Reduce.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Add.php - identifier: missingType.iterableValue path: src/Internal/Operations/Transforming/Add.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Filter.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/FlatMap.php - identifier: missingType.iterableValue path: src/Internal/Operations/Transforming/FlatMap.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/GroupInto.php - identifier: offsetAccess.invalidOffset path: src/Internal/Operations/Transforming/GroupInto.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Map.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Merge.php - identifier: missingType.iterableValue path: src/Internal/Operations/Transforming/Merge.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Rearrange.php - identifier: return.type path: src/Internal/Operations/Transforming/Rearrange.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Remove.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/RemoveAll.php - - identifier: missingType.generics path: src/Internal/Operations/Transforming/Segment.php - identifier: missingType.iterableValue @@ -92,35 +76,29 @@ parameters: path: src/Internal/Operations/Transforming/Segment.php - identifier: generator.keyType path: src/Internal/Operations/Transforming/Segment.php - # Test files: PHPDoc is prohibited on concrete classes. Mixed types originate # from Collection's generic element access (first, last, getBy, reduce, groupBy) # which returns mixed at the PHPStan level. - - identifier: property.nonObject path: tests/CollectionTest.php - identifier: argument.type path: tests/CollectionTest.php - - identifier: property.nonObject path: tests/EagerCollectionTest.php - identifier: argument.type path: tests/EagerCollectionTest.php - - identifier: property.nonObject path: tests/LazyCollectionTest.php - identifier: argument.type path: tests/LazyCollectionTest.php - - identifier: missingType.generics path: tests/Models/Products.php - identifier: missingType.iterableValue path: tests/Models/Products.php - - identifier: missingType.iterableValue path: tests/Models/Shipment.php - - identifier: missingType.iterableValue path: tests/Models/ShipmentRecord.php - identifier: argument.type path: tests/Models/ShipmentRecord.php + reportUnmatchedIgnoredErrors: true From 49e23a1849fedeec6063507000e8ed8427d171c4 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:52 -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 38ff1b46b4e5f0d1254fc921bf8579f468fcbae6 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:52 -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.