-
Notifications
You must be signed in to change notification settings - Fork 2
Add Agent Playbook section for automated updates #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -60,6 +60,71 @@ create the token and paste it to proceed. | |||||
| We use the [codacy-plugins-test](https://github.com/codacy/codacy-plugins-test) to test our external tools integration. | ||||||
| You can follow the instructions there to make sure your tool is working as expected. | ||||||
|
|
||||||
| ## Agent Playbook: Updating This Repository End-to-End | ||||||
|
|
||||||
| This section is written for an AI coding agent (or a human) tasked with updating this repo — most commonly bumping the wrapped PHPMD version, but also base image / orb bumps. Follow it top to bottom. | ||||||
|
|
||||||
| ### 1. What this repository is | ||||||
|
|
||||||
| This is a **Codacy engine**: a thin Scala wrapper (`src/main/scala/codacy/phpmd/PhpMd.scala`, built on `codacy-engine-scala-seed`, invoked via `com.codacy.tools.scala.seed.DockerEngine`) that packages [PHPMD](http://phpmd.org/) — a PHP static analysis/mess-detection tool — as a Docker image Codacy's platform can run against a customer's PHP source code. PHPMD itself is a **PHP/Composer** package, not something built from this repo's Scala source: it is pulled in as a `vendor/` dependency via `composer.json`/`composer.lock` and installed inside the Dockerfile's `builder` stage, then copied (`vendor/`) into the final image alongside the compiled Scala `bin/codacy-phpmd` launcher. | ||||||
|
|
||||||
| `docs/` holds Codacy's "pattern" configuration for this tool: | ||||||
|
|
||||||
| - `docs/patterns.json` — the list of PHPMD rules ("patterns"), their metadata, and a top-level `"version"` field recording which PHPMD release the pattern list corresponds to. **Hand-maintained, not auto-generated** — there is no DocGenerator script in this repo. | ||||||
| - `docs/description/description.json` + `docs/description/*.md` — human-readable titles/descriptions per pattern, also hand-maintained. | ||||||
| - `docs/tests/*` and `docs/multiple-tests/*` — PHP fixtures used by `codacy-plugins-test` to validate real output. | ||||||
| - `docs/tool-description.md` — short blurb about the tool. | ||||||
|
|
||||||
| Per the repo's own "Update Documentation" section above, `docs/patterns.json` and `docs/description/*` are updated **manually** by diffing against the official rule docs in [phpmd/phpmd](https://github.com/phpmd/phpmd) — there is no generator command to run. | ||||||
|
|
||||||
| ### 2. Files that encode versions — check all of these on every update | ||||||
|
|
||||||
| | File | What it controls | What to check | | ||||||
| |---|---|---| | ||||||
| | `composer.json` → `require.phpmd/phpmd` | Which PHPMD release is installed into the Docker image | Bump to the target version string (e.g. `"2.15.0"`). | | ||||||
| | `composer.lock` | Locked resolution of `phpmd/phpmd` and its transitive PHP deps (`pdepend/pdepend`, `symfony/*`, etc.) | Do **not** hand-edit — regenerate with `composer update` after changing `composer.json` (see step 3). | | ||||||
| | `docs/patterns.json` → top-level `"version"` | Records which PHPMD version the pattern list documents | Bump manually to match `composer.json`; add/remove/rename any patterns changed upstream. | | ||||||
| | `.circleci/config.yml` → `codacy/base` orb | Shared CircleCI steps (checkout, versioning, sbt build/test, docker build/publish, tagging) | Check the latest published orb version if asked to bump it; not required for a pure PHPMD bump. | | ||||||
| | `.circleci/config.yml` → `codacy/plugins-test` orb | Runs `codacy-plugins-test` in CI after the image is built | Same as above. | | ||||||
| | `Dockerfile` → base image (`alpine:3.20`) and `openjdk8-jre` | OS/runtime the packaged PHP CLI + Scala JVM launcher run on | Only bump if asked explicitly, or if the target PHPMD version raises PHP/extension requirements — check PHPMD's release notes for its required PHP version and Alpine's `php` package version. | | ||||||
| | `build.sbt` → `codacy-engine-scala-seed` dependency | Codacy's engine SDK | Not tied to PHPMD bumps; check Maven Central only if asked to update it separately. | | ||||||
|
|
||||||
| ### 3. Step-by-step update procedure | ||||||
|
|
||||||
| 1. **Bump `composer.json`**: set `require.phpmd/phpmd` to the target version. | ||||||
| 2. **Regenerate `composer.lock`.** You need PHP + Composer available locally (or use the Dockerfile's `builder` stage). The repo's own instructions: | ||||||
| ``` | ||||||
| curl -sS https://getcomposer.org/installer | php | ||||||
| php composer.phar update | ||||||
| ``` | ||||||
| If Composer fails to fetch a package with a GitHub OAuth/rate-limit error, create a token at https://github.com/settings/tokens/new and supply it when prompted. | ||||||
| 3. **Update `docs/patterns.json`** — bump the top-level `"version"` field to match, and manually reconcile the pattern list against the changelog/rule docs at https://github.com/phpmd/phpmd for the target version (added/removed/renamed rules). Update `docs/description/*` similarly if descriptions changed. | ||||||
| 4. **Compile and test the Scala wrapper**: `sbt "scalafmtCheckAll; scalafmtSbtCheck; test; stage"`. | ||||||
| 5. **Build the Docker image**: `docker build -t codacy-phpmd .` (this re-runs `composer install --no-scripts` inside the `builder` stage, so it will fail fast if `composer.lock` is inconsistent with `composer.json`). | ||||||
| 6. **Run `codacy-plugins-test` locally** before pushing — clone https://github.com/codacy/codacy-plugins-test and run it (this repo's CI runs it with `run_multiple_tests: true`, i.e. both the single-file `docs/tests/*` fixtures and the `docs/multiple-tests/*` scenarios) against your local image tag. | ||||||
| 7. **Iterate on failures**, re-running only the relevant test command after each fix. | ||||||
| 8. **Commit** the version bump(s) together with `composer.lock` and any `docs/` changes in one change. | ||||||
| 9. **Push and open a PR.** CI (`.circleci/config.yml`) runs `codacy/checkout_and_version` → `codacy/sbt` (scalafmt checks, `test`, `stage`, `docker build`, `docker save`) → `codacy_plugins_test/run` (`run_multiple_tests: true`) → `codacy/publish_docker` (master only) → `codacy/tag_version`. | ||||||
| 10. **Poll the PR's real CI checks until they all pass — local validation is NOT the finish line.** After every push, run `gh pr checks <pr-url>` and keep re-polling (short sleep while any check is `pending`) until all checks finish. If a check fails, fetch its actual log (CircleCI API/UI for the failing job — don't guess), find the true root cause, fix it, push again (never `--no-verify`, never force-push), and re-poll. Repeat until every check is green. The CI environment's toolchain (PHP version, Composer version, Alpine package versions) can differ subtly from a local machine, so a clean local build does not guarantee CI passes. Only stop iterating when every check passes, or you hit a genuine product/infra decision that needs a human — in which case explain it in the PR rather than guessing. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⚪ LOW RISK Suggestion: The GitHub CLI 'gh pr checks' command supports a '--watch' flag that handles polling automatically, making the manual 'sleep' loop unnecessary.
Suggested change
|
||||||
|
|
||||||
| ### 4. Common failure modes and fixes | ||||||
|
|
||||||
| | Symptom | Likely cause | Fix | | ||||||
| |---|---|---| | ||||||
| | `composer update` fails with a GitHub rate-limit/OAuth error | Unauthenticated Composer hitting GitHub API limits when resolving `dist` zips | Generate a token at https://github.com/settings/tokens/new and provide it to Composer when prompted | | ||||||
| | `docker build` fails in the `builder` stage on `composer install` | `composer.lock` out of sync with `composer.json` (e.g. hand-edited version without regenerating the lock file) | Regenerate `composer.lock` via `composer update` rather than editing it directly | | ||||||
| | `pattern`/`json` plugins-test checks fail | A PHPMD rule was renamed/added/removed upstream between versions | Manually reconcile `docs/patterns.json` (and `docs/description/*`) against https://github.com/phpmd/phpmd's docs/changelog for the target version | | ||||||
| | `multiple` plugins-test checks fail on a specific fixture | Expected output in `docs/multiple-tests/*` stale for the new tool behavior | Update the expected results to match the new (verified correct) output | | ||||||
|
|
||||||
| ### 5. Definition of done | ||||||
|
|
||||||
| - `composer.json` bumped and `composer.lock` regenerated to match (not hand-edited). | ||||||
| - `docs/patterns.json` version field and pattern list reconciled with the target PHPMD release; `docs/description/*` updated if descriptions changed. | ||||||
| - Local `sbt` build/format/test commands pass. | ||||||
| - Docker image builds successfully (this also validates the Composer install). | ||||||
| - `codacy-plugins-test` (single and multiple test modes) pass locally against the freshly built image. | ||||||
| - **After pushing and opening/updating the PR, every CI check on it is green.** Poll `gh pr checks <pr-url>` and iterate on any failure (fetch the real CI log, fix, push, re-poll) until all pass — a passing local build is not sufficient, because the CI toolchain can differ from your local one (see step 10). | ||||||
|
|
||||||
| ## What is Codacy? | ||||||
|
|
||||||
| [Codacy](https://www.codacy.com/) is an Automated Code Review Tool that monitors your technical debt, helps you improve your code quality, teaches best practices to your developers, and helps you save time in Code Reviews. | ||||||
|
|
||||||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ LOW RISK
Suggestion: Using scalafmtAll and scalafmtSbt in the local development step is more efficient because it automatically applies formatting fixes instead of simply flagging errors.