- name
- oca-module-porter
- description
- OCA module porting specialist. Port OCA Odoo modules between versions using oca-port CLI, apply OCA quality standards (pre-commit, manifest, README), run acceptance tests, and generate OCA-compliant commits and PRs. Actions: port, migrate, check, validate, test, commit, pr. Triggers: 'port module', 'migrate OCA', 'oca-port', 'port addon', 'migrate 16.0 to 17.0', 'port to 19.0', 'OCA migration', 'module migration checklist'. Supports: 14.0, 15.0, 16.0, 17.0, 18.0, 19.0.
- version
- 1.0.0
- tags
- ["odoo","oca","migration","porting","pre-commit","maintainer-tools"]
- allowed-tools
- ["Bash","Read","Write","Edit","Glob","Grep"]
# OCA Module Porter
Specialist skill for porting OCA Odoo modules from one version to another using official OCA tooling.
Covers the complete workflow: selection → automated porting → quality checks → testing → commit → PR.
## When to Use This Skill
- Porting an OCA module from version X to version Y (e.g., 18.0 → 19.0)
- Applying OCA quality standards to a migrated module
- Validating a ported module against OCA pre-commit requirements
- Generating OCA-compliant manifest, README, and commit messages
- Running acceptance tests after a port
- Submitting upstream PRs to OCA repositories
## How to Use (Prompt Patterns)
- "Port the `server_environment` module from OCA/server-tools 18.0 to 19.0"
- "Run oca-port on `account_statement_import_base`, check quality, generate commit"
- "Apply OCA pre-commit hooks to the ported `base_tier_validation` module"
- "Generate the README for `mail_tracking` using oca-gen-addon-readme"
- "Create an OCA-compliant PR description for the 19.0 migration of `queue_job`"
- "Validate the manifest of `web_environment_ribbon` against OCA standards"
---
## Deterministic Porting Workflow
### Phase 1: Setup and Validation
```bash
# Install oca-port (one-time)
pip3 install oca-port
# Verify installation
oca-port --version
# Set environment variables
export GITHUB_TOKEN="<your-github-token>" # Required for GitHub API
export MODULE="server_environment"
export REPO="server-tools"
export FROM_VERSION="18.0"
export TO_VERSION="19.0"
```
### Phase 2: Automated Port (oca-port CLI)
```bash
# Dry-run first — shows what would happen without making changes
oca-port origin/${FROM_VERSION} origin/${TO_VERSION} ${MODULE} --verbose --dry-run
# Effective port — creates working branch automatically
oca-port origin/${FROM_VERSION} origin/${TO_VERSION} ${MODULE} --verbose
# Non-OCA organization or non-standard branches:
oca-port origin/main origin/18.0-mig \
--source-version=${FROM_VERSION} \
--target-version=${TO_VERSION} \
--upstream-org=OCA \
./${MODULE} --verbose
# Fetch remote branches automatically:
oca-port origin/${FROM_VERSION} origin/${TO_VERSION} ${MODULE} --fetch
```
**oca-port creates a branch named**: `{TO_VERSION}-mig-{MODULE}` (or destination branch if specified)
**oca-port automatically**:
1. Compares git histories between source and target branches
2. Identifies commits not yet ported, grouped by Pull Request
3. Creates the working branch from the target branch
4. Proposes interactive porting of each missing PR/commit
5. Calls odoo-module-migrator for automated code transformations (v0.18+)
### Phase 3: Code Migration (odoo-module-migrator)
When oca-port cannot fully automate, or for manual migration paths:
```bash
# Install
pip3 install odoo-module-migrator
# Migrate code automatically
odoo-module-migrate \
--directory /path/to/repo \
--modules ${MODULE} \
--init-version-name ${FROM_VERSION} \
--target-version-name ${TO_VERSION}
# With git format-patch (single module only)
odoo-module-migrate \
--directory /path/to/repo \
--modules ${MODULE} \
--init-version-name ${FROM_VERSION} \
--target-version-name ${TO_VERSION} \
--format-patch \
--remote origin
```
**Output message types**:
- `INFO`: Automatically changed — no action required
- `WARNING`: Check this — may need manual fix
- `ERROR`: Must fix manually — module will not work otherwise
### Phase 4: Manual Migration Checklist
Apply the version-specific checklist below. Universal steps (all versions):
```bash
# 1. Bump version in __manifest__.py
# Change: 'version': '18.0.1.0.0' -> 'version': '19.0.1.0.0'
# 2. Remove old migration scripts
rm -rf ${MODULE}/migrations/
# 3. Run pre-commit to fix formatting
pre-commit run --all-files
# Expected: black, isort, prettier pass; ignore pylint at this stage
# 4. Commit formatting changes separately
git add .
git commit -m "[IMP] ${MODULE}: pre-commit formatting (black, isort, prettier)"
```
### Phase 5: Quality Validation
```bash
# Install pre-commit
pip3 install pre-commit
pre-commit install
# Run all hooks
pre-commit run --all-files
# Generate README from fragments
oca-gen-addon-readme \
--repo-name=${REPO} \
--branch=${TO_VERSION} \
--addon-dir=${MODULE}
# Fix manifest website field
oca-fix-manifest-website ${MODULE}/__manifest__.py
```
### Phase 6: Acceptance Testing
```bash
# 1. Python syntax check (all .py files)
python3 -m py_compile ${MODULE}/**/*.py && echo "PASS: No syntax errors"
# 2. Module loads in Odoo shell
./scripts/odoo_shell.sh -c "env['ir.module.module'].search([('name', '=', '${MODULE}')])"
# 3. Module installs without errors
./scripts/odoo_module_install.sh ${MODULE}
# 4. Run module tests (if test suite exists)
pytest --odoo-database=odoo_test --addons-path=. -p no:warnings ${MODULE}/tests/
# 5. Check manifest version
grep "'version'" ${MODULE}/__manifest__.py
# Expected: 'version': '19.0.1.0.0'
```
### Phase 7: Evidence Capture
```bash
TIMESTAMP=$(date +"%Y%m%d-%H%M%z")
EVIDENCE_DIR="web/docs/evidence/${TIMESTAMP}/oca-port-${MODULE}"
mkdir -p "${EVIDENCE_DIR}/logs"
oca-port origin/${FROM_VERSION} origin/${TO_VERSION} ${MODULE} 2>&1 \
| tee "${EVIDENCE_DIR}/logs/port.log"
python3 -m py_compile ${MODULE}/**/*.py 2>&1 \
| tee "${EVIDENCE_DIR}/logs/syntax.log" && echo "PASS" >> "${EVIDENCE_DIR}/logs/syntax.log"
pre-commit run --all-files 2>&1 | tee "${EVIDENCE_DIR}/logs/precommit.log"
```
### Phase 8: OCA-Compliant Commit
```bash
git add addons/oca/${REPO}/${MODULE}/
git commit -m "[MIG] ${MODULE}: Migration to ${TO_VERSION}
- Tool: oca-port CLI
- From: ${FROM_VERSION} -> ${TO_VERSION}
- Pre-commit: passed
- Tests: smoke tests passed (load + install)
- Evidence: ${EVIDENCE_DIR}"
```
### Phase 9: Upstream PR to OCA
```bash
git push origin ${TO_VERSION}-mig-${MODULE}
gh pr create \
--repo OCA/${REPO} \
--base ${TO_VERSION} \
--title "[${TO_VERSION}][MIG] ${MODULE}: Migration to ${TO_VERSION}" \
--body "$(cat <<'EOF'
## Migration Summary
Port of MODULE from FROM to TO.
## Changes
- Bumped version to TO.1.0.0
- Applied automated migration via oca-port
- Applied odoo-module-migrator transformations
- Fixed pre-commit hooks (black, isort, prettier)
- Updated README via oca-gen-addon-readme
## Testing
- [x] Python syntax check passed
- [x] Module loads in Odoo shell
- [x] Module installs without errors
- [ ] Full test suite (if applicable)
Closes #ISSUE_NUMBER
EOF
)"
```
---
## OCA Module Structure (Required)
```
MODULE_NAME/
|-- __init__.py
|-- __manifest__.py # Required: name, version, author, license, depends, data
|-- readme/
| |-- DESCRIPTION.rst # Required for oca-gen-addon-readme
| |-- USAGE.rst # Highly recommended
| |-- CONTRIBUTORS.rst # Highly recommended
| |-- INSTALL.rst # Optional
| |-- CONFIGURE.rst # Optional
| |-- HISTORY.rst # Optional (changelog)
| |-- newsfragments/ # Optional (towncrier fragments)
|-- models/
| |-- __init__.py
| |-- model_name.py
|-- views/
| |-- model_name_views.xml
| |-- model_name_menus.xml
|-- security/
| |-- ir.model.access.csv
| |-- model_name_security.xml
|-- data/
| |-- model_name_data.xml
|-- tests/
| |-- __init__.py
| |-- test_model_name.py
|-- static/
| |-- description/
| | |-- icon.png # Module icon (128x128)
```
---
## OCA Manifest Standards
```python
{
'name': 'Module Human-Readable Name',
'version': '19.0.1.0.0', # MANDATORY: {odoo_version}.{major}.{minor}.{patch}.{fix}
'author': 'Author Name, Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/{repo-name}',
'license': 'LGPL-3', # LGPL-3 is OCA default
'category': 'Specific/Category',
'summary': 'One-line module description (used in README)',
'depends': ['base'],
'data': [
'security/ir.model.access.csv',
'views/model_name_views.xml',
],
'demo': [],
'installable': True,
'auto_install': False,
'application': False,
'development_status': 'Beta', # Alpha | Beta | Production/Stable | Mature
'maintainers': ['github_username'],
}
```
**Version format rules**:
- `{odoo_version}.{major}.{minor}.{patch}.{fix}`
- Reset to `{TO_VERSION}.1.0.0` on each migration
- `development_status` defaults to `Beta` if not set
---
## OCA Pre-Commit Configuration
Standard `.pre-commit-config.yaml` for OCA repos (17.0+):
```yaml
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 24.3.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
additional_dependencies: [flake8-bugbear]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
name: prettier (yaml, json, md)
types_or: [yaml, json, markdown]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: check-yaml
- id: check-json
- repo: https://github.com/OCA/maintainer-tools
rev: 0.1.39
hooks:
- id: oca-gen-addon-readme
args: ['--addons-dir', '.', '--if-source-missing', 'ignore']
- id: oca-update-pre-commit-excluded-addons
- id: oca-fix-manifest-website
- repo: https://github.com/OCA/odoo-pre-commit-hooks
rev: v0.2.20
hooks:
- id: oca-checks-odoo-module
- id: oca-checks-po
args: ["--fix"]
- repo: https://github.com/OCA/pylint-odoo
rev: v8.0.0
hooks:
- id: pylint_odoo
args: [--rcfile=.pylintrc, --exit-zero]
```
**Hook groups summary**:
- `black` — Python code formatting
- `isort` — Python import sorting
- `flake8` — PEP8 linting
- `prettier` — YAML/JSON/Markdown formatting
- `oca-gen-addon-readme` — Generates README.rst from fragments
- `oca-checks-odoo-module` — OCA-specific XML/manifest checks
- `oca-checks-po` — Translation file validation
GitHubで見る