From 9fcdcf2baa0ffe60876ba461ce471ab7101071f1 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Thu, 9 Jul 2026 08:41:58 +0200 Subject: [PATCH 1/3] chore: run Rector from the Claude Code setup Mirror event-database-imports#107's Claude integration for Rector (the CI gate and Taskfile targets already landed in the Rector PR): - PostToolUse hook runs `rector process` on the edited src/tests PHP file before php-cs-fixer, so single-file edits are modernized then formatted. - pr-readiness agent gains a Rector (dry-run) check mirroring the CI gate. - CLAUDE.md notes Rector in the PostToolUse list. --- .claude/agents/pr-readiness.md | 12 +++++++----- .claude/settings.json | 5 +++++ CLAUDE.md | 5 +++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.claude/agents/pr-readiness.md b/.claude/agents/pr-readiness.md index 52b9ee3..8d75b37 100644 --- a/.claude/agents/pr-readiness.md +++ b/.claude/agents/pr-readiness.md @@ -17,11 +17,13 @@ JS/CSS to lint). Stop early if a critical check fails. 5. **YAML coding standards**: `task coding-standards:yaml:check` 6. **Markdown coding standards**: `task coding-standards:markdown:check` 7. **PHPStan (level 6)**: `task code-analysis:phpstan` -8. **Test fixtures + API tests**: `task fixtures:load:test --yes && task api:test`. Tests hit a real Elasticsearch, so fixtures must be loaded first. If the load fails with "No alive nodes", run `docker compose up --detach --wait` and retry — see the `reload-fixtures` agent for the full recovery dance. -9. **API spec up to date** (mirrors `.github/workflows/api-spec.yml`): - - `task api:spec:export` - - `git diff --exit-code public/spec.yaml` — must be clean. -10. **CHANGELOG updated**: `git diff develop -- CHANGELOG.md` should show at least one entry under `## [Unreleased]`. +8. **Rector (dry-run)**: `task code-analysis:rector` — the `Rector` gate fails on any suggested change; run `task code-analysis:rector:apply` to fix. +9. **Test fixtures + API tests**: `task fixtures:load:test --yes && task api:test`. Tests hit a real Elasticsearch, so fixtures must be loaded first. If the load fails with "No alive nodes", run `docker compose up --detach --wait` and retry — see the `reload-fixtures` agent for the full recovery dance. +10. **API spec up to date** (mirrors `.github/workflows/api-spec.yml`): + +- `task api:spec:export` +- `git diff --exit-code public/spec.yaml` — must be clean. +1. **CHANGELOG updated**: `git diff develop -- CHANGELOG.md` should show at least one entry under `## [Unreleased]`. ## Output diff --git a/.claude/settings.json b/.claude/settings.json index 98d3cae..e552f70 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -117,6 +117,11 @@ { "matcher": "Edit|MultiEdit|Write", "hooks": [ + { + "type": "command", + "command": "f=$(jq -r '.tool_input.file_path // empty'); REL_PATH=\"${f#\"$CLAUDE_PROJECT_DIR\"/}\"; case \"$REL_PATH\" in src/*.php|tests/*.php) docker compose exec -T phpfpm vendor/bin/rector process --no-progress-bar \"$REL_PATH\" >/dev/null 2>&1 || true ;; esac", + "timeout": 60 + }, { "type": "command", "command": "f=$(jq -r '.tool_input.file_path // empty'); case \"$f\" in *.php) REL_PATH=\"${f#\"$CLAUDE_PROJECT_DIR\"/}\"; docker compose exec -T phpfpm vendor/bin/php-cs-fixer fix --quiet \"$REL_PATH\" 2>/dev/null || true ;; esac", diff --git a/CLAUDE.md b/CLAUDE.md index c1ae5a2..479935f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -152,8 +152,9 @@ cluster** — no shared database, no HTTP call between them. run tooling **inside the `phpfpm` container**. - **Hooks** — `SessionStart` boots the Docker stack and checks host prerequisites; `PostToolUse` auto-runs - php-cs-fixer, phpstan, twig-cs-fixer, `composer normalize`, prettier, and markdownlint on the file you just edited - (so single-file changes don't need manual formatting); `PreToolUse` blocks edits to generated/locked/secret files + Rector (on `src`/`tests` PHP), php-cs-fixer, phpstan, twig-cs-fixer, `composer normalize`, prettier, and + markdownlint on the file you just edited (so single-file changes don't need manual formatting); `PreToolUse` + blocks edits to generated/locked/secret files (`config/reference.php`, lock files, `.env.local`, …); `Stop` validates the DI container (`lint:container`), warns on ES index-contract changes (`scripts/claude-hook-check-index-contract.sh`), and warns when a resource changed but `public/spec.yaml` was not regenerated (`scripts/claude-hook-check-spec-drift.sh`). From cad1111c0668353e5bcd57666abe3c6c7e07287b Mon Sep 17 00:00:00 2001 From: turegjorup Date: Thu, 9 Jul 2026 08:42:31 +0200 Subject: [PATCH 2/3] docs: add CHANGELOG entry for Rector Claude Code hook --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a4d74b..91ee831 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ See [keep a changelog] for information about writing changes to this log. ## [Unreleased] +- [PR-57](https://github.com/itk-dev/event-database-api/pull/57) + Run Rector from the Claude Code setup (PostToolUse hook + pr-readiness step) - [PR-56](https://github.com/itk-dev/event-database-api/pull/56) Scope CI image pulls to each job's real dependencies (phpfpm, or phpfpm + elasticsearch) instead of the whole stack - [PR-55](https://github.com/itk-dev/event-database-api/pull/55) From 63839c8af9637ab68476dad4e842b0d7d0bab8a9 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Thu, 9 Jul 2026 08:52:11 +0200 Subject: [PATCH 3/3] ci: drop redundant root user from the release workflow Mirror devops_itkdev-docker#116: the phpfpm service runs as ${COMPOSE_USER:-deploy}, so the release job's `--user=root` (and the `COMPOSER_ALLOW_SUPERUSER` that paired with it) are redundant. Set `COMPOSE_USER: runner` at the workflow level and drop both, keeping APP_ENV inline via `-e APP_ENV=prod`. --- .github/workflows/build_release.yml | 10 +++++----- CHANGELOG.md | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_release.yml b/.github/workflows/build_release.yml index c31aa4f..547097a 100644 --- a/.github/workflows/build_release.yml +++ b/.github/workflows/build_release.yml @@ -8,12 +8,12 @@ name: Create Github Release permissions: contents: write +env: + COMPOSE_USER: runner + jobs: create-release: runs-on: ubuntu-latest - env: - COMPOSER_ALLOW_SUPERUSER: 1 - APP_ENV: prod steps: - name: Checkout uses: actions/checkout@v7 @@ -21,8 +21,8 @@ jobs: - name: Composer install run: | docker network create frontend - docker compose run --rm --user=root -e APP_ENV=prod phpfpm composer install --no-dev --optimize-autoloader - docker compose run --rm --user=root -e APP_ENV=prod phpfpm composer clear-cache + docker compose run --rm -e APP_ENV=prod phpfpm composer install --no-dev --optimize-autoloader + docker compose run --rm -e APP_ENV=prod phpfpm composer clear-cache - name: Make assets dir run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 91ee831..42870ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ See [keep a changelog] for information about writing changes to this log. ## [Unreleased] - [PR-57](https://github.com/itk-dev/event-database-api/pull/57) - Run Rector from the Claude Code setup (PostToolUse hook + pr-readiness step) + Run Rector from the Claude Code setup (PostToolUse hook + pr-readiness step); drop the redundant + `--user=root`/`COMPOSER_ALLOW_SUPERUSER` from the release workflow (`COMPOSE_USER: runner`) - [PR-56](https://github.com/itk-dev/event-database-api/pull/56) Scope CI image pulls to each job's real dependencies (phpfpm, or phpfpm + elasticsearch) instead of the whole stack - [PR-55](https://github.com/itk-dev/event-database-api/pull/55)