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/.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 3a4d74b..42870ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ 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); 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) 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`).