Skip to content

Contributing

Matteo Boscolo edited this page Aug 8, 2026 · 3 revisions

Contributing

Contributions are welcome — bug fixes, new modules, documentation and translations. This page describes how the repository is organized and the conventions to follow so your pull request can be merged smoothly.

Repository layout

  • Each top-level folder is a separate Odoo module (e.g. plm, plm_engineering, plm_web_3d).
  • mirror_document_server/ is a standalone Flask service, not an Odoo module.
  • documents/ holds legacy design documents.
  • The development branch for this Odoo series is 19.0. Each major Odoo version has its own branch.
  • The Docker images and the Compose stack live in a separate repository: OmniaGit/DockerOdooPLM.

Before you start

  1. Open an issue describing the bug or feature, so work isn't duplicated: https://github.com/OmniaGit/odooplm/issues
  2. Fork the repo and create a topic branch off 19.0.
  3. Clone with submodules (the 3D/DXF viewer libs are submodules):
    git clone --recurse-submodules -b 19.0 https://github.com/OmniaGit/odooplm.git

Coding standards

The repo follows the OCA (Odoo Community Association) conventions. Python is written to max line length 88 and max complexity 16 (.flake8); files are UTF-8 with LF endings and 4-space indentation (2 for JSON/YAML/RST/MD).

What pre-commit actually runs

The hook set is deliberately small. The 2020-generation formatters that used to be pinned here — black, isort, autoflake, prettier, pylint/pylint-odoo, the whitespace fixers — no longer build on Python 3.12, so pre-commit died before running a single hook and the workflow was red on every push. They were removed rather than left broken: bringing them back means reformatting the repository in one go (black would rewrite 128 of 302 Python files, isort 151, prettier 167 XML files), which is a decision of its own. The comment at the top of .pre-commit-config.yaml records exactly what was dropped and what it would cost to restore.

What remains is what finds real breakage today, without rewriting a line:

Hook Purpose
bump-manifest-version (local) bumps the patch component of "version" in __manifest__.py for every module with staged changes, and stages the result
forbidden-files fails on leftover *.rej files
check-xml, check-yaml a malformed view or data file breaks the module at install time
check-merge-conflict, check-case-conflict, check-symlinks repository hygiene
check-docstring-first, debug-statements catches stray pdb / misplaced docstrings
sync-requirements regenerates aaa_requirements.txt from the manifests whenever one changes
flake8 report only (--exit-zero) with flake8-bugbear; the repo has a backlog of ~1300 findings, mostly long lines

Install and run pre-commit

pip install pre-commit
cd odooplm
pre-commit install          # run automatically on each commit
pre-commit run --all-files  # run on the whole repo once

Please make sure pre-commit run --all-files is clean before opening a PR.

Version bumps are mandatory. Every commit that touches a module must raise that module's __manifest__.py version — the local hook does it for you, so don't fight it. If the only staged file in a module is __manifest__.py itself, the hook skips it, assuming you set the version on purpose.

A second hook bumps plm on every commit, whatever changed: its version is the version of the odooplm pip package, and PyPI refuses a version it already holds, so a tag built on an unmoved plm cannot be published. It stands down when the hook above has already moved plm.

Never edit aaa_requirements.txt

It is generated. Declare a python package in the external_dependencies of the module that imports it, put its version in scripts/requirements_pins.txt, and let the generator write the file:

python3 scripts/sync_requirements.py           # regenerate
python3 scripts/sync_requirements.py --check   # fail if it drifted

The manifests carry no versions on purpose — an Odoo manifest states what a module imports, never which release of it works — which is why the pins live in their own file. The same data produces extras_require in setup.py, so the requirements file and the published wheel cannot disagree. Editing the file by hand is what let it drift before: googletrans and polib were declared by a module and missing from it, and cadquery was listed twice with two contradictory specifications.

Releasing

Tag a commit v19.0.<something> and .github/workflows/publish.yml builds the sdist and wheel, checks the requirements file still matches the manifests, runs twine check and publishes odooplm to PyPI through an OIDC trusted publisher. The package version is whatever plm/__manifest__.py carries at that commit.

The wheel bundles every module of the suite, so its declared licence is AGPL-3 — the stricter of the two in the repository.

Module conventions

  • Every module needs a valid __manifest__.py with at least: name, version (five-part OCA form 19.0.x.y.z), author (OmniaSolutions), maintainer, website, support, category, license, depends, data.
  • Keep the depends list minimal and accurate, and declare Python requirements under external_dependencies.
  • Default license for new modules is AGPL-3. Only the core plm module is LGPL-3 — see Modules Reference.
  • Repeat the licence header at the top of each source file, matching the module's manifest.
  • Place security rules under security/, views under views/, reports under report/, data under data/, and front-end assets under static/.

Testing

Tests use odoo.tests.common.TransactionCase and mix in PlmEntityCreator (plm/tests/entity_creator.py) for factory helpers. They opt out of the standard suite with @tagged("-standard", "<tag>"), so they only run when you ask for their tag:

odoo -c odoo.conf -d <db> -i <module> --test-tags=odoo_plm --stop-after-init

# several suites at once
odoo -c odoo.conf -d <db> --test-tags=odoo_plm,odoo_plm_web_revision,plm_automatic_weight --stop-after-init

Existing tags include odoo_plm, odoo_plm_check_in, odoo_plm_web_revision, plm_automatic_weight, odoo_plm_suspended, odoo_pack_and_go, plm_date_bom.

When developing views, auto-reload XML with:

odoo -c odoo.conf --dev=xml

Please add or update tests for the behaviour you change, and tag them so they run under the appropriate --test-tags.

Commit messages

The project uses a tagged commit format:

[TAG] | Short description of the change

Where TAG is one of:

Tag Use for
FIX Bug fixes
ADD New features / modules
IMP Improvements to existing behaviour
MOD Modifications / refactors

Example: [FIX] | plm_web_3d: correct section plane normal on STEP import

Submitting a pull request

  1. Keep each PR focused on one change.
  2. Write a clear description: what changed, why, and how to test it.
  3. Reference the related issue.
  4. Ensure pre-commit passes and tests are green.
  5. Target the 19.0 branch.

License

By contributing you agree that your contributions are licensed under the same license as the module you modify — AGPL-3 for every module except the core plm, which is LGPL-3. The __manifest__.py of the module is the authoritative source.

Contact

Clone this wiki locally