-
Notifications
You must be signed in to change notification settings - Fork 6
docs: repo-wide PR review guide (CLAUDE.md) + reviewer checklist #310
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
base: 19.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,122 @@ | ||||||||||||||
| # OpenSPP2 — Contributor & PR Review Guide | ||||||||||||||
|
|
||||||||||||||
| OpenSPP2 is an Odoo 19 monorepo of OpenSPP addons. This file is the **repo-wide | ||||||||||||||
| source of truth for how we review pull requests** — for human reviewers and for | ||||||||||||||
| AI-assisted review (Claude Code auto-loads it). The PR template links here. | ||||||||||||||
|
|
||||||||||||||
| > **Status: proposal.** Opened for the team to weigh in — refine, cut, or add | ||||||||||||||
| > rules as we agree on them. | ||||||||||||||
|
|
||||||||||||||
| ## PR Review Checklist | ||||||||||||||
|
|
||||||||||||||
| When reviewing a PR, explicitly check each of these and cite `file:line` for | ||||||||||||||
| anything raised: | ||||||||||||||
|
|
||||||||||||||
| ### 1. Correctness | ||||||||||||||
|
|
||||||||||||||
| - **Deleted code** — diff *both* directions. Count deleted test methods and | ||||||||||||||
| confirm coverage isn't quietly dropped. | ||||||||||||||
| - **Runtime behavior** — verify the changed path actually works (drive it or run | ||||||||||||||
| the module's tests), not just that the code reads correctly. A "column-shape" | ||||||||||||||
| test can pass green while the total is wrong. | ||||||||||||||
| - **Dependency completeness** — trace what happens when an *optional* dependency | ||||||||||||||
| isn't installed. | ||||||||||||||
| - **Edge cases** — None/empty handling; migrations (`migrations/*`) must be | ||||||||||||||
| idempotent and safe to re-run. | ||||||||||||||
|
|
||||||||||||||
| ### 2. Scope | ||||||||||||||
|
|
||||||||||||||
| - Flag unrelated changes bundled into one PR. Prefer one concern per PR — it | ||||||||||||||
| makes review and rollback cleaner. | ||||||||||||||
|
|
||||||||||||||
| ### 3. Release hygiene — REQUIRED (the most-missed rule) | ||||||||||||||
|
|
||||||||||||||
| - **Every changed module gets a `readme/HISTORY.md` changelog entry AND a | ||||||||||||||
| matching `__manifest__.py` version bump.** (See _Changelog & versioning_ | ||||||||||||||
| below.) This is the rule that most often slips — check it first. | ||||||||||||||
| - If any `readme/` fragment changed, **regenerate** `README.rst` and | ||||||||||||||
| `static/description/index.html` with the OCA generator | ||||||||||||||
| (`oca-gen-addon-readme`) and commit the regenerated files. | ||||||||||||||
|
Comment on lines
+37
to
+39
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. When regenerating files using
Suggested change
References
|
||||||||||||||
|
|
||||||||||||||
| ### 4. Odoo 19 compatibility | ||||||||||||||
|
|
||||||||||||||
| - `view_mode` uses **`list`**, not `tree`. | ||||||||||||||
| - No deprecated `attrs=` / `states=` — use `invisible=` / `readonly=` / | ||||||||||||||
| `required=` expressions. | ||||||||||||||
| - Manifest `depends` is complete and correct. | ||||||||||||||
| - The `openspp-check-odoo19-python` / `openspp-check-odoo19-xml` pre-commit | ||||||||||||||
| hooks catch common cases, but the reviewer still verifies. | ||||||||||||||
|
|
||||||||||||||
| ### 5. Security | ||||||||||||||
|
|
||||||||||||||
| - **No PII or secrets in logs** (`openspp-no-pii-in-logs`, `gitleaks`). | ||||||||||||||
| - **API v2 / DCI / controllers:** endpoints are authenticated; JWT is | ||||||||||||||
| algorithm-pinned with audience/issuer validated; token comparisons are | ||||||||||||||
| constant-time; no unauthenticated PII exposure; **SQL is parameterized** (no | ||||||||||||||
| string-interpolated queries); controller routes set `auth=` correctly. | ||||||||||||||
| - New models have **ACLs** (`openspp-check-acl`); XML IDs follow naming | ||||||||||||||
| (`openspp-check-xml-ids`); no over-broad `sudo()` (scope + annotate). | ||||||||||||||
|
|
||||||||||||||
| ### 6. Tests | ||||||||||||||
|
|
||||||||||||||
| - CI runs the module test matrix on PRs, but **run the affected module's suite | ||||||||||||||
| locally** too before opening/updating — and again after a rebase (git merges | ||||||||||||||
| text, not behavior). See _Running tests_. | ||||||||||||||
| - **Pre-commit must be clean** via the CI-matching container — see _Pre-commit_. | ||||||||||||||
|
|
||||||||||||||
| ## Review protocol (esp. for AI-assisted review) | ||||||||||||||
|
|
||||||||||||||
| - **Recommend first**, then get maintainer confirmation **before submitting a | ||||||||||||||
| formal GitHub review** (Approve / Request changes). | ||||||||||||||
| - **Verify load-bearing claims against the actual code** — don't rely on the PR | ||||||||||||||
| description; spot-check the riskiest assertions. | ||||||||||||||
| - **Run the tests.** A green PR check is not proof everything passes. | ||||||||||||||
|
|
||||||||||||||
| ## Changelog & versioning (`readme/HISTORY.md`) | ||||||||||||||
|
|
||||||||||||||
| Every module tracks changes in `readme/HISTORY.md`, rendered as the "Changelog" | ||||||||||||||
| in the generated `README.rst`. | ||||||||||||||
|
|
||||||||||||||
| ``` | ||||||||||||||
| ### {version} # must match `version` in __manifest__.py | ||||||||||||||
|
|
||||||||||||||
| - type(scope): description (#PR) | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| - **Types:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`. | ||||||||||||||
| - Newest version on top; newest entry first within a version. | ||||||||||||||
| - **Version bump:** patch for fixes, minor for features, major for breaking | ||||||||||||||
| changes. | ||||||||||||||
| - _Open question for the team:_ bump in the feature branch vs. on `19.0` after | ||||||||||||||
| merge. Both patterns exist today — let's settle it here. | ||||||||||||||
|
|
||||||||||||||
| ## Running locally | ||||||||||||||
|
|
||||||||||||||
| ### Pre-commit (CI-matching container) | ||||||||||||||
|
|
||||||||||||||
| Run the same hooks CI runs, on your changed files, before pushing: | ||||||||||||||
|
|
||||||||||||||
| ```bash | ||||||||||||||
| /Users/<you>/Projects/ci-local/run.sh OpenSPP2 --files <changed files> | ||||||||||||||
| # regenerate READMEs when a readme/ fragment changed: | ||||||||||||||
| /Users/<you>/Projects/ci-local/run.sh OpenSPP2 oca-gen-addon-readme --all-files --hook-stage manual | ||||||||||||||
|
Comment on lines
+100
to
+102
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. Using
Suggested change
|
||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Hooks include: `ruff` / `ruff-format`, `pylint_odoo`, the OCA checks, the | ||||||||||||||
| `openspp-*` custom checks (naming, XML IDs, ACL, PII-in-logs, performance, | ||||||||||||||
| Odoo-19 py/xml, API-auth), `gitleaks`, `bandit`, `semgrep`. | ||||||||||||||
|
|
||||||||||||||
| ### Module tests (Docker) | ||||||||||||||
|
|
||||||||||||||
| ```bash | ||||||||||||||
| cd OpenSPP2 | ||||||||||||||
| docker compose exec -T db psql -U odoo -d postgres -c "CREATE DATABASE test_MODULE;" | ||||||||||||||
| docker compose run --rm --entrypoint "" test \ | ||||||||||||||
| /opt/odoo/odoo/odoo-bin \ | ||||||||||||||
| --addons-path=/opt/odoo/odoo/addons,/opt/odoo/odoo/odoo/addons,/mnt/extra-addons/openspp,/mnt/extra-addons/server-ux,/mnt/extra-addons/server-tools,/mnt/extra-addons/queue,/mnt/extra-addons/odoo-job-worker,/mnt/extra-addons/server-backend,/mnt/extra-addons/rest-framework,/mnt/extra-addons/muk-it \ | ||||||||||||||
| -d test_MODULE --db_host=db --db_port=5432 --db_user=odoo --db_password=odoo \ | ||||||||||||||
| --stop-after-init --no-http -i MODULE --test-tags /MODULE --log-level=test 2>&1 | tail -80 | ||||||||||||||
| docker compose exec -T db psql -U odoo -d postgres -c "DROP DATABASE IF EXISTS test_MODULE;" | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Look for the summary line: `0 failed, 0 error(s) of N tests`. | ||||||||||||||
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.
@emjay0921 I think this should be in https://github.com/ACN-org/acn-workspace/blob/main/internal/claude-config/OpenSPP2/CLAUDE.md. We are standardizing on using the acn-workspace that is why you will notice that there are no claude files in the OpenSPP2 repo.