From fafb14bbe43e1afc2b9c198c83faf193dbd703f9 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:53 -0300 Subject: [PATCH 1/5] build: Pin the PHP tooling image in the Makefile. --- Makefile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2da2938..ce433a9 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,16 @@ endif 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} -u root --rm ${TTY} --network=tiny-blocks --name test-lib \ - -v ${PWD}:/app \ + -v ${PWD}:${WORKSPACE} \ -v ${PWD}/tests/Integration/Database/Migrations:/test-adm-migrations \ -v /var/run/docker.sock:/var/run/docker.sock \ - -w /app gustavofreze/php:8.5-alpine + ${PHP_IMAGE} RESET := \033[0m GREEN := \033[0;32m @@ -54,6 +59,10 @@ show-reports: ## Open coverage and mutation reports in the browser show-outdated: configure-test-environment ## 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} @@ -76,7 +85,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 df58b4ff70fe847259958ec485929782c3daa89f Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:53 -0300 Subject: [PATCH 2/5] ci: Resolve the tooling image from the Makefile. --- .github/workflows/ci.yml | 52 +++++++++++++--------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af3b92d..2dca071 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,11 +69,11 @@ 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: @@ -98,17 +89,8 @@ jobs: - name: Clean up Docker run: docker system prune -f - - name: Create Docker network - run: docker network create tiny-blocks - - name: Create Docker volume for migrations run: docker volume create test-adm-migrations - name: Run tests - run: | - docker run --network=tiny-blocks \ - -v ${PWD}:/app \ - -v ${PWD}/tests/Integration/Database/Migrations:/test-adm-migrations \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -w /app \ - gustavofreze/php:${{ needs.resolve-php-version.outputs.php-version }}-alpine bash -c "composer tests" + run: make tests From 46ecea4e79d1dfb65dcdb2c63151e579cd0b5b04 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:53 -0300 Subject: [PATCH 3/5] chore: Align the tooling configuration with the ecosystem assets. --- .gitattributes | 2 -- infection.json.dist | 2 +- phpstan.neon.dist | 20 ++------------------ 3 files changed, 3 insertions(+), 21 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/infection.json.dist b/infection.json.dist index 80412d9..b9596a3 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -3,7 +3,7 @@ "text": "reports/infection/logs/infection-text.log", "summary": "reports/infection/logs/infection-summary.log" }, - "tmpDir": "reports/infection/cache/", + "tmpDir": "reports/infection/", "minMsi": 100, "timeout": 120, "source": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8f21a9f..50f7b8d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,7 +3,7 @@ parameters: paths: - src - tests - reportUnmatchedIgnoredErrors: true + tmpDir: reports/phpstan ignoreErrors: # Late static binding in extension-point container factories that consumers subclass. - identifier: new.static @@ -11,7 +11,6 @@ parameters: - src/FlywayDockerContainer.php - src/GenericDockerContainer.php - src/MySQLDockerContainer.php - # tiny-blocks/collection generics carry a mixed TValue on Internal command and definition types. - identifier: missingType.generics paths: @@ -21,7 +20,6 @@ parameters: - src/Internal/Containers/Address/Ports.php - src/Internal/Containers/Definitions/ContainerDefinition.php - src/Internal/Containers/Environment/EnvironmentVariables.php - # Internal collaborators take raw config arrays at the boundary, where PHPDoc is prohibited. - identifier: missingType.iterableValue paths: @@ -35,7 +33,6 @@ parameters: - src/Internal/Containers/Definitions/VolumeMapping.php - src/Internal/Containers/Drivers/MySQL/MySQLCommands.php - src/Internal/Containers/Environment/EnvironmentVariables.php - # Internal command builders return argument lists assembled from collection mixed values. - identifier: return.type paths: @@ -43,47 +40,38 @@ parameters: - src/Internal/Commands/DockerExecute.php - src/Internal/Commands/DockerRun.php - src/Internal/Containers/Address/Ports.php - # Collection each/reduce pass concrete closures against the mixed-typed variadic API. - identifier: argument.type paths: - src/Internal/CommandHandler/ContainerCommandHandler.php - src/Internal/Commands/DockerRun.php - src/Internal/Containers/Address/Ports.php - # docker inspect json_decode and sprintf feed mixed values across the system boundary. - identifier: argument.type paths: - src/Internal/Containers/ContainerInspection.php - src/Internal/Containers/Drivers/MySQL/MySQLCommands.php - # gethostname() returns string|false at the system boundary when the host name is unavailable. - identifier: argument.type path: src/Internal/Containers/ContainerReaper.php - # docker inspect json_decode produces mixed offsets read in ContainerInspection. - identifier: offsetAccess.nonOffsetAccessible path: src/Internal/Containers/ContainerInspection.php - # docker inspect json_decode yields a mixed value cast to int at the boundary. - identifier: cast.int path: src/Internal/Containers/ContainerInspection.php - # docker inspect json_decode yields a mixed value iterated at the boundary. - identifier: foreach.nonIterable path: src/Internal/Containers/ContainerInspection.php - # Environment variable values arrive as mixed and are cast to string at the boundary. - identifier: cast.string path: src/Internal/Containers/Environment/EnvironmentVariables.php - # Fixtures and mocks accept raw arrays, where PHPDoc is prohibited inside tests. - identifier: missingType.iterableValue paths: - tests/Integration/MySQLRepository.php - tests/Models/InspectResponseFixture.php - tests/Unit/ClientMock.php - # ClientMock and fixtures hand mixed values to typed sinks and assertions in tests. - identifier: argument.type paths: @@ -91,25 +79,21 @@ parameters: - tests/Unit/FlywayDockerContainerTest.php - tests/Unit/GenericDockerContainerTest.php - tests/Unit/MySQLDockerContainerTest.php - # ClientMock's match arms assemble output tuples from untyped recorded responses. - identifier: return.type path: tests/Unit/ClientMock.php - # ClientMock casts a mixed recorded value to string when building command output. - identifier: cast.string path: tests/Unit/ClientMock.php - # ClientMock indexes into a mixed recorded payload when replaying responses. - identifier: offsetAccess.nonArray path: tests/Unit/ClientMock.php - # MySQLRepository reads a mixed PDO result as an object at the system boundary. - identifier: method.nonObject path: tests/Integration/MySQLRepository.php - # Mock-verified and no-exception tests assert a literal true to satisfy the assertion count. - identifier: staticMethod.alreadyNarrowedType paths: - tests/Unit/GenericDockerContainerTest.php - tests/Unit/Waits/ContainerWaitForDependencyTest.php + reportUnmatchedIgnoredErrors: true From 61bf795317b48df1cd353a92031b94aebcfa3a45 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:53 -0300 Subject: [PATCH 4/5] docs: Standardize the Copilot instructions. --- .github/copilot-instructions.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 77c2bb8..e34c801 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,10 +2,11 @@ ## Context -PHP library (tiny-blocks). Immutable domain models, zero infrastructure dependencies in core. +PHP library in the tiny-blocks ecosystem. ## Mandatory pre-task step -Before starting any task, read and strictly follow all instruction files located in `.claude/CLAUDE.md` and -`.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. +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 2813e23d7bb41c84c2b58ad84096db791e9a0890 Mon Sep 17 00:00:00 2001 From: Gustavo Freze Date: Wed, 19 Aug 2026 20:54:53 -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.